I’ve been playing around with a basic implementation of HLS the last few days, and despite it being a proprietary streaming transport there is a public specification available for it which seems reasonably complete. That being said, it is still proprietary, hasn’t made it through the standardization process and the public spec is suspected of being at least partially incomplete. THAT being said, I still managed to get both iTunes and an iPad working with it just based on my reading of the specification, so it has enough to get by.
However, as I worked through the small number of bugs I had in my implementation, firstly only iTunes would play back content but not the iPad. Later when I had fixed the bugs, the situation was reversed and only the iPad could play back but not iTunes. One would think that a desktop app would be more lenient with faulty implementations on the server side than a portable device which may not always be kept up to date, but apparently not!
It turns out that iTunes (at least 11.0.2 build 26) doesn’t actually implement Apple’s own specification properly, in that it can’t handle media segment URIs relative to the URI of the m3u8 playlist. This has been in the specification since at least draft 3 of the public specification, released April 2, 2010. Here’s what the playlist should (or could) look like:
#EXTM3U #EXT-X-VERSION:4 #EXT-X-TARGETDURATION:2 #EXT-X-MEDIA-SEQUENCE:1 #EXTINF:0.992653, #EXT-X-BYTERANGE:15883@0 test.mp3 #EXTINF:0.992653, #EXT-X-BYTERANGE:15883@15882 test.mp3 #EXTINF:0.992653, #EXT-X-BYTERANGE:15884@31764 test.mp3
With no further specification, the HLS client should request the media file at the same path level (and from the same server) as the playlist file. Unfortunately iTunes seems to require the full URI to the media segments:
#EXTINF:0.992653, #EXT-X-BYTERANGE:15884@31764 http://hls.paperairoplane.net/test.mp3
It’s not the end of the world, but it is unnecessary, and a requirement that died almost three years ago when the second draft specification expired. The other side-effect of this is that your playlists will now contain more data. If you are attempting to stream very long tracks and with reasonably short media segments, this means you have a much longer startup time due to the size of the playlist being bigger and thus being a larger download for the player before it can start requesting media segments.
The main mechanism by which we could offset this is also seemingly not present in iTunes – gzip content encoding. ITunes makes no attempt to negotiate any compression in the response, which was part of the specification since draft 4, released June 5, 2010. It mystifies me that Apple can stay so far behind in its own streaming transport with its flagship music playback software and yet clearly keep its devices implementing the same streaming mechanism up to date (at least enough to be useful).