Playing audio files with jQuery on user interactions like button clicks is a common need for many modern web applications. With the right techniques, we can build robust and compelling audio experiences.
In this comprehensive 2600+ words guide, we will deep dive into:
- Cross-browser support and compatibility
- Building accessible and intuitive audio controllers
- Optimizing performance and loading
- Comparing JavaScript audio libraries
- Supporting various audio formats
- Visualizing audio with JavaScript APIs
- Managing state across page reloads
- Providing fallback options for legacy browsers
So let‘s explore these topics in detail:
Browser Support and Compatibility
The HTML5 <audio> element has excellent browser support across modern browsers like Chrome, Firefox, Safari and Edge.
However, there are some key differences in how audio is handled across browsers that we need to consider:
Prefixed Audio Formats
Safari and IE 10 support different versions of the AAC audio codec:
Safari: aac
IE10: x-ms-wma
So we need to specify both in <source> for maximum compatibility:
<audio controls>
<source src="audio.aac" type="audio/aac">
<source src="audio.aac" type="audio/x-ms-wma">
</audio>
Auto Playback Restrictions
Many browsers now block or restrict autoplaying audio with Javascript for better user experience:
Chrome, Firefox, Edge:
- Disable autoplay with sound
- Allow autoplay if sound is muted
Safari:
- Allow autoplay if user has previously interacted with page
IE 11:
- Autoplay with sound is allowed
So for consistent behavior, we need to:
- Use click or tap event to trigger playback
- Handle muted state and unmute
- Detect Safari page interaction before enabling auto play
Asynchronous Playback
Because the Audio API is asynchronous, playing consecutive audio files can exhibit glitchy behavior in some browsers when the prev file is still buffering.
We can normalize this by listening to ended event before loading next audio:
audioElement.addEventListener(‘ended‘, () => {
// Play next sound
});
By considering these browser nuances, we can build audio players that provide smooth and unified playback.
Building Intuitive Audio Controls
The native browser <audio> tag comes with default controls for playback. But often we need custom controls that match our UI needs.
Here are some examples of intuitive audio controllers we can build with jQuery.
Play/Pause Button
A common interface is having a single play/pause toggle button:
$("#playPauseButton").on("click", function() {
if(audio.paused) {
audio.play();
} else {
audio.pause();
}
});
So based on current paused state, we either play or pause audio.
We toggle an icon to indicate state:
.play #playPauseButton::before {
content: url(/assets/pause-icon.svg);
}
.paused #playPauseButton::before {
content: url(/assets/play-icon.svg);
}
Playback Slider
Let‘s add a playback slider:
<input
type="range"
min="0"
max="100"
value="0"
id="playbackSlider"
/>
On slide change, we calculate the audio currentTime:
$("#playbackSlider").on("input", () => {
const percent = playbackSlider.value / 100;
audio.currentTime = audio.duration * percent;
});
We also need to update slider position during playback:
audio.addEventListener("timeupdate", () => {
const percent = audio.currentTime / audio.duration;
playbackSlider.value = percent * 100;
});
This allows intuitive audio seeking with a simple slider input.
Multiple Toggle Buttons
For more control, we can add play/pause along with stop and loop buttons:
<button id="playButton">Play</button>
<button id="pauseButton">Pause</button>
<button id="stopButton">Stop</button>
<button id="loopButton">Loop</button>
And in jQuery:
$("#playButton").on("click", () => {
audio.play();
});
$("#pauseButton").on("click", () => {
audio.pause();
});
$("#stopButton").on("click", () => {
audio.pause();
audio.currentTime = 0;
});
$("#loopButton").on("click", () => {
audio.loop = !audio.loop;
});
This provides more customizable controls.
Volume Slider
We can also add dynamic volume control:
<input
type="range"
min="0"
max="100"
value="100"
id="volumeSlider">
$("#volumeSlider").on("input", () => {
const value = volumeSlider.value / 100;
audio.volume = value;
});
This syncs browser volume to our player.
There are many possibilities for innovative audio controls. The benefit of using jQuery is rapid prototyping and shorter code.
Optimizing Performance
Delivering audio reliably across varying networks and hardware requires some performance optimizations.
Preloading Audio
We can preload audio files on page load so that playback starts instantly:
$("document").ready(() => {
$("#audio1").attr("src", "song1.mp3");
$("#audio2").attr("src", "song2.mp3");
});
This avoids delays caused by fetching audio over networks.
Compressed Formats
MP3 and AAC work best offering smaller sizes without compromising quality. They are well supported across modern browsers.
For example, an uncompressed WAV file of 5 min length is usually 40-50 MB.
The same file compressed to MP3 format at 192 kbps results only in 5-6 MB.
Streaming vs Full Download
Streaming audio allows playing files before full download sacrificing some latency:
<audio controls preload="none">
<source
src="http://domain.com/stream.mp3"
type="audio/mpeg">
</audio>
For short clips, full download may be preferable:
<audio controls preload="auto">
<source
src="audio.mp3"
type="audio/mpeg">
</audio>
External Libraries
Advanced audio libraries like Howler.js and SoundJS optimize performance by:
- Handling resource loading
- Caching decoded audio for better response
- Managing playback state
- Abstracting environment differences
So it may be beneficial integrating such libraries along with jQuery.
Comparing JavaScript Audio Libraries
While native HTML5 <audio> element provides basic support, third-party JavaScript audio libraries unlock more advanced features.
Let‘s compare some popular options:
| Library | Key Features |
|---|---|
| Howler.js | WebAudio and fallback support, sprite sheets, spatial audio, filters |
| SoundJS | Preloading, sprite sheets, mobile locking |
| Tone.js | Instruments, effects, complex compositions |
| Audio.js | Consistent cross-browser behavior |
| wavesurfer.js | Waveform visualization and analysis |
The benefit of using these libraries with jQuery is that we can handle UI, events and DOM manipulations using jQuery while leveraging advanced audio capabilities provided behind the scenes.
Some simplified examples:
Howler.js
var sound = new Howl({
src: [‘audio.mp3‘]
});
$("#play").on("click", () => {
sound.play();
});
SoundJS
var sound = createjs.Sound.createInstance("audio");
$("#pause").on("click", () => {
sound.pause();
});
So choose a library that fulfills the audio requirements of your application.
Supporting Diverse Audio Formats
There are 3 major audio formats used on the web today:
| Format | Quality | Browser Support |
|---|---|---|
| MP3 | Good | Widely Supported |
| AAC / M4A | Better | Safari, IE 10 |
| OGG | Comparable | Firefox, Chrome, Opera |
To maximize browser and device support, we need to specify audio in different formats:
<audio controls>
<source src="audio.ogg" type="audio/ogg">
<source src="audio.mp3" type="audio/mpeg">
<source src="audio.m4a" type="audio/x-m4a">
</audio>
The browser will automatically load the optimal format supported.
We can also detect support programmatically:
let mp3, ogg;
// Check MP3 support
const mp3 = new Audio();
mp3.canPlayType("audio/mpeg");
// Check Ogg Vorbis support
const ogg = new Audio();
ogg.canPlayType(‘audio/ogg; codecs="vorbis"‘);
if (mp3) loadMp3Format();
else if (ogg) loadOggFormat();
So supporting all relevant audio formats ensures maximum compatibility for our audio player.
Visualizing Audio with the Web Audio API
The Web Audio API available in most modern browsers allows processing and visualizing audio in JavaScript.
For example, we can build an audio waveform viewer using AnalyserNode:
// Get AudioContext
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// Pass audio to analyser
const analyser = audioCtx.createAnalyser();
const source = audioCtx.createMediaElementSource(audioElement);
source.connect(analyser);
// Get frequency data
analyser.fftSize = 256;
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
analyser.getByteTimeDomainData(dataArray);
We can then map this frequency data into a visual waveform:
// Draw waveform
function draw() {
requestAnimationFrame(draw);
analyser.getByteTimeDomainData(dataArray);
canvasCtx.fillStyle = ‘rgb(200, 200, 200)‘;
canvasCtx.fillRect(0, 0, canvas.width, canvas.height);
canvasCtx.lineWidth = 2;
canvasCtx.strokeStyle = ‘rgb(0, 0, 0)‘;
canvasCtx.beginPath();
var sliceWidth = canvas.width * 1.0 / bufferLength;
var x = 0;
for(var i = 0; i < bufferLength; i++) {
var v = dataArray[i] / 128.0;
var y = v * canvas.height/2;
if(i === 0) {
canvasCtx.moveTo(x, y);
} else {
canvasCtx.lineTo(x, y);
}
x += sliceWidth;
}
canvasCtx.lineTo(canvas.width, canvas.height/2);
canvasCtx.stroke();
}
draw();
This visualize the sound waveform that updates in realtime during playback!
There are many other visualizations possible like frequency spectrum, EQ, etc.
So the Web Audio API unlocks powerful audio processing capabilities that can enhance our audio player UIs.
Saving Playback State
Often we need to remember playback state – play/pause, current time, volume etc when user leaves or reloads page.
HTML5 localStorage provides a persistent storage solution:
// Save state
function saveState() {
localStorage.setItem("audioPlayback", JSON.stringify({
isPlaying: !audioElement.paused,
currentTime: audio.currentTime,
volume: audio.volume
}));
}
// Get saved state
function getSavedState() {
const playback = JSON.parse(localStorage.getItem("audioPlayback"));
if(playback) {
audioElement.currentTime = playback.currentTime;
audioElement.volume = playback.volume;
if(playback.isPlaying) {
audioElement.play();
}
}
}
We serialize the playback object into JSON string before saving into localStorage.
On page reload, we parse and apply saved properties onto audio element.
By leveraging localStorage, we can build stateful audio experiences.
Providing Fallback Support
While jQuery audio players have excellent browser support, some fallback handling is necessary for legacy platforms.
Common fallback options:
Flash Audio
Adobe Flash allows consistent audio playback across desktop browsers. We can detect and provide Flash fallback:
// Try HTML5 Audio
var audio = new Audio();
// Detect Flash
if(!audio.canPlayType("audio/mpeg")) {
// Embed Flash audio player
swfobject.embedSWF("player.swf", "altContent", "300", "120", "10");
}
Note: Flash has been discontinued so has limited lifespan.
Link to Download Source
If audio is not supported at all, we can provide link to original audio file:
<audio controls>
<source src="audio.mp3>
</audio>
<a href="audio.mp3">Download Audio</a>
This allows user to manually play in external player.
Pointer Events for Touch
Instead of click events, we can use pointer events to support both mouse and touchscreens:
$("#playButton").on("pointerdown", () => {
audio.play();
});
So considering fallback handling strategies improves compatibility across varied devices and platforms.
Conclusion
In this extensive guide, we thoroughly explored various techniques to handle audio playback using jQuery:
- Supporting cross browser differences in audio behavior
- Building accessible custom audio controllers
- Optimizing performance with compressed formats and preloading
- Integrating advanced JavaScript audio libraries like Howler.js
- Specifying audio in multiple formats (MP3, AAC, OGG)
- Visualizing audio waveform with Web Audio API
- Saving playback state across sessions using LocalStorage
- Providing Flash and pointer event fallbacks
These approaches allow creating robust, consistent and compelling audio experiences across platforms and devices.
jQuery makes it easy to handle all the UI, events and effects while we leverage HTML5 and JavaScript APIs behind the scenes for audio capabilities.
There are definitely many more possibilities we can build upon these techniques for needs like playlists, reactive visualizations, audio effects etc.
I hope this guide gives you a strong foundation to handle all your audio playback requirements using jQuery! Let me know if you have any other questions.


