如何在iOS中获得音频文件的持续时间?

nxowjjhe  于 2023-01-22  发布在  iOS
关注(0)|答案(9)|浏览(478)
NSDictionary* fileAttributes = 
    [[NSFileManager defaultManager] attributesOfItemAtPath:filename 
                                                     error:nil]

从文件属性键中,您可以获得日期、大小等。但是如何获得持续时间呢?

xam8gpfp

xam8gpfp1#

在 * NSFileManager * 类引用的"文件属性键"中,您可以看到没有可用于返回歌曲持续时间的键。* NSFileManager * 示例获取的有关文件的所有信息都与操作系统中实际文件本身的属性有关,例如文件大小。* NSFileManager * 实际上并不解释文件。
为了获取文件的持续时间,您需要使用一个知道如何解释文件的类。* AVFoundation * 框架提供了您所需的确切类 * AVAsset *。您可以使用具体子类 * AVURLAsset * 示例化此抽象类的示例。然后向其提供一个 * NSURL *,该 * NSURL * 指向您希望获取持续时间的音频文件。然后,您可以从 * AVAsset * 获取持续时间示例,方法是查询其duration属性。
例如:

AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:audioFileURL options:nil];
CMTime audioDuration = audioAsset.duration;
float audioDurationSeconds = CMTimeGetSeconds(audioDuration);

请注意,AVFoundation被设计为高度异步的框架,目的是提高性能和整体用户体验。即使执行简单的任务(如查询媒体文件的持续时间)也可能需要很长时间,并可能导致应用程序挂起。您应该使用AVAsynchronousKeyValueLoading协议异步加载歌曲的持续时间。然后在一个完成处理程序块中更新你的UI。你应该看看"块编程指南"以及WWDC2010视频"发现AV基础",这个视频可以在https://developer.apple.com/videos/wwdc/2010免费获得。

cqoc49vn

cqoc49vn2#

对于任何还在寻找这个的人,基于答案,Swift 4的代码(包括从苹果文档中获取的值的异步加载):

let audioAsset = AVURLAsset.init(url: yourURL, options: nil)

audioAsset.loadValuesAsynchronously(forKeys: ["duration"]) {
    var error: NSError? = nil
    let status = audioAsset.statusOfValue(forKey: "duration", error: &error)
    switch status {
    case .loaded: // Sucessfully loaded. Continue processing.
        let duration = audioAsset.duration
        let durationInSeconds = CMTimeGetSeconds(duration)
        print(Int(durationInSeconds))
        break              
    case .failed: break // Handle error
    case .cancelled: break // Terminate processing
    default: break // Handle all other cases
    }
}
xlpyo6sf

xlpyo6sf3#

您可以在Swift中使用以下方法实现相同的功能:

let audioAsset = AVURLAsset.init(url: audioFileURL, options: nil)
let duration = audioAsset.duration
let durationInSeconds = CMTimeGetSeconds(duration)
vjrehmav

vjrehmav4#

完整性-还有另一种方法可以获取mp3文件的持续时间:

NSURL * pathToMp3File = ...
NSError *error = nil;
AVAudioPlayer* avAudioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:pathToMp3File error:&error];

double duration = avAudioPlayer.duration; 
avAudioPlayer = nil;

我已经使用这个没有明显的延迟。

dpiehjr4

dpiehjr45#

雨燕5.0 + iOS 13:这是我唯一的工作方式(@John Goodstadt解决方案在Swift中)。目前我不知道为什么,但有一个记录的音频文件(在我的情况下,语音备忘录)和接收的音频文件之间的平均0.2秒的差异使用以下代码。

do {
        let audioPlayer = try AVAudioPlayer(contentsOf: fileURL)
        return CGFloat(audioPlayer.duration)
    } catch {
        assertionFailure("Failed crating audio player: \(error).")
        return nil
    }
edqdpe6u

edqdpe6u6#

我通过AVAudioRecorder录制了一个线性PCM文件(.pcm)。我在Farhad Malekpour的帮助下得到了持续时间。也许这个可以帮助你:iPhone:获取音频文件的持续时间

NSURL *fileUrl = [NSURL fileURLWithPath:yourFilePath];
AudioFileID fileID;
OSStatus result = AudioFileOpenURL((__bridge CFURLRef)fileUrl,kAudioFileReadPermission, 0, &fileID);
Float64 duration = 0; //seconds. the duration of the audio.
UInt32 ioDataSize = sizeof(Float64);

result = AudioFileGetProperty(fileID, kAudioFilePropertyEstimatedDuration, 
&ioDataSize, &duration);
AudioFileClose(fileID);
if(0 == result) {
   //success
}
else {
  switch (result) {
    case kAudioFileUnspecifiedError:{
        //
    } break;
        // other cases...
    default:
        break;
  }
}
gjmwrych

gjmwrych7#

如果可以,请尝试以下较新的方法:

let asset = AVURLAsset(url: fileURL, options: nil)

// Returns a CMTime value.
let duration = try await asset.load(.duration)

// An array of AVMetadataItem for the asset.
let metadata = try await asset.load(.metadata)

// A CMTime value and an array of AVMetadataItem.
let (duration, metadata) = try await asset.load(.duration, .metadata)

**注意:**同时加载多个属性可使AVFoundation通过批量加载请求来优化性能。

这里有一个来自苹果文档Loading media data asynchronously的简洁指南。

czq61nw1

czq61nw18#

使用AVAssetReader获取音频文件的持续时间

guard let assetReader = try? AVAssetReader(asset: audioAsset) {
    return nil
}
let duration = Double(assetReader.asset.duration.value)
let timescale = Double(assetReader.asset.duration.timescale)
let totalDuration = duration / timescale
print(totalDuration)
ibps3vxo

ibps3vxo9#

实际上,我发现您可以使用“从音乐获取详细信息”块,并将其设置为“获取持续时间“,其中可以是来自提示的MP3输入、指向MP3的链接、来自共享表的MP3等

相关问题