通过PHP流式传输时,Safari中的音频持续时间始终返回无穷大

GRO*_*ER. 6 javascript php

出于某种原因,在Safari(没有其他主要浏览器)中,当我通过PHP通过JavaScript中Audio上下文提供MP3时,MP3 的持续时间始终返回为。infinity

在过去的几天里,这个问题困扰着我,在阅读了一些链接(包括链接)以寻找解决方案之后,我根本没有进步。


我的密码

PHP:

$path = "path/to/file.mp3";
$file = [
    "path"      => $path,
    "size"      => filesize($path),
    "bitrate"   => $bitrate
];

header("Accept-Ranges: bytes", false);
header("Content-Length: " . $file["size"], false);
header("Content-Type: audio/mpeg", false);

echo file_get_contents($file["path"]);

exit;
Run Code Online (Sandbox Code Playgroud)

JavaScript:

var audio = new Audio(url);
// returns infinite on Safari
// returns 312.27311 on Chrome and Firefox (which is correct)
console.log(audio.duration);
Run Code Online (Sandbox Code Playgroud)

我仍未弄清楚为什么这个问题仅出现在Safari中,以及首先导致它的原因,因此,如果有人有解决方案,将不胜感激!

干杯。

bri*_*pie 6

经过像你一样的大量调查,我终于弄明白了。

Safari 发送的第一个请求具有标头:

Range: bytes=0-1
Run Code Online (Sandbox Code Playgroud)

您的工作是“正确”响应,以便 Safari 发送额外的请求来获取文件的其余部分。

这是我的“正确”标题示例:

Content-Length: 2
Accept-Ranges: bytes
Content-Range: bytes 0-1/8469
(Make sure you set response status to 206!)
(8469 is the Content-Length of the entire file)
Run Code Online (Sandbox Code Playgroud)

之后发生的事情有点神奇 - Safari 发送了一个包含以下标头的后续请求:

Range: bytes=0-8468
Run Code Online (Sandbox Code Playgroud)

你应该像这些标题一样“正确”响应:

Content-Length: 8469
Accept-Ranges: bytes
Content-Range: bytes 0-8468/8469
(Again, status 206!)
Run Code Online (Sandbox Code Playgroud)

我希望这可以为您解决问题,因为我花了很多时间搜索无济于事。我最终意识到我需要调整我的服务器来处理存在 Range 标头的请求。

我使用此提交来帮助我了解“正确”响应是什么:https : //github.com/jooby-project/jooby/commit/142a933a31b9d8742714ecd38475d90e563314f7