Download the code.
Demo.
Download the WP Audio Player Standalone.
So the rabbi asked me to add the ability to play the audio on the taamim page (basically, a long list of short MP3's) directly on the page, rather than click the link to open a new page. No problem, right? We're living in an HTML5 world, so I should be able to do:
$('a[href$=mp3]').each(function(){
$('<audio>').attr({src: this.href, controls: 'controls'}).insertBefore(this);
});
And everything ought to work: browsers that can't handle <audio>
elements get nothing, modern browsers get a modern audio player. Nice progressive enhancement.
But of course, it's not that easy. Webkit (Chrome, Safari) supports MP3 playing, but Firefox does not (and won't), and Internet Explorer only does for IE9 and up, and I have to support Windows XP and IE8 (source; consistent with my experimentation). I don't like the <embed>
ed players, so I'll go with Flash. I like the player that Language Log uses, and viewing the source tells me that's WPAudioplayer, which has a standalone version that requires just two files, the 11-kb swf
file and a 12-kb javascript file.
To use it, include the javascript with a <script> element and initialize the player with AudioPlayer.setup('/path/to/player.swf', {width: 100});
where 100
is the desired width of the player in pixels (it's constant for every player on the page and it's a mandatory option). Then, each player is implemented by replacing an existing element, identified by id
: AudioPlayer.embed(id, {soundFile: '/path/to/soundfile.mp3'});
.
Of course, iOS won't run Flash, so I still need to use the <audio>
element there. So I need to detect if the audio
element works, and if not, insert the Flash substitute. Browsers that can't handle either get a blank spot.
Putting it together into a plugin:
(function($) {
var uid = 0;
var init = function (swf, width){
AudioPlayer.setup(swf, {width: width});
init = $.noop;
}
$.fn.inline_mp3 = function(swf){
return this.each(function(){
var id = 'audioplayer_'+(uid++);
var player = $('<audio>').attr({
src: this.href,
controls: 'controls',
id: id
}).insertBefore(this);
// audio.canPlayType test from http://diveintohtml5.com/everything.html#audio-mp3
if (!(player[0].canPlayType && player[0].canPlayType('audio/mpeg;').replace(/no/, ''))){
init (swf, player.width());
AudioPlayer.embed(id, {soundFile: this.href});
}
});
};
})(jQuery);
It uses a unique number to assign an id to each element, and lazy-initializes the Flash player. The player should be styled with a given width (since IE8 doesn't have a default <audio>
size):>
audio {
width: 80px;
display: inline-block;
}
And use it:
$('a[href$=mp3]').inline_mp3('/path/to/player.swf');
And there are lots of other packages of html5/Flash fallback audio players but this is small and easy enough for me to understand.