The Quest for an Accessible Flash MP3 Player

This was my second in a series of blog posts on creating an accessible HTML5 audio player. If you're more interested in outcome than process, see the article Putting it all together: Accessible HTML5 Audio Player with Yahoo! Media Fallback.

In my previous blog post, I described how I created an accessible custom HTML5 audio player. For users whose browsers don't support the new HTML5 <audio> element, I need an accessible fallback option.

I started by testing each of the 10 Easy To Implement Flash Based Mp3 Players with JAWS 11, and found that nine of the ten players do not have labels on their controls. With no labels, JAWS identifies the various controls as "Graphic 1", "Graphic 2", etc., or in some cases simply says "Flash movie start. Flash movie end."

Of the players tested, the only player that is at all usable to screen reader users is the Yahoo! Media Player. A second player, niftyPlayer, also has potential because it exposes much of its functionality through a Javascript API (as does Yahoo!). So my next step was to start playing with each of these two players to see what they could do.

niftyPlayer

See my niftyPlayer Test Page.

The niftyPlayer is lightweight and easy to implement. The default player itself is not accessible (unlabeled buttons again), but its Javascript API allowed me to create a custom player that approximates the interface I created in my custom HTML5 Media Player, which I think is reasonable for fallback content.

For the technically curious, I commented the code extensively on the test page so you can see what I've done. Essentially it's the same approach as the HTML5 media player: I create a list of links to MP3 files to serve as a playlist. That list is the ultimate fallback. If users don't have HTML5 <audio> support, nor Flash support, or if they have Javascript disabled, they still get a list of links and can download the tunes and play them (of course, I'm cool with that and trust that they'll still do the right thing and buy my CD). If they have Javascript enabled, an empty <div> element with id="niftyControls" will be populated with fully accessible HTML controls, which when clicked will control the behavior of the niftyPlayer object.

With the custom controls in place, I have no real use for the original niftyPlayer interface, and keeping it on the page clutters the interface with unlabeled buttons for screen reader users. So, I'm hiding the Flash <object> element using visibility:hidden (I can't use display:none because that also hides it from Javascript).

One lingering problem is that the <object> code recommended in the niftyPlayer documentation fails HTML5 validation. HTML5 actually supports both <object> and (for the first time ever in an HTML spec) <embed>. However, the classid and codebase attributes are obsolete, and probably a few other attributes as well. At this phase in my testing I wasn't especially inclined to spend much time trying to figure out how to convert old <object> code to valid, functional HTML5, although it looks like Bruce Lawson has gotten a jump start on this in his article HTML 5 Flash embedded and other validation errors.

There are a few other problems with niftyPlayer too. The API is limited. It doesn't provide access to the volume control and there's no way to seek forward or backward within a tune. And as far as I could find, nobody seems to be doing any further niftyDevelopment, and there's little or no support for the existing player, either from the original developer or the user community. As a result of all this, I abandoned my niftyPlayer testing, leaving my implementation in a somewhat incomplete and buggy state. But I had high hopes for the next player in line to be tested...

Yahoo! Media Player

My test pages:

I'm not one to gush over big name brands, but one big advantage of the Yahoo! Player over the niftPlayer is that it was developed by Yahoo! Like many Yahoo! creations these days, there were clear signs that accessibility, particularly for screen reader users, had been actively considered.

The Yahoo! Media Player is easy to implement by following the steps documented at mediaplayer.yahoo.com. The one-page API documentation is similarly easy to follow, although as a developer I'd prefer having more details - there's a lot left undocumented. However, there's also an active user community on Yahoo! Groups as well as some historic activity on the Yahoo! Media Player wiki, unearthing the undocumented potential of the player and sharing their hacks (for example, see Michael Ryvkin's article Hacking the Yahoo! Media Player).

The player is implemented by adding a single line of code. This loads Javascript from Yahoo! servers, which injects the Flash player into the web page, along with HTML links to control the player independently of Flash, and HTML headings positioned off-screen to facilitate navigation for screen reader users.

