PHP 流媒体 MP3
我和提问者的情况很相似: 我可以使用 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 正在从该文件读取,是否有问题?
谢谢!
谢谢大家的回答。尽管这些事情都不能完全解决问题,但其中许多都给我指明了正确的方向。非常感谢。 对于完整的解决方案,请参阅下面我的回答
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这就是成功的秘诀。
Here's what did the trick.
您可以尝试 HTTP 分块。将“Transfer-Encoding”标头设置为“chunked”,然后在发送之前输出每个块的大小。每个块大小和块以 CRLF 结束。
对于更复杂的事情,我建议使用流媒体服务器,例如 Icecast。
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.
有两件事很突出:
Content-Length
。如果您的服务器设置为自动对输出进行 gzip 压缩,这可能会造成混乱。尝试关闭Content-Length
并查看是否可以解决问题。Content-Type
。由于您提供的是 Mp3,因此只需使用audio/mpeg
。您可以有效地摆脱最后一个header()
命令。人们很容易被 HTTP 标头迷惑。尝试一下,让我们知道效果如何!
Two things stand out:
Content-Length
set. If you server is set to automatically gzip your output, this can mess with things. Try turning offContent-Length
and see if that fixes it.Content-Type
s set. Since it's Mp3 that you're serving, just useaudio/mpeg
. You can effectively get rid of the whole lastheader()
command. It's easy to get carried away with HTTP headers.Try it out and let us know how it goes!
如果您的服务器在 apache 或 lighty 上运行,我建议您查看 x-sendfile
http://tn123。 ath.cx/mod_xsendfile/
这允许您在 php 应用程序中处理身份验证,但让您的网络服务器处理文件的传输。您获得的性能改进应该是一个不错的额外好处
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
删除
header("Content-Transfer-Encoding: binary");
然后你就准备好了!Remove
header("Content-Transfer-Encoding: binary");
And you'll be set!对于这些解决方案,您还需要在 apache (mod_xsendfile) 或 nginx HttpSecureLinkModule 中配置 xsendfile - 它们将为您提供准确的 mp3,以便浏览器能够正确播放
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
不幸的是,应用所有这些可有效隐藏原始路径和文件名的解决方案并不能防止未经授权的下载。
事实上,客户端(在我的例子中:Chrome)下载了该文件。
这是我放在服务器上的行:
无论有没有行,
最终结果都不会改变
目录 /mp3 位于
(因此 /home/myuser/mp3)
因此,公共 HTML 目录
调用我的域并让它
下载一个名为 music.mp3 的文件,其中包含所有原始内容。
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:
with or without the line
the final result doesn't change
The directory /mp3 is located into
(thus /home/myuser/mp3)
and the public HTML directory is
thus calling my domain and giving
it downloads a file called music.mp3 with all the original content.