6

I'm working on my school project and I'm trying to output a mp3 file using PHP but apparently it just outputs some corrupt file and I have no clue why. I browsed the entire net to find a solution, but no.

<?php
$filename = 'audio/1/1.mp3';

if(file_exists($filename)) {
    header('Content-Type: audio/mpeg');
    header('Content-Disposition: filename="test.mp3"');
    header('Content-length: '.filesize($filename));
    header('Cache-Control: no-cache');
    header("Content-Transfer-Encoding: chunked"); 

    readfile($filename);
} else {
    header("HTTP/1.0 404 Not Found");
}
?>

Can anyone explain this to me? That would be totally awesome!

Tim S.
  • 13,597
  • 7
  • 46
  • 72
  • Have you looked at the downloaded file in a text editor, or run it through a binary diff program, to see how it's different from the original server-side copy? There's nothing obviously wrong with your code. – Marc B Mar 11 '11 at 15:54
  • have you checked to see if there is any whitespace before the first php tags? – Ozzy Mar 11 '11 at 15:57

3 Answers3

6
header('Content-Disposition: inline;filename="test.mp3"');

That's what you're missing in your header() (you had no "inline" specified). Content-Transfer-Encoding should be "binary", not "chunked".

Edit: use "inline" if you want it to be displayed within the browser (if capabilities exist) or "attachment" if you want to force download.

Rene Pot
  • 24,681
  • 7
  • 68
  • 92
Furicane
  • 1,173
  • 6
  • 18
  • He needs Content-Disposition: attachment for this. Not inline. – osm Mar 11 '11 at 16:03
  • 1
    As you can see, I did provide explanation for both options ;) – Furicane Mar 11 '11 at 16:07
  • Didn't work. I've tried to download the file and play it with winamp which basically shows me a corrupt file like there are junks missing – Tim S. Mar 13 '11 at 19:38
  • Are you sure that the file you're readfile()-ing is not corrupt to begin with? – Furicane Mar 14 '11 at 00:55
  • Yeah it's not corrupt. Could there be something wrong in the server configuration? In the end it's returning a pretty big file – Tim S. Mar 15 '11 at 11:09
  • Open the file in the text editor and see what's the plain text output of it. – Furicane Mar 15 '11 at 11:42
  • Problem is sorted and I posted it as answer. It didn't had to do with the file nor this bit of script. Thanks for your help anyway! I gave you a thumb up – Tim S. Mar 15 '11 at 12:46
  • This was great info. Thanks. And "inline" is extremely useful. – Jake May 27 '13 at 16:28
0

can you try replace

header("Content-Transfer-Encoding: binary");
line with
header("Content-Transfer-Encoding: chunked"); 
osm
  • 4,186
  • 3
  • 23
  • 24
  • Is the \n really necessary? I'll have it a go soon! Thanks in advance – Tim S. Mar 11 '11 at 15:57
  • Didn't work. I've tried to download the file and play it with winamp which basically shows me a corrupt file like there are junks missing – Tim S. Mar 13 '11 at 19:02
0

Well the answer was way off and it wasn't my script. Before any HTML tag I load all content, if custom headers are defined I only show the content (retrieved from templates)

<?php
//get stuff
if(empty($page->customHeader)): ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><?php print $page->title ?></title>
</head>

<body>
<div class="container">
    <div class="header">
    </div>

    <div class="content">        
        <?php print $page->content ?>
    </div>

    <div class="footer">
    </div>
</div>
</body>
</html>
<?php else:
    print $page->content;
endif; ?>

For the templates i use ob_get_contents(), so in the actual template I echo/print data. For some reason ob_get_contents() doesn't fetch that properly so that's where it went wrong.

Now I define my headers in an array and the path of the content in another variable and call that.

...
</html>
<?php else:
    foreach($page->customHeader as $header) {
        header($header, true);
    }

    readfile($page->headerContent);
endif; ?>

Long story short: ob_get_contents() doesn't get binary content.

Thanks guys, definately going to give you thumbs up for the efford and rather useful information!

Tim S.
  • 13,597
  • 7
  • 46
  • 72