NSDictionary* fileAttributes =
[[NSFileManager defaultManager] attributesOfItemAtPath:filename
error:nil]
从文件属性键中,您可以获取日期,大小等。但是如何获得持续时间?
答案 0 :(得分:125)
在'File Attribute Keys' of the NSFileManager class reference中你可以看到没有使用的键可以返回歌曲的持续时间。 NSFileManager 实例获取文件的所有信息都与操作系统中实际文件本身的属性有关,例如文件大小。 NSFileManager 实际上并不解释该文件。
为了获取文件的持续时间,您需要使用知道如何解释文件的类。 AVFoundation 框架提供了您需要的确切类, AVAsset 。您可以使用具体的子类 AVURLAsset 实例化此抽象类的实例,然后为其提供 NSURL ,它指向您希望获得持续时间的音频文件。然后,您可以通过查询其duration
属性从 AVAsset 实例获取持续时间。
例如:
AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:audioFileURL options:nil];
CMTime audioDuration = audioAsset.duration;
float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
请注意,AVFoundation被设计为一个高度异步的框架,以提高性能和整体用户体验。即使执行简单的任务(例如查询媒体文件的持续时间)也可能需要很长时间,并且可能导致应用程序挂起。您应该使用AVAsynchronousKeyValueLoading protocol异步加载歌曲的持续时间,然后在完成处理程序块中更新UI。您应该查看'Block Programming Guide'以及WWDC2010视频“发现AV基础”,该视频可在https://developer.apple.com/videos/wwdc/2010免费获得。
答案 1 :(得分:14)
为了完整性 - 还有另一种获取mp3文件持续时间的方法:
NSURL * pathToMp3File = ...
NSError *error = nil;
AVAudioPlayer* avAudioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:pathToMp3File error:&error];
double duration = avAudioPlayer.duration;
avAudioPlayer = nil;
我使用了这个没有明显的延迟。
答案 2 :(得分:8)
您可以使用以下方法在Swift中实现相同的目标:
let audioAsset = AVURLAsset.init(url: audioFileURL, options: nil)
let duration = audioAsset.duration
let durationInSeconds = CMTimeGetSeconds(duration)
答案 3 :(得分:4)
对于仍在寻找此事的人。 根据答案, Swift 4 的代码(包括从Apple&#39的文档中获取的异步加载值):
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
}
}
答案 4 :(得分:0)
Swift 5.0 + iOS 12 :这是它为我工作的唯一方式(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
}
答案 5 :(得分:0)
我通过AVAudioRecorder
录制了线性PCM文件(.pcm)。我得到了Farhad Malekpour的帮助。也许这可以帮助您:
iPhone: get duration of an audio file
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;
}
}
答案 6 :(得分:0)
我实际上发现您可以只使用“从音乐中获取详细信息”块并将其设置为“获取持续时间”,其中可以是来自提示的 mp3 输入、指向 mp3 的链接、来自共享表的 mp3等