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

发布于 2024-08-14 17:20:41 字数 763 浏览 7 评论 0原文

我正在尝试找出在 iPhone 上使用 AudioFileStream 和 AudioQueue API 播放 mp4(或 m4a)音频文件时执行向前跳过或搜索的正确技术。

如果我将完整的 mp4 标头(直到 mdat 框)传递给打开的 AudioFileStream,则可以正确识别底层音频文件类型(在我的例子中为 AAC),然后当我传递文件的实际 mdat 数据部分时,AudioFileStream正确地开始生成音频数据包,这些数据包可以发送到音频队列并进行播放。

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

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

我似乎找不到任何有关使用 AudioFileStream 和 AudioQueue 时随机播放 mp4 文件部分的文档。我发现 Apple 的 QuickTime 文件格式 pdf 描述了在 mp4 文件中随机查找的技术,但这只是高级描述,没有提及使用特定的 API(例如 AudioFileStream)。

感谢您的任何见解。

I'm trying to figure out the proper technique for performing skipping ahead or seeking within an mp4 (or m4a) audio file while playing it using the AudioFileStream and AudioQueue APIs on the iPhone.

If I pass the complete mp4 header (up to the mdat box) to an open AudioFileStream, the underlying audio file type is properly identified (in my case, AAC) and when I then pass the actual mdat data portion of the file, the AudioFileStream correctly begins generating audio packets and these can be sent to the AudioQueue and playback works.

However, if I try a random access approach to the playing back the file, I can't seem to get it to work properly, unless I always send the first frame of the mdat box to the AudioFileStream. If instead, after sending the mp4 header to the AudioFileStream, I then attempt to initially skip ahead to a later frame in the mdat by first calling AudioFileStreamSeek() and then passing the data for the associated packets, the AudioFileStream appears to generate audio packets, but when I pass these on to the AudioQueue and call AudioQueuePrime(), I always get an error of 'nope' returned.

My question is this: am I always required to at least pass in the first packet of the mdat box before attempting to do random playback of other packets in the mp4 file?

I can't seem to find any documentation on doing random playback of sections of an mp4 file while using an AudioFileStream and an AudioQueue. I've found Apple's QuickTime File Format pdf which describes the technique of randomly seeking within an mp4 file, but it's just a high level description and doesn't have any mention of using specific APIs (such as AudioFileStream).

Thanks for any insights.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

撞了怀 2024-08-21 17:20:41

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

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

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

如果省略这些额外的字节,则 AudioQueuePrime() 调用将始终失败并出现“nope”错误,即使您可能已将有效的已解析音频数据包发送到 AudioQueue。

It turns out the approach I was using with AudioFileStreamSeek() is valid, I just wasn't sending the full initial mp4 header to the AudioFileStreamParseBytes() routine.

The problem was I had assumed the packets began immediately after the mdat box tag. By examining the data offset value (kAudioFileStreamProperty_DataOffset) returned by the AudioFileStream Property Listener callback, I discovered the true start of the packet data was 18 bytes later.

These 18 bytes are considered part of the initial mp4 header that must be sent to the AudioFileStream parser before sending the data of arbitrary packets after calls to AudioFileStreamSeek().

If these extra bytes are left out, then the AudioQueuePrime() call will always fail with a 'nope' error even though you may have sent valid parsed audio packets to the AudioQueue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文