首页 > 解决方案 > HTML5 音频擦过缓冲区在 chrome 中有效,但在 Firefox 中无效

问题描述

我正在实现一个基于网络的音乐播放器,但我遇到了关于擦洗/跳过的问题。我正在使用 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);

状态行被注释掉了,因为我一直在尝试不同的标题和状态代码组合,试图让它工作。这篇 MDN 文章(忽略了它在谈论 ogg 而我的数据是 flac 的事实)说 Gecko 可以寻找尚未加载的音频区域,只要服务器通告Accept-Ranges: bytes标头并返回206所有字节范围请求的状态代码。然而,由此产生了两个问题。一,即使遵循这些准则,在 Firefox 中擦洗仍然失败,二,当206启用返回状态代码时,Chrome 根本无法播放任何音频。

查看 Firefox 中的开发人员工具,我看到只发出了一个请求,并且直到音频缓冲到最后才完成:

火狐开发工具

另一方面,Chrome 会按照我的预期执行,并在擦过已经缓冲的区域时根据需要触发多个具有不同字节范围的 HTTP 请求,如图所示。

chrome 开发工具

然而,值得注意的是,这仅在 Web 服务器响应状态码时有效200,而不是206. 如果我不得不猜测其中的原因,我会说第一个请求应该返回200,随后的清理/缓冲请求应该返回206,但我不确定如何区分这些请求。

无论如何,我真的很感激任何关于如何使它工作的指示。我正在考虑 HTML5 可能<audio>不是正确的途径。据我所知,像 Spotify 这样的流行音乐流媒体服务无论如何都会重新实现这一点,所以也许这是有原因的。或者很可能我缺少一些后端逻辑,因为我使用的是自定义服务器而不是 nginx,在这种情况下,可能的解决方案可能是将静态音频数据托管在单独的 nginx 服务器上。这些只是我的想法,真的希望有人能帮助阐明这一点。

标签: firefoxrustcross-browserhtml5-audio

解决方案


尝试发送audio/x-flac内容类型。
此外,范围请求通常会用content-range标头来回答,这可能就是 Firefox 无法获取的原因。


推荐阅读