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

I have a tomcat server (Server A) which has a ton of progressively streaming encoded mp4 video and mp3 audio files and is on a private network. I also have a web server (Server B) running Apache 2 and PHP which is on the private network and has a public facing interface. Server B manages application ACL.

I want a client (say a browser) to be able to go to a specific url on Server B's public interface, and be able to download, (listen or view in a player) the media from the private server. At the moment, on server B, I have tried the following:

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

and

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

and

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

All of which PHP will either run out of memory or the client (browser) will download the entire file before even beginning to play. Am I going the wrong way about this? Any ideas on what I could be doing wrong?

No, that's the way it works. Basically your php is showing the file as a file. Your PHP script is going from "I'm not an HTML file, I'm an MP4 File, and here's my contents". PHP is not what you want for streaming

Why not try using HTML5 Video or Audio, pointing to your PHP script?

The first and third option should not run out of memory, however, I would suggest to set up a proxy on server B for a particular path (e.g. /path/to/videos/).

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

I'm not sure whether it will honour partial content requests, something you will have to figure out.

Secondly, there are two things that could explain why the browser has to download the whole file before playback:

  1. the file is not optimized for web streaming; you can use MP4Box to optimize it (i.e. bring the meta data headers to the front of the file)
  2. the file size is unkown; using either the aforementioned proxy or PHP's header() that can be resolved.

Flush buffers on your loop!!!

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