views:

217

answers:

1

I use a PHP script to validate video requests before serving them. This script works as expected on the desktop, with Safari and Chrome. But on iOS, I get a broken play button.

I'm sure the video is properly encoded for iPhone/iPad, because when I access it directly, it works as expected.

The relevant PHP code:

$file_name = 'test-video.mp4';
$file_size = (string)(filesize($file_name));
header('Content-Type: video/mp4');
header('Content-Length: '.$file_size);
readfile_chunked($file_name);
exit;

(readfile_chunked() is similar to readfile() but for very large files, found in the comments on the PHP manual page: http://php.net/manual/en/function.readfile.php. In any event, test-video.mp4 is only ~5 MB, which is less than the memory limit — and in this case I actually can substitute in the normal readfile() and produce the exact same behavior.)

The headers I get when I access test-video.mp4 directly are:

Accept-Ranges:bytes
Connection:Keep-Alive
Content-Length:5558749
Content-Type:video/mp4
Date:Sun, 27 Jun 2010 21:02:09 GMT
Etag:"1c04757-54d1dd-489944c5a6400"
Keep-Alive:timeout=10, max=30
Last-Modified:Tue, 22 Jun 2010 01:25:36 GMT
Server:Apache/2.2.15 (CentOS) mod_ssl/2.2.15 0.9.8l DAV/2 mod_auth_passthrough/2.1 FrontPage/5.0.2.2635

The headers from the PHP script are:

Connection:Keep-Alive
Content-Disposition:inline; filename="test-video.mp4"
Content-Length:5558749
Content-Type:video/mp4
Date:Sun, 27 Jun 2010 21:03:32 GMT
Keep-Alive:timeout=10, max=15
Server:Apache/2.2.15 (CentOS) mod_ssl/2.2.15 0.9.8l DAV/2 mod_auth_passthrough/2.1 FrontPage/5.0.2.2635
X-Powered-By:PHP/5.2.13

I've tried many different permutations of headers, even matching them exactly to those from a direct request, to no avail.

Has anyone had success serving HTML5 video through PHP, on iOS?

[Note: I would try using X-Sendfile, but the site is on a shared host with very limited access.]

EDIT: I was reading that iOS can be sensitive about file extensions, so I tried setting up a RewriteRule that rewrites MP4 requests back to my original PHP script, but that didn't help either.

A: 

If you are handling it yourself like that, then you will need to handle byte-range requests yourself as well.

sroussey
Exactly right — I ended up just copying the `rangeDownload()` function from Appendix A of the following article: http://mobiforge.com/developing/story/content-delivery-mobile-devices(What's cool about this function is it also allows the user start playback from any point in the video, just by clicking the timeline.)I think I was especially confused by the problem here because it worked perfectly on the desktop, whereas iOS has this byte-range requirement.
JKS