【发布时间】:2020-09-05 05:47:54
【问题描述】:
我正在实现一个基于网络的音乐播放器,但我遇到了关于擦洗/跳过的问题。我正在使用 HTML5 音频元素进行播放,如下所示:
<audio controls id="playback-element">
<source src="/source/12">
</audio>
音频播放效果很好。但是,如果(在 Firefox 中)我尝试跳过浅灰色突出显示的缓冲区,播放会跳回到最新的缓冲区,如下所示:
但是,相同的元素在 Chrome 中也可以正常工作。
提供音频文件的后端是使用warp Web 框架编写的自定义服务器。创建用于提供音频文件的 HTTP 响应如下所示:
let response = http::Response::builder()
.header(http::header::ACCEPT_RANGES, "bytes")
.header(http::header::CONTENT_TYPE, "audio/flac")
//.status(http::status::StatusCode::PARTIAL_CONTENT)
.body(data);
状态行被注释掉了,因为我一直在尝试不同的标题和状态代码组合,试图让它发挥作用。 This MDN article(忽略它在谈论 ogg 而我的数据是 flac 的事实)说 Gecko 可以寻找尚未加载的音频区域,只要服务器宣传 Accept-Ranges: bytes 标头并返回状态代码 206对于所有字节范围请求。然而,由此产生了两个问题。第一,即使遵循这些准则,在 Firefox 中清理仍然会失败,第二,当启用返回状态代码 206 时,Chrome 根本无法播放任何音频。
查看 Firefox 中的开发者工具,我发现只发出了一个请求,直到音频缓冲到最后才完成:
另一方面,Chrome 会按照我的预期执行,并在擦过已经缓冲的区域时根据需要触发多个具有不同字节范围的 HTTP 请求,如图所示。
然而,值得注意的是,这仅在 Web 服务器响应状态码 200 而不是 206 时有效。如果我不得不猜测其中的原因,我会说第一个请求应该返回200,随后的清理/缓冲请求应该返回206,但我不确定如何区分这些请求。
无论如何,我非常感谢有关如何使其正常工作的任何指示。我正在考虑 HTML5 <audio> 可能不是正确的路径。据我所知,像 Spotify 这样的流行音乐流媒体服务无论如何都会重新实现这一点,所以也许这是有原因的。或者很可能我缺少一些后端逻辑,因为我使用的是自定义服务器而不是 nginx,在这种情况下,可能的解决方案可能是将静态音频数据托管在单独的 nginx 服务器上。这些只是我的想法,真的希望有人能帮助阐明这一点。
【问题讨论】:
标签: firefox rust cross-browser html5-audio