如何使用PHP通过HTTP打开大文件,然后在浏览器中显示以供查看


How can I open large files over HTTP with PHP, then display in the browser for viewing?

我有一个tomcat服务器(服务器A),它有大量渐进式流式编码的mp4视频和mp3音频文件,并且位于专用网络上。我还有一个运行Apache 2和PHP的Web服务器(服务器B),它在专用网络上,有一个面向公众的界面。服务器 B 管理应用程序 ACL。

我希望客户端(比如浏览器)能够转到服务器 B 公共接口上的特定 URL,并能够从专用服务器下载(在播放器中收听或查看)媒体。目前,在服务器B上,我已经尝试了以下方法:

<?php
$handler = fopen('http://server_a/path/to/file.mp4', 'r');
header('Content-type: video/mp4');
while (!feof($handler)) {
    print fread($handler, 8192);
}
exit;

<?php
$handler = fopen('http://server_a/path/to/file.mp4', 'r');
header('Content-type: video/mp4');
print stream_get_contents($handler);
exit;

<?php
$handler = fopen('http://server_a/path/to/file.mp4', 'r');
header('Content-type: video/mp4');
fpassthru($handler);
exit;

所有这些PHP要么内存不足,要么客户端(浏览器)将在开始播放之前下载整个文件。我走错路了吗?关于我可能做错了什么的任何想法?

不,这就是它的工作方式。基本上,您的php将文件显示为文件。你的PHP脚本是从"我不是HTML文件,我是MP4文件,这是我的内容"开始的。PHP 不是你想要的流媒体

为什么不尝试使用HTML5视频或音频,指向你的PHP脚本?

第一个和第三个选项不应该耗尽内存,但是,我建议在服务器 B 上为特定路径设置一个代理(例如 /path/to/videos/ )。

http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass

我不确定它是否会满足部分内容请求,这是您必须弄清楚的。

其次,有两件事可以解释为什么浏览器必须在播放前下载整个文件:

  1. 文件未针对网络流进行优化;您可以使用MP4Box对其进行优化(即将元数据标头放在文件的前面)
  2. 文件大小是未知的;使用上述代理或可以解析的 PHP header()

刷新循环中的缓冲区!!

function flush_buffers(){
   ob_end_flush();
   ob_flush();
   flush();
   ob_start();
}