1

I need to generate audio from an mp3 file. So I use curl library to get the file, then set required headers, and echo the audio content.

The problem is that it does not work correctly in Chrome and Safari browsers. The audio files being loaded, and starts playing, but you can't change the time(can't set .currentTime in javascript, also in browser the timing slider does not work). (In Firefox works fine).

The code: 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;

Any ideas?

Maybe I miss some php headers?

Thanks.

Simon
  • 22,637
  • 36
  • 92
  • 121

1 Answers1

1

As I guess, I was missing a php header.

Need to add the following header:

header('Accept-Ranges: bytes');

Hope that will help somebody.

UPDATE:

I found a very similar question here: HTML5 <audio> Safari live broadcast vs not

Adding the Accept-Ranges header fix the issue for chrome. But for safari you need to check for HTTP_RANGE and add Content-Range header.

Here is my implementation, which works fine in all major browsers.

        $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;
Simon
  • 22,637
  • 36
  • 92
  • 121