HTML5音频 - currentTime属性不准确?

8

我正在尝试使用HTML5的<audio>标签,并注意到一些与currentTime属性有关的奇怪行为。

我想播放本地音频文件,并让timeupdate事件通过比较currentTime属性和duration属性来检测它何时完成。

如果我让歌曲从开始到结束播放,这实际上相当好用 - 歌曲的结尾被正确确定。

但是,手动更改currentTime(直接通过JavaScript或使用基于浏览器的音频控件)会导致API不再返回正确的currentTime值,而似乎将其设置在实际播放位置之前的几秒钟。

(这些“几秒钟”的提前量基于Chrome,Firefox似乎完全疯狂,导致差异要大得多。)

这是一个关于问题的小jsFiddle示例:http://jsfiddle.net/yp3o8cyw/2/

有人能告诉我为什么会发生这种情况吗?还是我没有理解API应该做什么?

P.S.:我刚刚注意到,这实际上只发生在MP3编码文件中,OGG文件完全没问题。


我正在遇到这个确切的问题。我只在“长”mp3上遇到了问题,越长,当向前和向后跳跃时,currentTime属性变得越不可靠。这对我来说是一个真正的问题。你曾经能够解决过mp3的这个问题吗? - Brian FitzGerald
1
如下评论所述:您可以使用替代的JavaScript技术来解码MP3文件,而不是依赖于HTML5音频。Aurora.js对我来说非常好用。(https://github.com/audiocogs/aurora.js/) - Loilo
谢谢Loilo,我会去看看Aurora。 - Brian FitzGerald
2个回答

16
经过几个小时的解决这个神秘问题,我相信我已经弄清楚了这里发生了什么。这不是.ogg与.mp3的问题,而是关于mp3(以及其他文件类型)中变量比特率编码和恒定比特率编码的问题。
我不能为发现这一点而自取功名,只能在互联网上搜索。Terrill Thompson先生是一位绅士学者,他在2015年2月1日写了一篇详细文章detailed article,其中包括以下摘录:

可变比特率(VBR)使用算法对媒体进行高效压缩,根据给定时刻数据的复杂性在低和高比特率之间变化。相反,恒定比特率(CBR)使用相同的比特率压缩文件。 VBR比CBR更有效,因此可以以更小的文件大小提供与CBR相当质量的内容,这听起来很有吸引力,是吗?

不幸的是,如果媒体正在流式传输(包括渐进式下载),特别是涉及定时文本,则存在折衷。正如我所了解的那样,如果用户向前或向后快进,VBR编码的MP3文件无法进行可靠的定时播放。

我为任何遇到此同步问题的人编写此文(这使得音频和文本的精确同步成为不可能),因为如果您遇到此问题,要弄清楚发生了什么真是一场噩梦。

我的下一步是进行更多测试,最终找出将所有.mp3转换为恒定比特率的高效方法。 我想FFMPEG可能能够帮助,但我将在另一个线程中探讨这个问题。 还要感谢Loilo最初发布此问题以及Brad分享的信息。


请告诉我您是否有任何进展! - AlexKempton
3
嘿 @AlexKempton,我折腾了一会儿后发现这实际上与你的 MP3 文件使用变量码率和固定码率有绝对关系。简而言之,使用固定码率,就不应该遇到问题(根据我的经验)。如果使用可变码率,则可能会遇到时间问题。http://terrillthompson.com/blog/624 - Brian FitzGerald
1
哇 - 感谢您将这个发布出来。这不是一个容易搜索的事情。在服务器上简单地将我的 .wav 文件转换为 .mp3(或几乎任何格式)就可以解决这个问题。 - Ryan Martin

4

首先,我无法在我的机器上复现您的问题,但是我目前只有一个很短的MP3文件,所以可能是这个问题的原因。不管怎样,我认为我可以解释一下发生了什么。

MP3文件(MPEG)是非常简单的流,它们没有绝对位置数据。从文件的开头读取并不可能知道任意帧开始的字节偏移量。媒体播放器通过needle dropping在文件中查找。也就是说,它知道整个音轨的大小和您的时间偏移量大致在哪里。它会猜测并开始解码,一旦同步到下一个帧头,就会立即恢复。这是一个不精确的过程。

Ogg是一个更强大的容器,并且在其帧头中内置了时间偏移量。在Ogg文件中搜索要简单得多。

另一个问题是,大多数支持MP3的浏览器之所以支持是因为编解码器已经在您的系统上可用。播放Ogg Vorbis和MP3通常需要使用完全不同的库和不同的API。虽然Web标准提供了共同的抽象,但是像您看到的那样,小的实现细节会导致问题。


很遗憾,这听起来相当可信,虽然我想知道即使浏览器完全加载了,它为什么不能处理 - 但实际上我对MP3格式本身的工作方式并不是很熟悉。那么其他HTML5 / JS框架是如何解决这个问题的呢?你认为深入研究这个主题(阅读AudioContext API)可以解决这个问题吗? - Loilo
@Loilo 完全下载和完全解码是两个不同的概念。即使浏览器已经有了所有的数据流,它也可能不会完全解码以获取一个准确的样本点。旧的 MP3 播放器就是这样做的(Winamp v1),而且非常痛苦!虽然现在,MP3 的解码速度比实时还要快得多。您可以在此处阅读有关比特流格式的更多信息:http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm 有关实际编解码器本身的更多信息,请参见:http://www.mp3-converter.com/mp3codec/ - Brad
谢谢提供的链接。 我刚刚测试了更多类似的东西,甚至可以在像SoundJS等流行的JS库中重现问题 - 所以它似乎真的只基于MP3格式。真遗憾。所以我可能无法为我的MP3编写基于Web的音频播放器。;) - Loilo
2
@Loilo 所有这些库在后台都使用完全相同的浏览器实现。唯一不同的是 Aurora。 - Brad
是的,遗憾的是似乎没有任何绕过的方法。所以我只能希望OGG会变得更加流行。谢谢你的帮助! - Loilo
哦,而且要赞一个提到Aurora.js的人。这个东西看起来真的很棒! - Loilo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接