PHP Streaming MP3

不羁的心 提交于 2019-11-26 15:49:57

问题


I have a very similar situation to the person who asked: Can I serve MP3 files with PHP? Basically I am trying to protect mp3 files from direct download, so users have to go through php to get authenticated first. Here's my code:

header('Content-type: audio/mpeg');
header('Content-length: ' . filesize($file));
header('X-Pad: avoid browser bug');
Header('Cache-Control: no-cache');
header("Content-Transfer-Encoding: binary"); 
header("Content-Type: audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3");
readfile($file);

Here's my problem: The file only plays a very small chunk of the beginning (via Quicktime in the browser) and then stops - Quicktime seems to think the length of the file is only as long as the chunk it managed to download. When I reload - it plays a slightly larger chunk - whatever it managed to download up to that point.

Is that a problem in the headers I am sending? How would I stream such a file? Is it a problem if an swf is reading from that file?

Thanks!


Thank you guys for all the answers. Although none of these things were exactly what solved the problem, many of them sent me in the right direction. Much appreciated. For the full solution see my answer below


回答1:


Here's what did the trick.

$dir = dirname($_SERVER['DOCUMENT_ROOT'])."/protected_content";
$filename = $_GET['file'];
$file = $dir."/".$filename;

$extension = "mp3";
$mime_type = "audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3";

if(file_exists($file)){
    header('Content-type: {$mime_type}');
    header('Content-length: ' . filesize($file));
    header('Content-Disposition: filename="' . $filename);
    header('X-Pad: avoid browser bug');
    header('Cache-Control: no-cache');
    readfile($file);
}else{
    header("HTTP/1.0 404 Not Found");
}



回答2:


You can try HTTP chunking. Set the "Transfer-Encoding" header to "chunked", then output the size of each chunk before sending it. End each chunk size and chunk with a CRLF.

For anything more complex, I recommend using a streaming server, such as Icecast.




回答3:


Two things stand out:

  1. You've got a Content-Length set. If you server is set to automatically gzip your output, this can mess with things. Try turning off Content-Length and see if that fixes it.
  2. You've got about a thousand Content-Types set. Since it's Mp3 that you're serving, just use audio/mpeg. You can effectively get rid of the whole last header() command. It's easy to get carried away with HTTP headers.

Try it out and let us know how it goes!




回答4:


if your server is running on apache or lighty, i would suggest you look into x-sendfile

http://tn123.ath.cx/mod_xsendfile/

this allows you to handle authentication in your php application, but let's your webserver handle the transmission of the file. the performance improvement you gain should be a nice additional benefit




回答5:


Remove header("Content-Transfer-Encoding: binary"); And you'll be set!




回答6:


For these solution you also need to configure xsendfile in apache (mod_xsendfile) or nginx HttpSecureLinkModule - they will give you exact mp3, so browser will play it correctly




回答7:


Applying all these solutions, which are valid to hide the original path and filename, unfortunately doesn't prevent from unauthorized download. Indeed the client (on my case: Chrome) downloads the file.

Here the lines I put on my server:

<?php
$dir = dirname($_SERVER['DOCUMENT_ROOT'])."/mp3";
$filename = $_GET['file'];
$file = $dir."/".$filename;

$extension = "mp3";
$mime_type = "audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3";

if(file_exists($file)){
    header('Content-type: {$mime_type}');
    header('Content-length: ' . filesize($file));
    header("Content-Transfer-Encoding: binary"); 
    header('Content-Disposition: filename="' . $filename);
    header('X-Pad: avoid browser bug');
    header('Cache-Control: no-cache');
    readfile($file);
}else{
    header("HTTP/1.0 404 Not Found");
}
?>

with or without the line

    header("Content-Transfer-Encoding: binary"); 

the final result doesn't change The directory /mp3 is located into

/home/myuser/

(thus /home/myuser/mp3) and the public HTML directory is

/home/myuser/public_html

thus calling my domain and giving

/player.php?file=music.mp3

it downloads a file called music.mp3 with all the original content.



来源:https://stackoverflow.com/questions/2358253/php-streaming-mp3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!