某些浏览器中生成音频的时序问题
Timing problem for generated audio in some browsers
我需要从 mp3 文件生成音频。所以我使用curl库来获取文件,然后设置所需的headers和echo
音频内容。
问题是它在 Chrome 和 Safari 浏览器中无法正常工作。正在加载音频文件并开始播放,但您无法更改时间(无法在 javascript 中设置 .currentTime
,并且在浏览器中,时间滑块不起作用)。 (在 Firefox 中工作正常)。
代码:php
$agent = 'stagefright/1.2 (Linux;Android 5.0)';
$url = 'http://www.jplayer.org/audio/mp3/Miaow-07-Bubble.mp3';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1) ;
curl_setopt($ch, CURLOPT_REFERER, 'http://www.jplayer.org/');
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
$media = curl_exec($ch);
curl_close($ch);
$content_length = strlen($media);
$type = "audio/mpeg";
header("Content-type: ".$type);
header("Content-length: ".$content_length);
echo $media;
exit;
有什么想法吗?
也许我错过了一些 php headers?
谢谢。
我猜,我漏了一个 php header。
需要添加以下内容header:
header('Accept-Ranges: bytes');
希望对某人有所帮助。
更新:
我在这里发现了一个非常相似的问题:HTML5 <audio> Safari live broadcast vs not
添加 Accept-Ranges
header 解决了 chrome 的问题。但是对于 safari,您需要检查 HTTP_RANGE
并添加 Content-Range
header.
这是我的实现,在所有主流浏览器中都可以正常工作。
$content_length = strlen($media_total);
$total_bytes = $content_length;
$content_length_1 = $content_length - 1;
if (isset($_SERVER['HTTP_RANGE'])) {
$byte_range = explode('-',trim(str_ireplace('bytes=','',$_SERVER['HTTP_RANGE'])));
$byte_from = $byte_range[0];
$byte_to = intval($byte_range[1]);
$byte_to = $byte_to == 0 ? $content_length_1 : $byte_to;
$media_total = substr($media_total,$byte_from,$byte_to);
$content_length = strlen($media_total);
header('HTTP/1.1 206 Partial Content');
}
else {
$byte_from = 0;
$byte_to = $content_length_1;
}
$content_range = 'bytes '.$byte_from.'-' . $byte_to . '/' . $total_bytes;
header('Accept-Ranges: bytes');
header("Content-Range: ".$content_range);
header("Content-type: ".$type);
header("Content-length: ".$content_length);
header('Content-Transfer-Encoding: binary');
echo $media_total;
exit;
我需要从 mp3 文件生成音频。所以我使用curl库来获取文件,然后设置所需的headers和echo
音频内容。
问题是它在 Chrome 和 Safari 浏览器中无法正常工作。正在加载音频文件并开始播放,但您无法更改时间(无法在 javascript 中设置 .currentTime
,并且在浏览器中,时间滑块不起作用)。 (在 Firefox 中工作正常)。
代码:php
$agent = 'stagefright/1.2 (Linux;Android 5.0)';
$url = 'http://www.jplayer.org/audio/mp3/Miaow-07-Bubble.mp3';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1) ;
curl_setopt($ch, CURLOPT_REFERER, 'http://www.jplayer.org/');
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
$media = curl_exec($ch);
curl_close($ch);
$content_length = strlen($media);
$type = "audio/mpeg";
header("Content-type: ".$type);
header("Content-length: ".$content_length);
echo $media;
exit;
有什么想法吗?
也许我错过了一些 php headers?
谢谢。
我猜,我漏了一个 php header。
需要添加以下内容header:
header('Accept-Ranges: bytes');
希望对某人有所帮助。
更新:
我在这里发现了一个非常相似的问题:HTML5 <audio> Safari live broadcast vs not
添加 Accept-Ranges
header 解决了 chrome 的问题。但是对于 safari,您需要检查 HTTP_RANGE
并添加 Content-Range
header.
这是我的实现,在所有主流浏览器中都可以正常工作。
$content_length = strlen($media_total);
$total_bytes = $content_length;
$content_length_1 = $content_length - 1;
if (isset($_SERVER['HTTP_RANGE'])) {
$byte_range = explode('-',trim(str_ireplace('bytes=','',$_SERVER['HTTP_RANGE'])));
$byte_from = $byte_range[0];
$byte_to = intval($byte_range[1]);
$byte_to = $byte_to == 0 ? $content_length_1 : $byte_to;
$media_total = substr($media_total,$byte_from,$byte_to);
$content_length = strlen($media_total);
header('HTTP/1.1 206 Partial Content');
}
else {
$byte_from = 0;
$byte_to = $content_length_1;
}
$content_range = 'bytes '.$byte_from.'-' . $byte_to . '/' . $total_bytes;
header('Accept-Ranges: bytes');
header("Content-Range: ".$content_range);
header("Content-type: ".$type);
header("Content-length: ".$content_length);
header('Content-Transfer-Encoding: binary');
echo $media_total;
exit;