Streaming Audio is the Worst

So, about a month ago, I was working on some new features for KWVA. They run a ShoutCast server to live stream all of their programming, and they’d been asking for us to embed that into their site for a while (Previously, we had been linking to the .pls file and calling it a day).

Digging around for an off-the-shelf WordPress plugin proved futile, as everything I found was either way overcomplicated and/or bloated, and virtually everything was flash-based. This being the distant future of the year two thousand and thirteen, clearly a flash-only solution wouldn’t do, and I didn’t want anything complicated anyhow, so I set out to write my own simple solution.

I admittedly don’t know terribly much about streaming audio, but after a couple hours’ work, some Googling, and judicious copy-pasting, I’d come up with a minimal plugin that I dubbed, appropriately, SimpleCast. The concept was fairly straightforward, insert an <audio> tag pointing at our ShoutCast stream, poke it with JavaScript to see if it can play mp3 or not, and replace it with a flash-based player if not.

A cursory survey around the office revealed that this worked perfectly on Firefox, Chrome, Safari, and even someone’s iThingy. Job done, aren’t we clever, let’s release it on GitHub too because we’re cool like that, right? Well, a month later and I’m getting some sporadic reports that it’s not working for some users, and I’ve gotten enough that I can’t write it off as “one or two people have borked browsers.” Further investigation shows it’s a bit fussy and some combinations of Browser/OS/whatever don’t work as expected (Firefox 23 on Linux works, Firefox 23 on Windows 7 doesn’t. Huh.)

Turns out there’s a bit of a, let’s say, quirk with HTML5’s media support implementation. See, the HTML5 spec helpfully provides a method to check media support, namely media.canPlayType(type). In my cursory reading on this, I’d foolishly assumed this would be a boolean. It’s not. Rather, this returns either an empty string (""), "maybe", or "probably". What?

Turns out my implementation worked to my boolean expectation because empty string is falsy in Javascript, so checking if(!media.canPlayType) worked as expected for no support. The probelm arose with "maybe", as my logic implicitly assumed that "maybe" meant “yes it works” and happily embedded the HTML5 implementation. I’d argue that this is kind of crap and it really should be a boolean (what the hell good does “maybe” do anyone, and how am I supposed to treat “probably”?), but I vaguely understand that there are issues with patents and platform-specific implementations and whatnot. So, armed with this newfound understanding, I decided to treat “maybe” as “no”, rolled Modernizr into the project for good measure, and rewrote the logic as so:

[javascript]
if(Modernizr.audio.mp3 == "probably") {
// Insert <audio> tag here
} else {
// Embed flash player instead
}
[/javascript]

Testing this new version went wonderfully at first, as it still worked in all the desktop browsers it had before, but now Chrome was a bit less fussy and used the Flash player instead. Great, commit, push, problem solved… wwll maybe I should test this on a mobile browser first. Out comes the Nexus 7, Chrome Mobile version 29.whatever, I pull up the page on my dev server and… nothing shows up where the player should be. With a growing sense of dread, I hooked up my tablet to enable remote debugging, and fire up the mobile console:

[javascript]
> Modernizr.audio.mp3
"maybe"
>
[/javascript]

Uuuuuuuuuuuuuugh. Great. So Chrome Mobile doesn’t support mp3 playback with the <audio> tag according to my model. What about flash? Well…

What version of Flash is supported on Chrome for Android?

Chrome for Android will not be supporting Flash. As you may have seen in November, 2011, Adobe announced it has stopped investing in Flash for mobile browsing. Google has long been committed to making the web platform more powerful through open web technologies like HTML5 and is working with Adobe and other partners to further advance the web standard.

Well now what? I mean, they’re totally right, Flash is dying and we can’t rely on it. At the same time, though, this leaves me in some weird limbo: I can’t play my mp3 stream with HTML5, nor can I use Flash, so what the hell am I supposed to use?

We seem to be in a horrible transitional state where Adobe’s given up on Flash, everyone agrees it’s on its way out, and yet the current state of web standards implementation hasn’t quite caught up yet. This is thanks in no small part to the joy of software patents and the popularity of proprietary encodings, as I note that ogg vorbis is supported quite well by modern browsers. Unfortunately, everyone still loves their MP3s, so here we are.

OSCON 2013 Wrapup

Chalkboard in the lobby of the Oregon Convention Center on the last day of OSCON 2013.

Chalkboard in the lobby of the Oregon Convention Center on the last day of OSCON 2013.

Got back in from OSCON 2013 last night, and I’m still worn out even after having a chance to sleep it off. This was my first visit to OSCON, and now I’m sorry I didn’t get to go earlier. It’s (in my case) three days of absolute insanity, having your brain crammed full of more information than you can possibly hope to retain, meeting tons of great people, and of course: lots of goodies, freebies, and parties.

Some highlights:

    • Adam Harvey gave a very nice rundown of new features in PHP 5.5
    • Leigh Heyman’s keynote about the White House’s recent forays into OSS was excellent, if only for a video clip of President Obama asking “what the heck is an API?” (Video here)
    • Alex Martelli managed to be very entertaining in Good Enough is Good Enough, nicely reinforcing my idea that half-assed work is fine, as long as it’s the right half.
    • Justin Hileman showed off some nice techniques for debugging PHP without resorting to vardump() and die() all the time. He also showed off PsySH, a REPL for PHP that he’s made and which looks very promising (go fork it).
    • r0ml (Robert Lefkowitz) gave an excellent talk on literacy, which I can’t possibly do justice.
    • r0ml followed up on Friday morning with a keynote about distinction and the creation thereof (video). He raises some interesting points (as usual), but I’m not sure I agree with his conclusions.
    • After that, Piers Cawley showed up to sing a bit. I was pretty close to being burnt out at this point, so I decided this was a good time to duck out for more coffee (sorry, Piers).
    • Everything wrapped up with Paul Fenwick’s keynote, Fear, Uncertainty, and Dopamine. Paul talked about the how and why of people contributing to open source, and how we can get more people involved in it. Again, I can’t do this one justice, so just watch the video yourself.

All in all, OSCON was a blast and is going to be my go-to annual event now that I’m in a position to do things like this (hooray for employers that invest in their employees).