Artificial Intelligence

iPhone video streaming from Drupal's file system

It's well known the iPhone can play H.264 video. With tools like ffmpeg, hooking this up to Drupal ought to be simple, right? Here are a few snags I hit, and how to resolve them.


Filed under:

It's well known the iPhone can play H.264 video. With tools like ffmpeg, hooking this up to Drupal ought to be simple, right? Here are a few snags I hit, and how to resolve them.

The server is not correctly configured.

This error means your server doesn't support byte range requests. Range requests allow a client to request just part of a file, with a header that looks something like this:

GET /system/files/sample.mp4 HTTP/1.1
Host: example.com
Range: bytes=1000-1999

The server should respond with "HTTP/1.1 206 Partial Content" followed by the requested chunk.

Now, I should confess that tossing an MP4 file in Drupal's filesystem perhaps isn't really "streaming". However with byte range requests a client can fake it pretty effectively.

So how can this marvelous feature be enabled on your server? It turns out this is the wrong question. The byterange filter is built-in to Apache's HTTP handling; I'm not even sure it can be easily turned off. However, when using private files the data is transferred by Drupal's file_download() function, which doesn't support range requests, and mod_php sends the entire document if it's greater than 8000 bytes.

The solution is to use X-Sendfile. While primarily designed as a performance enhancement, it has the nice side-effect of offloading the transfer to Apache, so range requests work again. (This relatively new Drupal module currently requires a core patch, but there's a patch to remove the patch.)

Cannot Play Movie - Movie could not be played.

Initially, this was caused by the lack of a voodoo UUID atom required by the iPhone. To fix this, use 'ffmpeg -f ipod' instead of 'ffmpeg -f mp4'.

Cannot Play Movie - Movie could not be played.

Wait – I just fixed that! This error will also occur if the wrong H.264 profile is used. libx264 defaults to the High Profile (HiP), while the iPhone demands the "Low-Complexity Baseline Profile". Use 'ffmpeg -vpre ipod640' or '-vpre ipod320' to resolve this error.

That should satisfy the iPhone's picky MediaPlayer.framework. You can link to the .mp4 file directly, or use <object> or <video> tags.

For desktop browsers, there are Flash widgets like Flowplayer (and now Flashy!). Personally, I wish the web would go back to direct embedding. It seems the Flash players are primarily necessitated by politics (witness the current format war within the W3C over the <video> tag), and DRM.

Similar posts

Get notified on new marketing insights

Be the first to know about new B2B SaaS Marketing insights to build or refine your marketing function with the tools and knowledge of today’s industry.