57
NSDictionary* fileAttributes = 
    [[NSFileManager defaultManager] attributesOfItemAtPath:filename 
                                                     error:nil]

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

4

7 回答 7

143

NSFileManager类参考的“文件属性键”中,您可以看到没有可以使用的键来返回歌曲的持续时间。NSFileManager实例获取的有关文件的所有信息都与操作系统中实际文件本身的属性有关,例如文件大小。NSFileManager实际上并不解释文件。

为了获得文件的持续时间,您需要使用一个知道如何解释文件的类。AVFoundation框架提供了您需要确切类AVAsset您可以使用具体的子类AVURLAsset实例化这个抽象类的实例,然后为它提供一个指向您希望获得持续时间的音频文件的NSURL 。然后,您可以通过查询AVAsset实例的属性来获取持续时间。duration

例如:

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

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

于 2011-08-13T17:32:53.647 回答
15

对于任何仍在寻找这个的人。根据答案,Swift 4的代码(包括从 Apple 文档中获取的值的异步加载):

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
    }
}
于 2018-05-28T12:15:40.213 回答
14

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

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

double duration = avAudioPlayer.duration; 
avAudioPlayer = nil;

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

于 2012-10-31T14:23:22.780 回答
13

你可以在 Swift 中使用:

let audioAsset = AVURLAsset.init(url: audioFileURL, options: nil)
let duration = audioAsset.duration
let durationInSeconds = CMTimeGetSeconds(duration)
于 2017-12-24T05:36:14.777 回答
7

Swift 5.0 + iOS 13:这是它对我有用的唯一方法(Swift 中的@John Goodstadt 解决方案)。目前我不确定为什么,但是使用以下代码录制的音频文件(在我的情况下是语音备忘录)和接收到的音频文件之间平均存在 0.2 秒的差异。

    do {
        let audioPlayer = try AVAudioPlayer(contentsOf: fileURL)
        return CGFloat(audioPlayer.duration)
    } catch {
        assertionFailure("Failed crating audio player: \(error).")
        return nil
    }
于 2019-05-06T07:01:27.390 回答
1

我通过AVAudioRecorder. 我在 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;
  }
}
于 2020-02-17T03:16:48.263 回答
-1

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

于 2021-07-26T17:20:41.807 回答