HTML 音频对象报告错误的文件持续时间

HTML Audio Object reporting wrong file duration

我开始使用 AAC 音频文件而不是 MP3 来避免时间漂移,但现在我发现自己在 Chrome 中遇到问题,报告音频持续时间不正确。

我有一个示例音频可以帮助说明问题。音频的实际持续时间是 22:01 但 Chrome 显示的持续时间是 20:13 但如果您实际播放音频结束时,持续时间开始变化,直到成为正确的持续时间。

Sample AAC audio here!

问题的根源是什么?我读到也许可以通过输入正确的元数据来解决,但它似乎是正确的...

一些有趣的数据:

Chrome 中的 MP3 显示 21:58

Safari 中的 AAC 显示 22:10

Safari 中的 MP3 显示确切的持续时间 22:01

有没有机会让它在任何地方都一样工作?

我留下MP3文件以防万一here

您的音频编码有问题。这是音频文件本身,而不是浏览器。确保将原始文件保存为 44.1KHz/16 位 WAV,并使用可靠的 AAC 编码器。

我拿了你的AAC文件,用Adobe Audition打开,保存为44/16 WAV,用XLD (MacOS)编码成AAC。我将 AAC 文件拖到 Chrome 中,它正确地报告了持续时间。

所以我会尝试不同的编码器,直到您找到合适的编码器。

原因

问题在于 AAC 是一种 流式传输 格式。这意味着没有全局文件 header 作为容器格式提供(例如“mp4”),因此浏览器必须 猜测 基于 [=64 的时间=] 从初始加载的 数据包 headers (ADTS) 和服务器提供的文件长度。

由于浏览器在整个流被消耗之前不知道实际样本长度,因此结果将根据浏览器(或底层系统)尝试预测持续时间的方式而有所不同。

AAC 也可以用 可变比特率 (VBR) 编码,这使得很难正确预测持续时间,因为在开头找到的 bit-rate 可能不会成为稍后用于其他示例数据包的bit-rate。

当然也有可能 file/encoding 损坏或有故障。

这些相同的挑战也适用于 MP3 文件。这就是为什么它们有时也会显示不正确的持续时间。

解决方法

首先是使用常数 bit-rate (CBR) 对 AAC 进行编码。这将使浏览器能够更可靠地预测时间,因为如果变化明显,VBR 可以在任何时候放弃计算。这很可能会影响文件大小。

如果 CBR 不是一个选项,一种解决方法是为 AAC 流(例如 MP4)提供 容器格式,它可以在全局 header 中存储持续时间在开头加载 - MP4 可以作为音频元素的缓冲音频使用。这样做时,您将得到正确的时间(小数位可能有一些舍入误差):

AAC 在 Firefox 的 MP4 容器中加载:

AAC 加载到 Chrome
中的 MP4 容器中

要为 AAC 生成 MP4 容器,您可以使用带有这些参数的免费 ffmpeg,这将复制 AAC as-is(没有 re-encoding 发生,因此结果将与以前具有相同的质量和 bit-rate):

ffmpeg.exe -i "Lesson+53-A.aac" -c:a copy "Lesson+53-A.mp4"

你还会看到 ffmpeg 指出这个问题:

[aac @ 0000000001c624a0] Estimating duration from bitrate, this may be inaccurate [...]

另一个可能不太方便的解决方法是将持续时间作为元数据提供在例如文件名本身(类似于“myfile_MMSS.aac”)或作为 url 中的 hash-tag/argument,或 side-load 单独的元数据。

后者会有一定的影响,因为我们无法覆盖本机播放器的持续时间字段(以 cross-browser 友好的方式),这可能需要您构建自定义播放器界面,以便您可以将元数据显示为持续时间而不是浏览器预测的持续时间。