I’ve recently been using mediastreamer to stream my music to work. The actual audio playback portion of mediastreamer relies on either flash or the HTML5
Anyway, about half my collection is in FLAC. Even if the endpoint did support FLAC playback, it would be too large to be practical for all-day-streaming. Since I didn’t want to go to the bother of reencoding my entire collection just so I could stream it over the internet, I sat down this weekend and started hacking transcoding support into mediastreamer.
The tag reading library used by mediastreamer already supported FLAC, so adding FLAC files to the database was as simple as updating the glob that searched for files. My approach to transcoding was to use commandline tools to decode and reencode the file in question, and then pipe that into the webserver for streaming. It turns out that everyone’s implementation is broken in some way unless I specify a Content-length header. As far as Flash is concerned, files hosted without a Content-length never end, meaning the playlist never advances. Chrome’s native
There’s two ways I can think of to know the file-size, so that I can set the Content-length header in HTTP:
Method 2 is currently in development. Deterministic output means that VBR is right out, so I’m stuck with encoding to CBR mp3. I’m estimating the Content-length by multiplying the length of the song in milliseconds by (bitrate / 1000). This is close enough, but somehow results in a length several kbytes longer than the output from lame. Interestingly, this doesn’t seem to affect Flash; the Content-length doesn’t need to beright, it just needs to be close. How frustrating. Still, it would be nice to know how to accurately predict the output of lame. It’s unsettling to be setting incorrect Content-lengths.
I’m going to look into submitting bug reports to webkit for their poor <audio> support. Or maybe not. It’s possible that Sinatra is just incorrectly responding to Range requests, which webkit seems to like - but range is probably a dangerous proposition for a file that’s being dynamically generated, so I’m not entirely sure whose fault it is. No other browsers use Range when they make requests for their <audio> tags, as far as I can tell. Unfortunately, I’ll probably have to build a webserver that hosts both vorbis and mp3, without Content-length headers, to test this across a wide range of browsers.