Search code examples
phpcurldownloadmp3

PHP Curl mp3 download reseting meta data


I am having a website where downloading of mp3 is done, when I am downloading it through php(curl) the song gets downloaded but the meta data of song like album art, artist name etc is lost.

On server the file has all the data, but on downloading everything is lost. Heres my code:

if (!empty($path) && $path != null)
            {
                $ch = curl_init($path);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_HEADER, true);
                $data = curl_exec($ch);
                curl_close($ch);
                if ($data === false)
                {
                    echo 'CURL Failed';
                    exit;
                }

                if (preg_match('/Content-Length: (\d+)/', $data, $matches))
                {
                    $contentLength = (int) $matches[1];
                }

                header("Pragma: public");
                header("Expires: 0");
                header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
                header("Cache-Control: private", false); // required for certain browsers
                header('Content-Type: audio/mpeg');
                header("Content-Disposition: attachment; filename=\"" . urlencode($song->title) . ".mp3\";");
                header('Content-Transfer-Encoding: binary');
                header('Content-Length: ' . $contentLength);
                ob_clean();
                flush();
                echo $data;
                exit;
            }

Solution

  • You're forcing curl to add the hTTP response headers to your mp3 file, so you'll be getting something that looks like:

    HTTP/1.1 ...
    Content-type: audio/mpeg
    Content-length: 12345
    
    ID3v2.......
    mp3 data here
    

    Since the ID3 data isn't right at the beginning of the data you're sending out, the audio player can't locate it, because all it sees are the HTTP headers.

    If all you're doing with those headers is extracting the content-length, then why even bother doing that? You can use strlen() in PHP to calculate it for you. e.g.

    $mp3data = file_get_contents('url to mp3 file');
    $length = strlen($mp3data);
    
    header("Content-length: $length");
    echo $mp3data;