Random access to Web audio

Doug Kaye's ITConversations has the first installment of a new online talk show called The Gillmor Gang. My ongoing interest in the ability to form URLs that link into large media objects has now infected Doug, and we've been talking about how to enable that capability on his site.

And then it all came rushing back to me, like the hot kiss at the end of a wet fist. I recalled an exchange, some months ago, with Kevin Marks, a former Apple QuickTime engineer who is now Technorati's director of engineering. Our conversation was prompted by my mobile webcasting column. Kevin wrote to point out that streaming is really only useful for live events, and that downloadable files are otherwise superior. But what about random access, I asked? HTTP 1.1 supports that, Kevin pointed out.

I've known for a long time that certain applications -- notably Adobe Reader -- make use of the HTTP Range header to request partial content. I'd never seen the protocol in action, though. It took me a while to find a PDF on the Web that exhibits random-access behavior -- perhaps because it's not really necessary for the vast majority of sub-1MB PDFs out there -- but eventually I found this 4MB document and was able to watch Adobe Reader requesting a sequence of chunks in the background, and skipping ahead when I scrolled to the end of the document to view the last page.

What about downloadable MP3s? I tried QuickTime, no joy. Windows Media Player, no joy. RealOne Player: bingo! And likewise Winamp. How did I never notice this before? Here's some of the chatter between Winamp and Doug's server:

GET /mp3/2004/The%20Gillmor%20Gang%20-%20May%2014,%202004.mp3 HTTP/1.0
Connection: keep-alive
Host: rdscon.vo.llnwd.net
User-Agent: WinampMPEG/5.0
Accept: */*
Icy-MetaData: 1
 
HTTP/1.0 200 OK
Date: Sat, 15 May 2004 03:05:23 GMT
Server: Apache/1.3.29 (Unix)
Last-Modified: Sat, 15 May 2004 02:43:02 GMT
ETag: "216a53-1173385-40a583b6"
Accept-Ranges: bytes
Content-Length: 18297733
Content-Type: audio/mpeg
Connection: close
 
GET /mp3/2004/The%20Gillmor%20Gang%20-%20May%2014,%202004.mp3 HTTP/1.1
Connection: keep-alive
Host: rdscon.vo.llnwd.net
User-Agent: WinampMPEG/5.0
Accept: */*
Range: bytes=9902232-
 
HTTP/1.0 206 Partial Content
Date: Sat, 15 May 2004 03:05:23 GMT
Server: Apache/1.3.29 (Unix)
Last-Modified: Sat, 15 May 2004 02:43:02 GMT
Accept-Ranges: bytes
Content-Type: audio/mpeg
Content-Range: bytes 9902232-18297732/18297733
Content-Length: 8395501
Connection: close
 
GET /mp3/2004/The%20Gillmor%20Gang%20-%20May%2014,%202004.mp3 HTTP/1.1
Connection: keep-alive
Host: rdscon.vo.llnwd.net
User-Agent: WinampMPEG/5.0
Accept: */*
Range: bytes=15105006-
 
HTTP/1.0 206 Partial Content
Date: Sat, 15 May 2004 03:05:23 GMT
Server: Apache/1.3.29 (Unix)
Last-Modified: Sat, 15 May 2004 02:43:02 GMT
Accept-Ranges: bytes
Content-Type: audio/mpeg
Content-Range: bytes 15105006-18297732/18297733
Content-Length: 3192727
Age: 214
Connection: close
In this sequence, the server reports a Content-Length of about 18MB. I scroll halfway, and request the range starting there. Then I scroll farther and request another range.

There remains the problem of link addressability. Doug would have to invent, and hack into his server, some kind of URL parameterization -- which, in fact, he's considering doing. Of course somebody must already have thought of that, and sure enough, Ari Luotonen did in his original 1995 proposal for byte ranges:

EXAMPLES OF THE BYTERANGE URL PARAMETER
 
The first 500 bytes:
   host/dir/foo;byterange=1-500
 
The second 500 bytes:
   host/dir/foo;byterange=501-1000
 
Bytes from 501 until the end of file:
   host/dir/foo;byterange=501-

According to this comparison of HTTP 1.0 and 1.1, the URL parameter idea ran afoul of HTTP 1.1's conditional GET feature, and so byte ranges migrated into the realm of HTTP headers.

To sum up, an ordinary downloadable MP3 sitting on a conventional Web server (as opposed to a streaming MP3 hosted on an Icecast or Shoutcast server) is perfectly able to be randomly accessed -- but only by means of HTTP Range headers, not by means of parameterized URLs. And some (but evidently not all) MP3 players are prepared to exploit that random-access feature.

What's missing?

I can see at least one major objection. The byte range syntax isn't human-friendly. The hours/minutes/seconds format that streaming servers support would be nicer. Knowing nothing about MP3 formats, I can't say whether it would be feasible for a sufficiently smart server extension to translate from hours/minutes/seconds to byte ranges.


Former URL: http://weblog.infoworld.com/udell/2004/05/18.html#a1002