A couple of months ago I built a jQuery plugin that replaces <audio> element with a little of custom HTML code. By adding some CSS you get a whole new player which looks the way you want and has the same functionality as the default player. There is no direct way to style the element. But the HTML5 DOM has methods, properties, and events for the element and thus makes it quite easily manipulable.
To sum it up, the plugin enables indirect styling of <audio> element. That's why I built it. I wanted the player to fit the design theme for one of my present projects – IP telephony for business (VOIP). The audio element serves for IVR (Interactive Voice Response) function where clients can built their own voice responders / menus, make audio records and rehear them.
A couple of weeks ago I wrote an in-depth article about the plugin for Codrops, which I recommend for people who think of themselves as less experienced in the field. Receiving some helpful feedback there, helped me to improve the player. Obviously, this is not the end and I will be looking for your feedback here as well.
Features
Before deciding to build a plugin on my own, I did a little research on existing alternatives. I had clear and strict requirements: (1) it must be lightweight, customizable and right; (2) it must solve contemporary problems like touch and responsive; (3) it must not solve problems I don't have yet. However, nothing passed through the filter. As the matter of fact, the player I built is:
- Responsive.
To achieve this, full responsibility falls on your CSS. My example is responsive. You can have a non-responsive player as well, but that is not recommended. Responsiveness is an important sign of a good web experience. - Touchable.
Touchableness is an important sign of a good web experience as well. Having these two, you are device and screen independent. And that is a half job done! - Adaptive.
When the browser does not support the audio element entirely or any of the provided audio files, the player then gracefully degrades to a one-button (Play/Pause buttons only)<embed />element based player which will use a third party plugin (mostly Quick Time on Mac, Windows Media Player on Windows) to play the audio file. Another possible scenario: JavaScript disabled in the browser. Browser's default player takes action then. And that is totally fine. - Native.
The player is in no way directly native. The plugin accepts audio element's attributes (src,autoplay,loop,preoload) and tags (<source>). Besides that, "autoplay" and "loop" attributes are inherited on the previously mentioned fallback case. - Usable.
The essential Play / Pause and playback progress controls, Volume On / Off / Up / Down controls and indication of how much of the audio is preloaded (buffered). - Image-less.
This depends on your CSS as well. The looks of my player is all CSS, not a single image file used. Having that and sizing everything withemunits, enables the player to be scaled and zoomed. - Flash-less.
So long, Flash. You are unwanted here.
- Lightness.
The minified version of the plugin is just 4KBlargesmall.
Usage
Add the audio element, set the attributes you need and add source(s). The more different sources you add, the more users will be able to listen to your audio (because none of the audio formats are supported across all browsers). Three examples:
<audio src="audio.wav" preload="auto" controls></audio>
This will just preload the audio.wav file and won't play it until user clicks Play button. Other preload values (none, metadata) will not preload the file.
autoplay the file when it loads and then loop it in this way:
<audio src="audio.wav" preload="auto" controls autoplay loop></audio>
Specify multiple audio formats to solve the previously mentioned problem:
<audio preload="auto" controls> <source src="audio.wav" /> <source src="audio.mp3" /> <source src="audio.ogg" /> </audio>
Mystic controls? It is a boolean attribute which does not influence the plugin in any way, but ensures that browser's default player is displayed and displayed with controls when JavaScript is disabled.
The final step – calling the plugin (by including jQuery and the plugin files in the document if that hasn't been done previously) on the audio element:
<audio src="audio.wav" preload="auto" controls></audio>
<script src="jquery.js"></script>
<script src="audioplayer.js"></script>
<script>
$( function()
{
$( 'audio' ).audioPlayer();
});
</script>
The plugin has some optional parameters. The most important one is called classPrefix. The passed value becomes a class name for the parent element and class name prefix for child elements. Other options may only be advantageous for languages other than English. Example with default values:
$( 'audio' ).audioPlayer(
{
classPrefix: 'audioplayer',
strPlay: 'Play',
strPause: 'Pause',
strVolume: 'Volume'
});
HTML
As I mentioned in the very first paragraph, when the plugin is called, the <audio> element is replaced then with some HTML:
<div class="audioplayer audioplayer-stopped"> <audio src="audio.wav" preload="auto" controls></audio> <div class="audioplayer-playpause" title="Play"><a href="#">Play</a></div> <div class="audioplayer-time audioplayer-time-current">00:00</div> <div class="audioplayer-bar"> <div class="audioplayer-bar-loaded"></div> <div class="audioplayer-bar-played"></div> </div> <div class="audioplayer-time audioplayer-time-duration">…</div> <div class="audioplayer-volume"> <div class="audioplayer-volume-button" title="Volume"><a href="#">Volume</a></div> <div class="audioplayer-volume-adjust"><div><div></div></div></div> </div> </div>
There are some class names, which are assigned to the parent element when:
- audioplayer-playing – audio is being played:
<div class="audioplayer audioplayer-playing"> - audioplayer-stopped – audio is being stopped:
<div class="audioplayer audioplayer-stopped"> - audioplayer-muted – volume is muted:
<div class="audioplayer audioplayer-muted"> - audioplayer-novolume – no volume adjustment is available:
<div class="audioplayer audioplayer-novolume">
Important: when the audio element is not supported or none of the given audio files are compatible with the browser, the player switches to Mini mode, which basically reduces the player to Play/Pause button (because "embed" element is limited in terms of manipulation):
<div class="audioplayer audioplayer-stopped audioplayer-mini"> <embed src="audio.wav" width="0" height="0" volume="100" autostart="false" loop="false" /> <div class="audioplayer-playpause" title="Play"><a href="#">Play</a></div> </div>
Reminder: using classPrefix options on the initiation of the plugin you can replace every audioplayer occurrence with your own value in the HTML and so to have different looks of multiple players on the same website.
Now, everything depends on how you will style the player using CSS. I will skip this part here and go directly to demo, but you can read my article on Codrops about the styling anytime.
Demo
As mentioned hundreds of times before, my player is responsive and isn't even dependent on Media Queries. I have a made a scheme which explains the layout:

The parent element .audioplayer is position: relative; whereas the child elements .audioplayer-* are position: absolute;.
Grab the plugin: audioplayer.js (uncompressed; 8KB) or audioplayer.min.js (minified; 4KB).
Feedback
I tested the player and it works fine on the latest Safari, Chrome, Firefox, Opera both Mac and Windows versions. The player works well on Internet Explorer 9, 10 and gracefully degrades to mini mode on earlier versions. I have also been lucky with iOS 6, Windows Phone 7 and Android 4.2 default browsers. However, the earlier Android versions does not support "audio" nor "embed" elements, so the player won't work there at all.
What was your experience, got any thoughts, insights or built your own look? Feel free to send me a tweet or leave a comment below. Thanks!
P.S. do not confuse the plugin with the media centre or so. It was not built to have playlists or display album covers.


70 comments. Write?
what’s wrong with pause button? left part is smaller than right http://img402.imageshack.us/img402/7758/pausew.jpg
why is that so so important? just change it.
Like it. Will there be a version that can easily be intergrated into Wordpress in the future?
you can do this with custom fields (http://www.advancedcustomfields.com/).
Great job, and great article, thanks for sharing!
I like the approach, its simplicity and effectiveness. The audio element is a huge challenge and it seems you did a great job here. I will test your plugin on my next project. Many thanks for sharing.
I really enjoy this plugin—great work! I’m experiencing an issue in Firefox 18 (worked fine in IE9 and Chrome 24.0.1312.52 m). When the autoplay attribute is present, two tracks of the audio start playing over each other slightly out of sync. Clicking Stop will stop one of the tracks while the other continues.
Same thing happened to me… seems to happen sporadically though. Very strange. Have you found any solution?
Really like the player though am getting a Uncaught Error: IndexSizeError: DOM Exception 1
eight times from line 103 in the console.. just thought I’d let you know!!
Thanks for your work!!
Hi Sven. Thanks for letting me know this. What browser/OS did you use for testing the player?
Hi Osvaldas,
I am getting the same error as Sven is getting: Uncaught Error: IndexSizeError: DOM Exception 1 .
I am using Chrome 26 under Mac 10.7.5
Great work by the way!
Oops, I have posted too early, I didn’t see the fix by Felipe.
Hi Osvaldas. You are most welcome. Currently, am using OSX 10.7.5 Firefox 18.01 and Chrome 26.01386.
Did you get that error on all of these browsers?
Yes i did, also just check in Safari Version 6.0.1 and getting the same error
Osvaldas,
I have the same issue, fixed with this code: http://pastebin.com/B3iutXRR
Replace updateLoadBar function and add after timeCurrent.text the new listener.
Tested using Windows IE9+, Chrome, FF, Opera. but since all browser that support html5 audio has loadedmetadata event it should work fine.
Can you put this in Github so people can contribute to this?
by the way, awesome work :)
Thank you, this fixed the errors for me.
Has anyone used this for multiple instances of the player on the same page? When I start one player and then click “play” on another player, they both play - the first does not stop. I’m looking for a kill function.
The Javascript now pause the other playing audio. Also change a bit of code to allow play and pause directly using the tag and this reflects on the player.
Fixed the “mini” style that is showing up the native controls and the play/pause from the player.
[removed] http://pastebin.com/49WJEDvt, CSS: http://pastebin.com/yta8GCg6
js link: http://pastebin.com/49WJEDvt
Beautiful, works perfectly for me and includes the fix for console errors. Great job Felipe, and thank you for sharing!
Hey Felipe,
Thnx for sharing your fixes.. You are THE MAN !
Thnx to your update, i got it working :) ..
I am a beginner in hltm5, ccs and jquery and i need people like you.. This is my first website:
www.nr-tainment.com
http://www.nr-tainment.com/media.html - the one with the player
What do you think?
I need to have this script work with IE 7 and IE8 if possible. Your demo does work when I test it but on my site it throws an error in IE8 and won’t work. I am at a loss. http://www.ctaudioproductions.com/chris-thomas-services/character-voices.php. I grabbed your exact page and loaded it just to see to do some tests and I get the same error. I just don’t know enough to figure this one out. Any help is appreciated… thanks.
Has anyone figured out how to get IE8 support (IE7 can go away IMO)? I’m getting an error saying “AddEventListener” in the js file is unsupported - not sure if there is a workaround?
It will not work on old IEs, because old ies doesn’t have support to html5 audio api, you need to add a flash fallback or something…
of course there’s a way to attach events to old ies, but if you fix this issue, you still be unable to play since the browser doesn’t have support.
if you really need to support IE, I recommend you to use other player with builtin flash fallback and style it…
Thanks… I’m confused because it sounded like this had a fallback for IE8. Our site’s IE8 users only represent 2.5% of our users, maybe it isn’t a big deal. Yeah, I can live with that.
Brian, it does have a callback as stated in the post:
It’s not bulletproof, but in IE6-7-8 it turns to the mini mode which should play the audio.
Pete, try downloading the demo (http://cl.ly/NDVZ). Obviously, for some reason you did not set it up correctly.
So you are using Quicktime and Windows Media Player as fallback just because you don’t want to use Flash? Plus I have to encode an audio 3 times?
Yep, this is why HTML5 sucks. You could have just made an audio player in Flash and fallback on HTML5 for mobile with only 1 audio file and be done with it. Works everywhere.
But I guess some people like to piss against the wind.
Very nice player, But I have a question. If someone would like to use this player for shoutcast streaming internet radio, what would he has to change in the codes to make it work?
Great idea, thanks! I’ve tested it. The player does play shoutcast streams. However, a tiny workaround is needed. For now the plugin does not accept shoutcast URL’s as valid ones. So, if you are going to use the player specifically for shoutcast streams, find the 77th line in audioplayer.js file fill it up with this code:
isSupport = true;. The last thing: always attach a semicolon at the end of stream’s URL, for example:src=“http://shoutcast-stream.com:12345/;”.I’m going to tune the plugin as soon as I get a chance to so that it could play streams without extra workarounds.
I’ve made a temporary demo – check it!
@Osvladas, I did the change you sugested ” isSupport = true;” it works fine in chrome 25.0.1364.152 but when it comes to Firefox, IE 10 and Safari 5.1.7, no sound, even with mp3 it still doesn’t work. All I can come up with is that the player is not supported in them.
Greetings,
This is a great player. Awesome work! I am trying to figure out a way to incorporate it into Drupal. I am not really a good enough programmer to create a dedicated module, however I wonder if with some tweaks, it is possible. I guess I most curious if anybody reading these comments is a Drupal user and what it would take to get this to work. Of course, it will work fine with manual playlist and linking to audio files. But would be cool to somehow connect with the media module. Just curious. Cheers, Kevin
Hi Kevin. Thanks. I don’t have a single connection with Drupal – I won’t be able to help you. But if you ever get this on Drupal – take a minute to share your experience here.
Hi Osvaldas,
I have tossed the idea out there within the Drupal developer community to see if anybody is interested in porting your player to a Drupal module. I would do it in a second if I could code well enough. At any rate, I will definitely let you know if my initiative gains any traction. Cheers, Kevin
Osvaldas, I am trying to find something that is nice like this for wordpress. Can you tell me if this can be integrated into a wordpress site?
Thank you!!
kathy
Hi Osvaldas and thank you for the player !
Just a problem, i have an android phone (htc desire with chrome) and the player appears in responsive mode (little), starts but no sound. That the same issue in your demo page… Any ideas ?
Martin
I don’t read that…. “However, the earlier Android versions does not support “audio” nor “embed” elements, so the player won’t work there at all.”
Sorry for the inconvenience…
“77th line in audioplayer.js file fill it up with this code: isSupport = true;”
it works, we can add the stream of our radiostation to your player.
Thanks
To pause other players when another has been CLICKED to play
$.each($(’.audioplayer-playpause’), function() {
/* If this parent has class ‘audioplayer-playing’ then trigger click to pause */
if( $(this).parent().hasClass(‘audioplayer-playing’) ) {
$(this).trigger(‘click’);
}
});
Before this line
$( this ).attr( ‘title’, params.strPause ).find( ‘a’ ).html( params.strPause );
Line 197 in original
This is probably better.
$.each($(’.audioplayer-playing’), function() {
$(this).find(’.audioplayer-playpause’).trigger(‘click’);
});
I am having trouble getting this working, this feature should really be standard when multiple players are on a page.
Could you send me a link to your version working?
Unfortunately I couldn’t get multiple instances of the player working (see my previous comment) and finally gave up and used another player. Hopefully someone else is able to provide info about how to combine multiple instances of this great player.
That is a shame, I will have to find another player also. This should be a standard feature. :(
it works for me. just replace:
$( this ).attr( ‘title’, params.strPause ).find( ‘a’ ).html( params.strPause );
thePlayer.addClass( cssClass.playing ).removeClass( cssClass.stopped );
isSupport ? theAudio.play() : theAudio.Play();
with
.each($(’.audioplayer-playing’), function() {
$(this).find(’.audioplayer-playpause’).trigger(‘click’);
});
$( this ).attr( ‘title’, params.strPause ).find( ‘a’ ).html( params.strPause );
thePlayer.addClass( cssClass.playing ).removeClass( cssClass.stopped );
isSupport ? theAudio.play() : theAudio.Play();
I put exactly that code in the audioplayer.js at line 197, like Curtis also indicated but is does not work for me (tested with FF21, IE9 & Chrome27). I even loose the “Osvaldas look”, it plays in the default browser player.
Any idea, anyone?
Thanks!
PS: Great player, ačiū!
Great player. Truly responsive, unlike others. Would you be prepared to make me a playlist version if I paid you? Regards. Richard.
Great player! Thank you very much.
I only have one small issue… On my Nokia Lumia 620 (Windows Phone 8), the browser is not displaying the duration correctly.
I initially used the downloaded js file, and I was shown “NaNaNa” where the duration is supposed to be displayed. I then used the .min.js and now it’s showing “...” where the duration is supposed to be.
Could you point me in the right direction in order to fix this?
Thanks
Thanks for the feedback, Kevin. I will check this as soon as I get a chance to. The problem is the lack of devices in my collection!
can i use soundcloud audio with this script?
please help. i believe someone is there to help me out.
thanks and regards,
Thanks for this, it seems great, and just what I’m looking for.
Do you have an open source licence for it? If you would release it under the MIT licence that would be perfect!
Hi Steve. It’s already open source! Feel free to use it under the MIT license.
Hi Osvaldas,
Thanks you for sharing this great way of playing audio.
I copied all files from your zip. One instance works fine, but as soon as I add another instance (different audio in a second wrapper like http://pastebin.com/VjZyDbJX), the player lookes like this http://tinypic.com/r/2lmpg9e/5:
It gets to the right an extra total time and speaker symbol, and the counter displays both 00:00 and the current position. It happens both in Firefox and Chrome.
I’m afraid it’s my lack of programming skills, but could you give a hint how to use multiple instances? Regards, Age
Great player, really nice! One thing though… I have it setup to playback mp3 files and the duration of the mp3’s don’t quite match the duration on the playbar. This may very well be because it has been encoded with variable bitrate. But I was just wondering is there is a way to set the duration manually?
Fixed it by converting variable bitrate encoded mp3’s to a constant bitrate!
Every now and then, I get the audio file playing twice over the top of each other. Refresh the page a couple of time and the problem seems to disappear. Any ideas how to get around this?
Yeah! That’s a really nice audio player! Great touch support, thank you!
Anyway I can turn this into a shoutcast/radio player?
Hi, Just wanted to let you know that even though you don’t state there is IE 8 support, I have just tested it on a very basic install of Windows XP with IE 8.0.6001.18702 and it works. Ok the full player doesn’t appear, but a play/pause button does, and it plays and pauses audio.
I tested it using your demo page. I do admit it would be nice to have a Flash fall back, much like other HTML5 audio players have, but otherwise it seems to work fine.
Amazing! I love how this player has its own visual appeal. Thanks for sharing!
support shoutcast?
I made a WordPress plugin to have a shortcode displaying the player:
https://gist.github.com/brasofilo/5630542
jQuery is adapted to work with WP’s bundled version. And the style and script only load if the shortcode is present on the post. Multiple players are working fine and if one player starts, the others stop.
using this great player in a cordova phone gap app, and noticed the play/pause button jumps a bit in a web view when switching between the two different states. changing text-indent to 99px for .audioplayer-playpause fixes this.
Great player but there should be a github repository!
Is there a JavaScript API to play/pause/change volume on behalf of the user?
Great Player, was searching for this for a longer time.
But please ensure future development on github so we can contribute and keep the project alive!
Realy very nice & good audio player, but the great pity is that the player can not play audio files from a playlist.
I mean, html elements list (ol, li) with anchors & links (a, href, src) to self hosted audio files (mp3).
I would like to ask you whether it would be possible to write this function.
I believe that this feature a lot of other users would be pleased.
Many thanks in advance
Yes a playlist function would be great!
Great Work - really stripped down to the basics, yet so good. I wonder if you took a look at medialemenjs - which can also be used as a audio player. Where did it lack the requirements?
very cool
Just two hints:
Can you please post a list of devices you know it works on?
What about publishing this code on a platform like github? :)