The player is highly customizable, and has a much more robust API than niftyPlayer does. One of its configuration parameters is displaystate, which can be set to:

  • 0 to load in a minimized state (default setting)
  • 1 to load in a maximized state
  • -1 to load in a hidden state. This hides all the invisible screen reader -accessible content in addition to the skin. It simply displays play buttons beside each MP3 link, and when one of these links is clicked the player (including its accompanying accessible HTML) becomes visible in its maximized state.
  • 3 to load in a "no UI" state. This is initially the same as -1, but the player never loads, even after clicking a song title link from the playlist. This essentially disables the default player interface, but still allows access to the player via the API, so you can create your own.

There are a couple of things I don't like about the default player: The code is inserted at the very bottom of the web page, just prior to the </body> tag, and that's where it's always positioned visibly. I'd rather it be embedded within the flow of the document, at the author's discretion. There's no parameter that allows this to happen, and if there's a way to adjust its position using CSS, I don't know how to do it. Worse yet, the default player fails miserably on color contrast:

screen shot of default Yahoo Media Player, which includes hideous pale yellow buttons on a white background

The Contrast Analyser agrees:

screen shot of the Contrast Analyzer results window after analyzing the Yahoo! Media Player buttons. Results at all levels show FAIL

So, I created my own player, again striving for a similar interface to the one I created for HTML5. Again, the details are in the commented source code. I'm pleased with the results. It works, and it's fully accessible to screen reader users.

I did find one seemingly rare bug, and it's not just my code - I can replicate it on any Yahoo! Media Player, including the one on the YMP home page. In Firefox 3.6.8 in Windows 7 on my computer, if I pause the media, then play again, it behaves like a Stop button, and restarts the media at 0 rather than resuming where it left off. This happens on my computer even if Firefox is running in safe mode, but does not happen in Firefox 3.6.8 running on Windows XP nor on Mac OS X. I've had a couple people running this same browser in Windows 7 on their computers, who don't experience the problem, so who knows. Maybe it's just my bad luck. Regardless, I'm not too concerned about this bug, because for my purposes the Yahoo! player is fallback content, and Firefox 3.6.8 users will be playing their audio in HTML5.

Next Step

Now that I have both a custom HTML5 audio player and a fallback custom Yahoo! Media Player, I'm ready to put them together into a functional unit. Stay tuned...

7 comments on “The Quest for an Accessible Flash MP3 Player

  1. Terrill,

    Our group working on YMP did indeed care a lot about accessibility, and we consulted with an in-house expert at Yahoo. I wish we had gotten more mileage out of this strength.

    About the insertion of the player into the flow or out of it, the play buttons are inserted inline, while the player is outside of the flow. You can stick to the inline play buttons by using the param to hide the main player. But I am confident that out of the flow is the right way to handle this, because it keeps the pause button onscreen. Just minimize it to prevent the player from interfering with layout and you get the benefit of both.

    About contrast, you can customize the colors using CSS. That was an explicit product requirement. I believe there is documentation on the wiki, and if not Greasemonkey will do the job. If you share your hacks with the email list and/or wiki, it will be good for everybody.

    Thanks for doing this writeup.

  2. BTW, the player architecture supports multiple media rendering engines, which it uses as fallbacks internally. It covers over the details of which rendering engine is being used. The HTML5 audio element would slip very cleaning into this architecture.

    You can get more info from the engineers who developed the player, who are reachable on the mailing list.

  3. Hy Terrill
    I read your blogpost and because i think you know a lot of things about audio flash palyers, I was wondering what do you think about podsnack.com?

  4. Hi @Alexei. I hadn't tried podsnack.com but since you asked I thought I'd check them out. Their player is not good from an accessibility standpoint. I just tried several of their example players, and tried creating a player myself from scratch, and every player is the same: They don't expose any content at all to screen readers. For example using the screen reader JAWS, all I hear is "Flash movie start. Flash movie end."

  5. Hi Terrill -

    I like your player a lot. The only thing I would like to see is nice on-screen focus for the song items also. Keyboard users would benefit from that.

    Thanks for your work.

    Ghita

    • Hi Gary, I like your implementation. I haven't had time to work on the player in the last couple of months, but I'm hoping to make time before the end of the year. I'll add Previous and Next tracks buttons to the features wish list.