问题描述
我正在开发 iOS MPEG-DASH 播放器,但在搜索功能方面遇到问题。
ExtAudioFileSeek(::) documentation 说
将文件的读取位置设置为指定的样本帧编号。对 ExtAudioFileRead(::_:) 函数的后续调用将返回来自该位置的样本,即使它位于数据包的中间。
不幸的是,AudioToolBox.AudioFile_ReadProc
循环不会直接寻找正确的帧,而是遍历所有文件段,请求 16 和 27682 字节的包。
需要很多时间(特别是对于长音轨)并强制下载所有中间片段(这不应该是必需的)
这也会导致应用在播放高音质长曲目时崩溃。
这里是我的日志跟踪。我将帧索引转换为“mega”以提高可读性。
[PlayerEngine] - Trying to seek at 16.870537 %
[AudioSource] - Pausing AudioOutputUnit
[AudioSource] - AudioOutputUnit successfully stopped
[AudioOutputUnit] - Trying to seek at frame 31.006805M
[AudioOutputUnit] - Successfully sought at frame 31.006805M
[AudioInputUnit] - Audio frames have been flushed
[AudioInputUnit] - Seek to frame 31.006806M pending
[AudioConverter] - Converted frame buffer has been flush
[AudioSource] - Resuming AudioOutputUnit
[AudioSource] - AudioOutputUnit successfully resumed
[PlayerEngine] - Successfully sought at 16.870537 %
[AudioInputUnit] - Seeking to frame 31.006805M
[CoreAudioDecoder] - Trying to seek at frame 31.006805M
[CoreAudioDecoder] - Seek on frame 31.006806M done successfully
[CoreAudioDecoder] - AudioToolBox.AudioFile_ReadProc : inClientData,inPosition:1.315635M,requestCount:16
(...)
[CoreAudioDecoder] - AudioToolBox.AudioFile_ReadProc : inClientData,inPosition:1.331687M,requestCount:27682
非常感谢!
解决方法
酷!
既然您提到了读取回调,我假设您不仅使用 ExtAudioFile
API,还使用 AudioFile
API,例如 ExtAudioFileWrapAudioFileID(AudioFileInitializeWithCallbacks(...))
压缩音频格式并不总是在帧和文件偏移之间有简单的映射,因此您看到的幼稚行为可能是由于其中一个 API (AudioFile
?) 不知道这种映射,这是可以理解的。
尝试在包装的音频文件的 kExtAudioFileProperty_PacketTable
或 ExtAudioFile
上设置 kAudioFilePropertyPacketTableInfo
属性。前者可能更有意义。我不知道整个数据包表信息是否会从一开始就提供给您,或者是否会随着时间的推移向您显示,也不知道 API 会如何对您多次设置这些属性做出反应。
祝你好运!