【发布时间】:2018-09-02 22:16:35
【问题描述】:
如何让 HTML5 音频元素立即开始播放低比特率的音频流?
有关问题的实时示例,visit this webpage。
问题
我正在将低比特率的 ogg/opus 流式传输到 HTML5 音频元素。除了一个问题,它运行良好。
在我测试过的两个浏览器(Chrome 和 Firefox)上,浏览器会缓冲直到接收到 32 kB 的数据。这可以是音频文件 20-40 秒内的任何时间。
当命中~32 kB 时,浏览器会触发loadeddata 事件以及3 的readyState,紧接着是canplay 事件。
示例代码:
<audio id="test" controls="controls" autoplay>
<source src="https://SCRIPT" type="audio/ogg; codecs=opus"/>
</audio>
<script>
var obj = document.getElementById('test');
obj.addEventListener('canplay', function() {
console.log("Can play event");
});
obj.addEventListener('canplaythrough', function() {
console.log("can play through event");
});
obj.addEventListener('loadeddata', function() {
console.log("Loaded data event");
console.log(obj.readyState);
});
</script>
我尝试用.play()“ping”它,但没有成功。
当加入一个已经进行了至少一分钟的流时(服务器可以立即提供大量数据),音频基本上会立即开始播放。问题是当流是新的(即刚刚创建)并且没有足够的数据来触发看似任意的播放点时,因为应用程序应该是低开销的。
这种延迟水平是不可接受的,坦率地说,这确实令人困惑。为什么与要求更高的流相比,开销较低的流延迟时间更长?这与人们认为的常识相反。
我想到了更复杂的解决方法,但最好使用广泛使用的 HTML5 音频来完成这项工作。
问题
- 有谁知道如何强制
.play(),即使readyState是0或在canplay事件之前? - 有没有办法修改初始缓冲区/延迟设置?
- 除了在文件头页中放置 30 kB 的垃圾之外还有什么想法吗?
更新信息
我在 Chrome 允许的情况下尽可能频繁地记录 audio.readyState,并发现它在 loadeddata 触发前几毫秒从 0 ("HAVE_NOTHING") 更改为 1 (HAVE_METADATA)。正如我之前提到的,它更改为3 ("HAVE_FUTURE_DATA") 和loadeddata。
这是一个来自 Chrome 的日志示例,末尾的整数是readyState
12:49:36.199 StreamTest.php:94 0(页面加载)
...(打印“0”)...
12:49:54.497 StreamTest.php:94 0
12:49:54.503 StreamTest.php:94 1
12:49:54.505 StreamTest.php:74 加载数据事件
12:49:54.505 StreamTest.php:75 3
12:49:54.505 StreamTest.php:66 可以播放事件
更新 2
这些是流标头:
HTTP/1.0 200 OK
Date: Sun, 25 Mar 2018 08:54:07 GMT
Server: Apache
Accept-Ranges: none
Cache-Control: max-age=0, no-cache, no-store, must-revalidate
Pragma: no-cache
Connection: close
Expires: Wed, 11 Jan 1984 05:00:00 GMT
X-Frame-Options: sameorigin
Content-Type: audio/ogg; codecs=opus
测试页
更新 3
我创建了一个测试页面,其中包含一些测试来演示 HTML5 音频播放行为。看到这个网页:http://webtests.online/LiveHTML5Audio.php
【问题讨论】:
-
您是否收到有关 play() 作为 Promise 的任何错误或警告?
-
没有。不在 FF 或 Chrome 上。其他的没试过。它似乎忽略了它。我添加了以下内容,并且没有错误消息:try{ obj.play(); }catch(error){ console.log("播放失败");控制台日志(错误); }
-
试试
preload="auto"或“无” -
我在 Chrome 中测试了这些,它看起来是相同的行为。我以 Chrome 允许的频率记录
audio.readyState,发现它在loadeddata触发前几毫秒从0("HAVE_NOTHING") 变为1(HAVE_METADATA)。正如我之前提到的,它使用loadeddata更改为3("HAVE_FUTURE_DATA")。感谢您的光临和提示。我将继续尝试任何人建议的一切。 -
Web Audio APi 使用了一个可以处理此类问题的缓冲区。这是example that uses the
<audio>tag and audio buffer over XHR
标签: html audio html5-audio audio-streaming