某些浏览器中生成音频的时序问题

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;