我正在实现一个基于网络的音乐播放器,但我遇到了关于scrubbingskipping的问题。我使用了一个HTML5音频元素来播放,就像这样。
<audio controls id="playback-element">
<source src="/source/12">
</audio>
音频播放工作正常 然而,如果(在Firefox中)我试图跳过缓冲区域,如浅灰色高亮显示的那样,播放就会跳回到最新的缓冲区域,就像这样。
然而,同样的元素在Chrome浏览器中也能正常工作。
为音频文件提供服务的后端是一个自定义服务器,使用 经 网络框架。创建服务音频文件的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);
状态行被注释掉了 因为我一直在试验不同的头和状态码的组合 试图让它工作。这篇MDN文章 (忽略了它说的是ogg,而我的数据是flac)说,Gecko可以寻求尚未加载的音频区域,只要服务器宣传的 Accept-Ranges: bytes
头,并返回状态码 206
的所有字节范围请求。然而由此产生了两个问题。其一,即使遵循这些准则,在Firefox中,刷新仍然失败;其二,当返回状态码为 206
启用了,那么Chrome浏览器根本无法播放任何音频。
在Firefox的开发者工具中,我看到只有一个请求,而且直到音频缓冲到最后才完成。
而Chrome浏览器,则是我所期望的,当擦过已经缓冲的区域时,会根据需要发出多个不同字节范围的HTTP请求,如图所示。
然而,值得注意的是,只有当网络服务器响应状态码时,这才会发挥作用 200
,不 206
. 如果要我猜测其中的原因,我会说,第一个请求应该回到 200
,随后的scrubbuffer请求应返回 206
但我不知道如何区分这些请求。
无论如何,我真的很感激任何关于如何让这个工作的建议。我正在考虑,也许HTML5 <audio>
是不是正确的路线,这一点。据我所知,像Spotify这样的流行音乐流媒体服务无论如何都会自己重新实现这一点,所以也许有这样的原因。或者很有可能是我遗漏了一些后端逻辑,因为我使用的是自定义服务器而不是nginx,在这种情况下,一个可能的解决方案可能是在一个单独的nginx服务器上托管静态音频数据。这些只是我的想法,真的希望有人能帮我解惑。
试着发送 audio/x-flac
内容类型。另外,一个范围请求通常以 content-range
头,也许这就是Firefox无法获取的原因。