在Linux + FireFox上使用PHP流式传输mp3

时间:2012-03-11 04:46:05

标签: php apache firefox streaming mp3

我正在尝试使用PHP流式传输mp3文件并在浏览器上播放它。 我正在使用Ubuntu服务器(apache)和客户端进行测试。我的代码适用于Chrome,但不适用于FireFox。 当我直接访问mp3(因此它由Web服务器提供服务)时,它也适用于FireFox,但是将Web服务器生成的标头与我用PHP发送的标头进行比较,我找不到如何解决问题。 (我正在使用FireBug监视标题)

以下是网络服务器生成的标题(确实有效):

Accept-Ranges   bytes
Connection  Keep-Alive
Content-Length  490265
Content-Type    audio/mpeg
Date    Sun, 11 Mar 2012 04:01:45 GMT
Etag    "22064e-77b19-4badff4a88200"
Keep-Alive  timeout=5, max=100
Last-Modified   Sat, 10 Mar 2012 09:15:52 GMT
Server  Apache/2.2.20 (Ubuntu)

以下是从我的PHP脚本发送到浏览器的标题:

Accept-Ranges   bytes
Cache-Control   no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection  Keep-Alive
Content-Length  490265
Content-Type    audio/mpeg
Date    Sun, 11 Mar 2012 04:16:00 GMT
Expires Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive  timeout=5, max=100
Pragma  no-cache
Server  Apache/2.2.20 (Ubuntu)
X-Powered-By    PHP/5.3.6-13ubuntu3.6

这是我用来传输mp3的代码:

header('Content-length: ' . filesize($path));
header('Content-Type: audio/mpeg');
header('Accept-Ranges: bytes');

readfile($path);

exit;

我也尝试了其他没有帮助的标题,例如:

header('Content-Disposition: inline; filename="name.mp3"');
header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
header('Pragma: no-cache');
header('Cache-Control: no-cache');

但正如我所说,这些都没有解决问题。

非常感谢您的帮助,

乌迪德。

编辑:

好的,这似乎非常奇怪。经过大量调试后,我确保PHP版本和Web服务器版本的标题和内容是相同的,然后我发现了什么打破了它,但我不知道为什么。以下是打破它的场景:

  • 1)在前一个脚本中将$ _SESSION中的路径字符串存储起来。
  • 2)在流式传输mp3的脚本中读取此字符串。
  • 3)使用此字符串作为加载mp3文件的路径。

如果我这样做,FireFox无法播放该文件,当我按下mp3播放器时,它会打印一个“GstDecodeBin2:这似乎是一个文本文件”消息。 如果我硬编码路径而不是使用$ _SESSION,它可以工作。疯狂的是我绝对确定$ _SESSION中的路径是正确的!请记住,PHP和Web服务器版本的标题和内容是相同的!

2 个答案:

答案 0 :(得分:0)

HTTP Accept-Ranges标头允许浏览器发送要下载的文件的起点和终点,这允许多部分下载同一文件。这里有很多PHP实现,这里有一个在fread()的PHP.net文档页面上。

http://www.php.net/manual/en/function.fread.php#106999

答案 1 :(得分:0)

我发现使用WireShark监控请求的问题是什么。之前我使用过FireBug和HTTPFox,他们没有显示所有请求!

WireShark告诉我,在初始成功请求之后,还有另一个请求相同的URI。第二个请求没有被xdebug捕获,并且被FireBug和HTTPFox错过了。问题是这个请求不包括PHPSESSID!结果显然会话没有成功,因为它确实在第一次请求时工作,我很困惑。 在我看来,这就像FireFox及其媒体播放器模块中的一个错误。 我可以通过手动将PHPSESSID作为查询字符串添加到URL来解决此问题。