【问题标题】:PHP Streaming MP3PHP 流媒体 MP3
【发布时间】:2011-01-22 10:18:18
【问题描述】:

我的情况与提问的人非常相似: 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 正在从该文件中读取,会不会有问题?

谢谢!


谢谢大家的回答。尽管这些东西都不能完全解决问题,但其中许多都让我朝着正确的方向前进。非常感激。 有关完整的解决方案,请参阅下面的答案

【问题讨论】:

  • 我想你的真实代码中没有那个错字(“标题”)?此外,您不需要 X-Pad hack。这仅对古老的 Netscape 是必需的(请参阅george.hotelling.net/90percent/geekery/…)。您不需要 Content-Transfer-Encoding,您应该只指定一次 Content-Type(音频/mpeg 可以)。
  • @Matthew Flaschen:PHP 函数不区分大小写,所以这只是一个一致性问题。 Content-Type 可能是这里真正的问题。

标签: php mp3 header filestream readfile


【解决方案1】:

不幸的是,应用所有这些有效隐藏原始路径和文件名的解决方案并不能防止未经授权的下载。 确实是客户端(在我的情况下: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 的文件,其中包含所有原始内容。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        这就是诀窍。

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

        【讨论】:

        • 您可能想在阅读之前对 $_GET['file'] 进行一些验证/清理...
        • 我检查文件是否存在if(file_exists($file)){...是你的意思吗?
        • 不,他不是那个意思。自己想想,如果有人尝试这个会发生什么yoursite.com/yourscript.php?file=../../../home/…
        • 它很棒,但它不可搜索!!
        • 要使其可搜索,只需添加以下标题行,但此代码中不支持恢复。 header('Accept-Ranges: bytes'); 如果您需要 Content-Transfer-Encoding,最好尝试使用 header("Content-Transfer-Encoding: chunked");
        【解决方案5】:

        有两点很突出:

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

        试试看,告诉我们结果如何!

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            【解决方案7】:

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

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

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-04-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-04-19
              • 2012-01-30
              相关资源
              最近更新 更多