Rom*_*man 0 html javascript audio html5-audio
我开始使用 AAC 音频文件而不是 MP3 来避免时间漂移,但现在我发现自己在 Chrome 中遇到了一个报告错误音频持续时间的问题。
我有一个示例音频可以帮助说明问题。音频的实际持续时间是22:01,但 Chrome 显示的持续时间为20:13,但如果您实际播放音频的结尾,持续时间会开始变化,直到变为正确的持续时间。
问题的根源是什么?我读到也许它可以通过输入正确的元数据来解决,但它似乎是正确的......
一些有趣的数据:
Chrome 中的 MP3 显示21:58。
Safari 中的 AAC 显示22:10。
Safari 中的 MP3 显示确切的持续时间22:01。
有没有机会让它在任何地方都一样??
我把 MP3 文件留在这里以防万一
小智 8
问题是 AAC 是一种流格式。这意味着没有像容器格式那样提供全局文件头(例如“mp4”),因此浏览器必须根据初始加载的数据包头(ADTS)和提供的文件长度的比特率猜测时间服务器。
由于浏览器在整个流被消耗之前不知道实际样本长度,因此结果将根据浏览器(或底层系统)尝试预测持续时间的方式而有所不同。
AAC 也可以使用可变比特率(VBR)进行编码,这使得很难正确预测持续时间,因为在开始时找到的比特率可能不是以后用于其他样本数据包的比特率。
当然也有文件/编码损坏或错误的可能性。
顺便说一句,这些相同的挑战也适用于 MP3 文件。这就是为什么它们有时也会显示不正确的持续时间。
第一种是使用恒定比特率 (CBR) 对 AAC 进行编码。这将使浏览器能够更可靠地预测时间,因为如果变化很明显,VBR 可以在任何时候中断计算。这很可能会影响文件大小。
如果 CBR 不是一个选项,一种解决方法是为 AAC 流提供一种容器格式,例如 MP4,它可以将持续时间存储在开头加载的全局标头中 - MP4 可以作为音频元素作为缓冲音频使用。这样做时,您将获得正确的时间(小数位可能存在一些舍入错误):
在 Firefox 中加载到 MP4 容器中的 AAC:
AAC 加载到 Chrome 中的 MP4 容器中
要为 AAC 生成 MP4 容器,您可以使用例如带有这些参数的免费ffmpeg,它们将按原样复制 AAC(不进行重新编码,因此结果将具有与以前相同的质量和比特率):
ffmpeg.exe -i "Lesson+53-A.aac" -c:a copy "Lesson+53-A.mp4"
Run Code Online (Sandbox Code Playgroud)
你还会看到 ffmpeg 指出了这个问题:
[aac @ 0000000001c624a0] 根据比特率估计持续时间,这可能不准确 [...]
另一个可能不太方便的解决方法是提供持续时间作为元数据,例如文件名本身(类似于“myfile_MMSS.aac”)或作为 url 中的哈希标签/参数,或者单独加载元数据。
后者会产生一定的影响,因为我们无法覆盖本地播放器的持续时间字段(以跨浏览器友好的方式),这可能需要您构建自定义播放器界面,以便您可以将元数据显示为持续时间而不是浏览器预测的持续时间.