Audio Player: Responsive and Touch-Friendly

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.

Audio Player: Responsive and Touch-Friendly

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; (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 with em units, 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 4KB large small.

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">&hellip;</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:

Audio Player: Responsive and Touch-Friendly

The parent element .audioplayer is position: relative; whereas the child elements .audioplayer-* are position: absolute;.

See the demo.

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.

P.S. do not confuse the plugin with the media centre or so. It was not built to have playlists or display album covers.

&