PHP流媒体MP3

时间:2010-03-01 18:53:34

标签: php mp3 header filestream readfile

我的问题非常类似于: Can I serve MP3 files with PHP? 基本上我试图保护mp3文件免受直接下载,因此用户必须先通过php才能获得首次验证。 这是我的代码:

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);

这是我的问题:文件只占一开始的一小部分(通过浏览器中的Quicktime)然后停止 - Quicktime似乎认为文件的长度只与它管理的块一样长下载。当我重新加载时 - 它会播放一个稍微大一点的块 - 无论它设法下载到那一点。

这是我发送的标头中的问题吗?我该如何传输这样的文件? 如果swf正在从该文件中读取,这是一个问题吗?

谢谢!


谢谢你们所有答案。虽然这些事情都没有解决问题,但其中许多人都把我引向了正确的方向。非常感激。 有关完整解决方案,请参阅下面的答案

7 个答案:

答案 0 :(得分:8)

这就是诀窍。

$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");
}

答案 1 :(得分:1)

您可以尝试HTTP chunking。将“Transfer-Encoding”标头设置为“chunked”,然后在发送之前输出每个chunk的大小。用CRLF结束每个块大小和块。

对于任何更复杂的内容,我建议使用流媒体服务器,例如Icecast

答案 2 :(得分:1)

有两件事突出:

  1. 你有Content-Length套。如果您将服务器设置为自动gzip您的输出,这可能会搞乱事情。尝试关闭Content-Length并查看是否可以解决此问题。
  2. 你有大约一千Content-Type套。既然你正在服务的是Mp3,那就使用audio/mpeg。您可以有效地删除整个最后header()命令。使用HTTP标头很容易被搞砸。
  3. 尝试一下,让我们知道它是怎么回事!

答案 3 :(得分:0)

如果您的服务器在apache或lighty上运行,我建议您查看x-sendfile

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

这允许您在php应用程序中处理身份验证,但让您的Web服务器处理文件的传输。你获得的性能提升应该是一个很好的额外好处

答案 4 :(得分:0)

删除header("Content-Transfer-Encoding: binary");您将被设置!

答案 5 :(得分:0)

对于这些解决方案,您还需要在apache(mod_xsendfile)或nginx HttpSecureLinkModule中配置xsendfile - 它们将为您提供精确的mp3,因此浏览器将正确播放

答案 6 :(得分:0)

不幸的是,应用所有这些有效隐藏原始路径和文件名的解决方案并不能防止未经授权的下载。 事实上,客户端(在我的情况下:Chrome)下载文件。

这是我放在服务器上的行:

<?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");
}
?>

有或没有线

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

最终结果不会改变 目录/ mp3位于

/home/myuser/

(因此/ home / myuser / mp3) 公共HTML目录是

/home/myuser/public_html

因此调用我的域名并提供

/player.php?file=music.mp3

它会下载一个名为music.mp3的文件,其中包含所有原始内容。