HTML Audio Object报告错误的文件持续时间

时间:2017-12-24 12:50:45

标签: javascript html5 audio html5-audio

我开始使用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

2 个答案:

答案 0 :(得分:2)

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

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

所以我会尝试不同的编码器,直到找到一个正常工作的编码器。

答案 1 :(得分:2)

原因

问题是AAC是流式格式。这意味着没有像容器格式那样提供全局文件头(例如“mp4”),因此浏览器必须根据最初加载的的比特率猜测时间数据包标头(ADTS)和服务器提供的文件长度。

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

AAC也可以使用可变比特率(VBR)进行编码,这使得很难正确预测持续时间,因为在开头找到的比特率可能不是用于的比特率之后的其他样本包。

当然,文件/编码也有可能损坏或出错。

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

的变通方法

第一种是使用恒定比特率(CBR)对AAC进行编码。这将允许浏览器预测更可靠的时间,因为如果变化是显着的,VBR可以在任何点甩掉计算。这很可能会影响文件大小。

如果CBR不是一个选项,一种解决方法是为AAC流提供容器格式,例如MP4,它可以将持续时间存储在开头加载的全局标题中 - MP4s可以被Audio元素用作缓冲音频。执行此操作时,您将获得正确的时间(对于次要数字可能有一些舍入误差):

在Firefox中的MP4容器中加载AAC:
snapshot using mp4 container in firefox

AAC加载到Chrome中的MP4容器中
snapshot using mp4 container in chrome

要为AAC生成MP4容器,您可以使用带有这些参数的免费ffmpeg,这些参数将按原样复制AAC(不会进行重新编码,因此结果将具有相同的质量和如前所述的比特率):

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

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

  

[aac @ 0000000001c624a0]从比特率估算持续时间,这可能不准确[...]

另一种可能不那么方便的解决方法是将持续时间作为元数据提供,例如文件名本身(类似“myfile_MMSS.aac”)或url中的hash-tag /参数,或者单独加载元数据。

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