Into the Woods now uses the HTML5 video element. For the moment, support is limited to iOS and Safari 5 on Snow Leopard (the only Mac/Safari configuration that includes a fullscreen button). Conveniently, Jeroen Wijering released a JW Player skin that closely resembles the QuickTime X player, so the switch should be fairly transparent.
The bad news is that it took me well over a month to work out all of the kinks — and as much as I loathe to admit it, I don’t think the video element is ready for prime time.
Hiding the player while the video buffers is one of the trickier problems. This behavior is important because there’s at least a few seconds lag on the iPad before any loading indicator appears, making the site feel unresponsive. While the iPad supports hiding the video element, the iPhone doesn’t. And while the iPhone supports lowering the opacity to zero, the iPad doesn’t. So in the end, I moved the player outside the bounds of a box with its overflow hidden. To my dismay, this technique unloads the Flash object in Firefox for Windows, so I relented and opted to only hide the player on iOS, at the expense of a totally consistent loading experience across platforms & devices. Both the video element and the Flash player support transparent backgrounds on the desktop (not on iOS, though!) — so, close enough.
Turns out the iPad’s video implementation is the least flexible. Bizarrely, if you add a video element to the DOM using jQuery’s $.replace() or $.append() methods, it always appears on top of other elements, regardless of z-index or overflow properties (which broke my hiding method). For whatever reason, only when I used the $.html() method would layering remain intact.
On all iOS devices, although content can be overlaid on top of video elements, interaction always defers to the video element below. So if you try tapping a link, the link will be ignored, and the tap will be received only by the player. This behavior forced me to add iOS-specific code to unload a video when the “Copy/Embed” interface is opened. (An aside to the “Copy/Embed” interface: iOS doesn’t support copying text from “readonly” input fields, nor does it support JavaScript text selection.)
Another significant hurdle was implementing HTTP byte-range support for iOS. This feature allows the player to request a specific chunk of a video instead of the entire thing. While HTML5 video will play in Safari 5 without byte-range support, iOS requires it. Also strange, browsers make multiple requests to a video source file, presumably to gather metadata before downloading the entire file — but the 2nd request from Safari is from a different user agent (QuickTime/7.6.6 (qtver=7.6.6;cpu=IA32;os=Mac 10.6.4)), which can’t read the same $_COOKIEs, meaning you can’t use them to pass authentication tokens. And while I used to be able to do basic video analytics by tracking file downloads, byte-range downloads make so many disparate requests that progress is impossible to track. So I had to write a new analytics method for the front-end and the embedded player that works by sending data with hidden GIFs.
In the end, I’m very happy with the result, and I think watching episodes on iOS devices is more engaging simply because there aren’t other windows or tabs to distract. But I don’t wish this experience on any other developer. Browser implementations are just too quirky for the video element to be treated as a standard (right now). And I haven’t even mentioned the competition between video codecs (H.264, Ogg Theora, and now WebM). For practical reasons, it doesn’t make sense for Into the Woods to encode videos in multiple formats when H.264 is supported by the JW Player and iOS. So Firefox is out. Chrome is out, too, because Google refuses to add a fullscreen button (per the W3C’s specification).
I bet we’ll support a Flash player for at least another 2 years. In the meantime, I’m watching for new browsers that meet our minimum video requirements — Android may already.