14

我和那个问的人有一个非常相似的情况: 我可以用 PHP 提供 MP3 文件吗? 基本上我试图保护 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 正在从该文件中读取,会不会有问题?

谢谢!


谢谢你们所有的答案。尽管这些东西都不能完全解决问题,但它们中的许多都将我引向了正确的方向。非常感激。有关完整的解决方案,请参阅下面的答案

4

7 回答 7

10

这就是诀窍。

$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");
}
于 2010-03-02T22:54:40.127 回答
1

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

对于更复杂的事情,我建议使用流媒体服务器,例如Icecast

于 2010-03-01T18:58:25.877 回答
1

有两点很突出:

  1. Content-Length有一套。如果您的服务器设置为自动 gzip 您的输出,这可能会造成混乱。尝试关闭Content-Length并查看是否可以解决问题。
  2. 你有大约一千Content-Type套。由于您提供的是 Mp3,因此只需使用audio/mpeg. 您可以有效地摆脱整个最后一个header()命令。很容易被 HTTP 标头迷住。

试试看,让我们知道它是怎么回事!

于 2010-03-01T21:27:03.100 回答
0

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

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

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

于 2010-03-01T18:57:53.563 回答
0

删除header("Content-Transfer-Encoding: binary");,你会被设置!

于 2012-03-09T00:53:59.003 回答
0

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

于 2013-06-06T12:18:40.107 回答
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 的文件,其中包含所有原始内容。

于 2015-03-31T14:05:49.420 回答