iPhone:获取音频文件的持续时间

9

如何获取音频文件的持续时间?

我可以创建一个AVAudioPlayer对象,用URL初始化它,然后获取持续时间,但这种方法太麻烦了。有没有更简单的方法?

谢谢。


可能是如何在iOS中获取音频文件的持续时间?的重复问题。 - user471651
8个回答

15

正确的代码是

NSURL *afUrl = [NSURL fileURLWithPath:soundPath];
AudioFileID fileID;
OSStatus result = AudioFileOpenURL((CFURLRef)afUrl, kAudioFileReadPermission, 0, &fileID);
Float64 outDataSize = 0;
UInt32 thePropSize = sizeof(Float64);
result = AudioFileGetProperty(fileID, kAudioFilePropertyEstimatedDuration, &thePropSize, &outDataSize);
AudioFileClose(fileID);

outDataSize 应该是 Float64 类型而不是 UInt64。


我现在已经开始编写Objective-C一天了,所以请原谅我的初学者问题。我该如何将outDataSize转换为一个保存毫秒的int类型? - Brett Sutton

10

您可以使用Audio File Services函数。有一个属性可用于获取预计的持续时间。 代码:

    NSURL *afUrl = [NSURL fileURLWithPath:soundPath];
    AudioFileID fileID;
    OSStatus result = AudioFileOpenURL((CFURLRef)afUrl, kAudioFileReadPermission, 0, &fileID);
    Float64 outDataSize = 0;
    UInt32 thePropSize = sizeof(Float64);
    result = AudioFileGetProperty(fileID, kAudioFilePropertyEstimatedDuration, &thePropSize, &outDataSize);
    AudioFileClose(fileID);
你可以在这里查看文档:这里

谢谢,但我不明白,为什么每次outDataSize都等于0? - Ilya Suzdalnitski
谢谢你的解决方案,我找到了问题所在。 - Ilya Suzdalnitski
嘿,这一点都不公平,你使用实际的知识来得到检查,而不是对你从未接触过的操作系统的模糊推测。 :) - MusiGenesis
1
@Ilya:很高兴它起作用了! @MusiGenesis:我必须在某些答案上使用实际知识! - pgb
注意了,数据类型必须是Float64而不是UIInt64! - Paresh Masani

2

将AVAudioPlayer与Swift结合变得非常简单(我正在迁移下面的Realm表,但你可以理解这个想法):

import AVFoundation

let resource = old!["filename"] as? String
let afUrl = NSBundle.mainBundle().URLForResource(resource, withExtension: nil)
let player = try! AVAudioPlayer(contentsOfURL: afUrl!)

new!["duration"] = Double(player.duration)

2

如果您了解有关音频文件的信息(采样率、位深度、通道数),并且它是未压缩的格式(WAV/AIFF),那么您可以从文件大小计算出大致持续时间:

持续时间(秒)=(文件长度-猜测100字节的文件头大小)/(采样率*(位深度*通道数/8))


头部只有100字节?经典的44字节呢? :) - MusiGenesis
我做这个已经14年了,应该知道得更好,但就在上个月,我花了半天时间试图找出我的声音开头那个小的“咔嗒”声是从哪里来的。我使用了我的快速而简单的方法,只考虑了44字节的头文件。我再次吸取了教训。 - MusiGenesis
1
你可以使用dataOffset,我猜它表示头部大小。`SInt64 dataOffset = 0; UInt32 dataOffsetSize = sizeof(dataOffset); AudioFileStreamGetProperty(inAudioFileStream, kAudioFileStreamProperty_DataOffset, &dataOffsetSize, &dataOffset);` - pronebird

2

这取决于文件类型。如果是WAV格式的文件,您可以找到文件头并确定播放持续时间。如果是压缩格式(*.mp3等),最好使用您提到的方法。


1
 AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:mp3_url options:nil];
                    [audioAsset loadValuesAsynchronouslyForKeys:@[@"duration"] completionHandler:^{
                        CMTime audioDuration = audioAsset.duration;
                        float audioDurationSeconds = CMTimeGetSeconds(audioDuration);

                        NSLog(@"duration:%f",audioDurationSeconds);
                    }];

1

这是来自iOS中如何获取音频文件的持续时间?的最佳答案示例代码。

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

1

如果有人想要获取音频和视频文件的时长,可以看一下另一篇帖子中的这个答案,它使用了AVAsset

https://dev59.com/fm435IYBdhLWcg3wxDL_#7052147

使用 AudioFileGetProperty(像这里的其他两个主要答案一样)来获取A/V文件的持续时间在我的设备上无法为一些 .mov 文件工作(结果始终为0),而使用 AVAsset 的解决方案可以获取我设备上所有音频和视频文件的持续时间。

(有趣的是,不过,从这两种解决方案中获得的持续时间有时比实际 AVAudioPlayer UI 中显示的持续时间多1秒。最可能是 AVAudioPlayer 使用了非标准舍入例程来显示持续时间。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接