【问题标题】:Stream mp3 with PHP, on Linux+FireFox在 Linux+FireFox 上使用 PHP 流式传输 mp3
【发布时间】:2012-03-11 04:46:04
【问题描述】:

我正在尝试使用 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 版本和 webserver 版本的 headers 和 content 是相同的,然后我发现了什么破坏了它,但我不知道为什么。这是破坏它的场景:

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

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

【问题讨论】:

  • 是否你的脚本真的做范围?
  • 我不这么认为,我不知道范围是什么意思,我只是添加了这个标头,因为我看到网络服务器添加了它。

标签: php apache firefox streaming mp3


【解决方案1】:

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

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

【讨论】:

  • 谢谢,这是重要信息,但没有解决问题,在这种情况下浏览器不请求范围。我怀疑问题可能出在缓存控制上,您可以看到 PHP 发送的标头存在一些差异:它发送“Cache-Control no-store, no-cache, must-revalidate, post-check=0, pre-check=0”和“Pragma no-cache”。我会尝试以某种方式阻止 PHP 发送这些标头。
  • 由于评论太长,我编辑了问题,请见上文。
【解决方案2】:

我发现问题在于使用 WireShark 监控请求。之前我使用了 FireBug 和 HTTPFox,它们并没有显示所有请求!

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    相关资源
    最近更新 更多