2

如何在 iPhone 上的流式音频中实现搜索(时间线功能)?

AudioFileStreamSeek 方法接受我想要开始搜索的字节偏移量。我希望能够获得正在播放的 mp3 的当前位置,并让用户在稍后的时间点返回(搜索)到相同的位置。

但是我找不到任何知道已经播放的字节数的方法。我可以找出已流式传输的字节数。但无法找出已经播放了多少字节。我使用 Matt Gallagher 的音频流示例作为基础。

任何帮助是极大的赞赏。

谢谢。

或许只能找到解决办法。AudioFileStreamSeek 文档说

调用此函数后,解析器假定传递给 AudioFileStreamParseBytes 函数的下一个数据从 outAbsoluteByteOffset 参数中返回的字节偏移开始。

我们如何做到这一点?我们应该使用 Http Range 参数吗?如果我们将字节偏移量发送到 Range,它会按预期工作吗?我应该如何清除缓冲区中的现有字节以避免两个流一起播放?

非常感谢任何帮助。谢谢。

4

3 回答 3

2

AudioFileStreamSeek 适用于数据包,而不是字节数。因此,您真正需要跟踪的是数据包计数。

Matt 代码中的 MyEnqueueBuffer 方法是将缓冲区发送到 AudioQueue 进行播放的地方。在 packetfilled 重置为 0 之前,抓取 packetfilled 并增加索引变量:

myData.absolutePackets = myData.absolutePackets + myData->packetsFilled;

我的问题是,即使使用此值,我也无法正确实现 AudioFileStreamSeek。因此,如果您有一些使用 Matt 的代码进行搜索的示例代码,请分享。

谢谢!

于 2009-03-20T15:17:50.507 回答
1

我还没有真正尝试过 AudioFileStream API(我们在内部推出了自己的 API),但这里有一些你必须注意的事情。

假设你随机寻找字节流没有问题,那么你必须不断跟踪 MP3 帧号和绝对字节流位置之间的关系,就像 Paul 所说的那样。我假设您可以在 AudioFileStream_PacketsProc 中通过调用 AudioFileStreamSeek 来做到这一点。

这是更棘手的部分。当您进行随机搜索时,您必须重置 AudioFileStream 的内部状态。因为它可能处于某种中间状态,期待下一个传入字节完成当前帧。我不确定您是否可以只输入零以使其跳过当前帧并重新开始(您必须尝试,因为我在 API 中看不到任何类似 AudioFileStreamReset 的东西;但是,音频队列本身确实具有重置功能,您可以清理已经排队的帧)。无论如何,您也必须照顾您的 AudioFileStream_PacketsProc,因为您将解析您已经跟踪的字节流的一部分。

请注意,您不能仅仅依靠第二个和比特率来找到 MP3 帧的开始。即使使用非可变速率 MP3 流,每隔几帧也可能有填充。所以最准确的信息仍然来自解析器。

我应该快速补充一点,另一种进行随机搜索的方法是简单地“缓存”(存储)解析的数据包,如果你没有播放一个非常长的大流。帧索引可以从帧头信息中计算出来。对于非 VBR MP3,每秒帧数是一个常数(例如,对于 44.1 kHz 立体声非 VBR MP3,每秒帧数是 44100/1152 = 38.28125 帧;请查看 MP3 规范了解为什么会这样)。

于 2009-03-21T06:52:03.800 回答
0

您可以将 AudioQueueStart 与您要寻找的地方的 mSampletime 一起使用吗?

所以只是停止播放....并从不同的采样时间开始?[只需获取当前的采样时间并根据需要进行操作?]

inDeviceStartTime 音频队列应该开始的时间。

要指定相对于关联音频设备的时间线的开始时间,请使用 AudioTimeStamp 结构的 mSampleTime 字段。使用 NULL 指示音频队列应尽快启动。

返回值 结果代码。请参阅“音频队列结果代码”。</p>

讨论 如果关联的音频设备尚未运行,此函数将启动它。

于 2009-04-14T20:38:29.013 回答