在MP4文件中播放跳过/搜索

时间:2009-12-10 16:44:16

标签: iphone mp4 m4a

我正在尝试找出适当的技术,用于在使用iPhone上的AudioFileStream和AudioQueue API播放它时,在mp4(或m4a)音频文件中执行跳过或寻找。

如果我将完整的mp4标题(直到mdat框)传递给打开的AudioFileStream,则正确识别基础音频文件类型(在我的情况下,AAC),然后我传递文件的实际mdat数据部分,AudioFileStream正确地开始生成音频数据包,这些数据包可以发送到AudioQueue并播放。

但是,如果我尝试使用随机访问方法来播放文件,我似乎无法正常工作,除非我总是将mdat框的第一帧发送到AudioFileStream。如果相反,在将mp4标头发送到AudioFileStream后,我首先尝试通过首先调用AudioFileStreamSeek()然后传递相关数据包的数据来跳过mdat中的后一帧,AudioFileStream似乎生成音频数据包,但当我将这些传递给AudioQueue并调用AudioQueuePrime()时,我总是会收到'nope'错误。

我的问题是:在尝试随机播放mp4文件中的其他数据包之前,我是否总是要求至少传入mdat框的第一个数据包?

在使用AudioFileStream和AudioQueue时,我似乎无法找到有关对mp4文件各部分进行随机播放的文档。我发现了Apple的QuickTime文件格式pdf,它描述了在mp4文件中随机搜索的技术,但它只是一个高级描述,并没有提到使用特定的API(例如AudioFileStream)。

感谢您的任何见解。

1 个答案:

答案 0 :(得分:3)

事实证明我使用AudioFileStreamSeek()的方法是有效的,我只是没有将完整的初始mp4标头发送到AudioFileStreamParseBytes()例程。

问题是我假设数据包在mdat box标签之后立即开始。通过检查AudioFileStream Property Listener回调返回的数据偏移值(kAudioFileStreamProperty_DataOffset),我发现数据包数据的真正开始时间是18个字节。

这18个字节被认为是初始mp4标头的一部分,必须在调用AudioFileStreamSeek()之后发送任意数据包的数据之前将其发送到AudioFileStream解析器。

如果遗漏了这些额外的字节,那么即使您可能已经将有效的已解析音频数据包发送到AudioQueue,AudioQueuePrime()调用也将始终失败并显示“nope”错误。