【问题标题】:HTML5 audio - currentTime attribute inaccurate?HTML5 音频 - currentTime 属性不准确?
【发布时间】:2014-10-17 13:12:09
【问题描述】:

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

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

如果我让歌曲从头到尾播放,这实际上效果很好 - 歌曲的结尾是正确确定的。

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

(前面的“几秒钟”基于 Chrome,Firefox 似乎完全发疯了,这导致差异更大。)

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

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

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

【问题讨论】:

  • 我正在解决这个确切的问题。我只遇到过“长”mp3 的问题,当向前和向后跳过时,currentTime 属性越长,越不可靠。这对我来说是一个真正的问题。你曾经用 mp3 解决过这个问题吗?
  • 正如接受答案下方的评论中所述:您可以使用替代 JavaScript 技术来解码 MP3 文件,而不是依赖 HTML5 音频。 Aurora.js 对我来说做得很好。 (github.com/audiocogs/aurora.js)
  • 谢谢 Loilo,我去看看极光。

标签: javascript html audio mp3 html5-audio


【解决方案1】:

在与这个神秘问题作斗争数小时后,我相信我已经弄清楚这里发生了什么。这不是 .ogg 与 .mp3 的问题,而是 mp3(可能还有其他文件类型)上的可变比特率编码与恒定比特率编码的问题。

我不能把发现这一点归功于我,只是为了搜索互联网。早在 2015 年 2 月 1 日,绅士和学者 Terrill Thompson 就这个问题写了一封detailed article,其中包括以下摘录:

可变比特率 (VBR) 使用一种算法来有效地压缩 媒体,在低比特率和高比特率之间变化,具体取决于 给定时刻数据的复杂性。恒定比特率 (CBR),在 相反,使用相同的比特率压缩文件。 VBR 比 CBR 更有效,因此可以传递 较小的文件大小具有可比的质量,这听起来很有吸引力, 是吗?

不幸的是,如果正在流式传输媒体,则需要进行权衡 (包括渐进式下载),特别是如果定时文本 涉及。据我所知,VBR 编码的 MP3 文件无法播放 如果用户向前或向后滑动,则可靠的时间。

我正在为遇到此同步问题(这使得音频和文本的精确同步变得不可能)的其他人写这篇文章,因为如果你这样做了,弄清楚发生了什么真是一场噩梦。

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

【讨论】:

  • 如果您对此有任何运气,请告诉我!
  • 嘿@AlexKempton,在搞砸了一段时间后,我发现它实际上与你的 mp3 上的可变比特率与恒定/固定比特率绝对相关。长话短说,使用恒定/固定比特率,你不应该有问题(根据我的经验)。使用可变比特率,您可能会遇到令人讨厌的时序问题。 terrillthompson.com/blog/624
  • 哇 - 谢谢你把这个放在那里。不是一件容易搜索的事情。只需在服务器上将我的 .wav 文件转换为 .mp3(或几乎任何文件)即可解决此问题。
【解决方案2】:

首先,我实际上无法在我的机器上重现您的问题,但我现在手边只有一个简短的 MP3 文件,所以这可能是问题所在。无论如何,我想我可以解释发生了什么。

MP3 文件 (MPEG) 是非常简单的流,其中没有绝对位置数据。不可能通过读取文件的第一部分来知道某个任意帧开始的字节偏移量。媒体播放器通过落针查找文件。也就是说,它知道整个轨道的大小以及您的时间偏移量在轨道中的大致距离。它猜测并开始解码,一旦与下一个帧头同步就开始解码。这是一个不精确的过程。

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

另一个问题是大多数支持 MP3 的浏览器这样做只是因为编解码器已经在您的系统上可用。播放 Ogg Vorbis 和 MP3 通常是具有不同 API 的完全不同的库。虽然 Web 标准在提供通用抽象方面做了很多工作,但次要的实现细节会导致您看到的怪癖。

【讨论】:

  • 遗憾的是,这听起来很合理,尽管我想知道即使它已完全加载浏览器也无法处理它 - 但实际上我对 MP3 格式本身的工作原理并不是很熟悉。那么其他 HTML5/JS 框架是如何解决这个问题的呢?你认为深入研究这个主题(阅读有关 AudioContext API)可以解决这个问题吗?
  • @Loilo 完全下载和完全解码是两件不同的事情。即使浏览器拥有所有可用的数据流,它也可能不会为了获得样本准确的搜索点而一直解码。旧的 MP3 播放器会这样做(Winamp v1),这很痛苦!尽管这些天来,解码 MP3 的速度比实时解码快得多。您可以在此处阅读有关比特流格式的更多信息:mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm 此处有关实际编解码器本身的更多信息:mp3-converter.com/mp3codec
  • 感谢您的链接。我刚刚测试了更多这样的东西,我什至可以用 SoundJS 和其他流行的 JS 库重现这个问题 - 所以它似乎真的完全基于 MP3 格式。多可惜。所以我可能无法为我的 MP3 编写基于网络的音频播放器。 ;)
  • @Loilo 所有这些库都在后台使用完全相同的浏览器实现。唯一没有的是 Aurora。
  • 是的,遗憾的是似乎没有任何办法。所以我只能希望OGG会变得更受欢迎。 ;) 感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多