I really like to get feedback on the topics I write, good or bad. The good ones immediately get forwarded to my boss in hopes of a few more points in my review. The bad ones I try to fix the topics to make them better.
Some recent feedback wasn't really bad, but rather a suggestion. "Luke" posted a comment on my topic "Using JavaScript to Control the Audio Object" saying that he'd like to change songs on the fly with a pick list. The original had a text box that you could write in your own audio file to play.
There's a pretty slick multi-file player that uses SVG, audio, and XML to create a cool player. For something a little simpler (seems to be a theme song in here somewhere), the mods I did to my original single song player might do the trick.
Specifying a source file on an audio element
There's two ways to assign a URL to an audio element in HTML, use the src attribute on the audio element or the source element between the audio tags. The src attribute is good when you have just a single file that you're going to play.
Here's an ultra simple audio player:
<!DOCTYPE html>
< html>
<head>
<title>Simple Audio Example</title>
< /head>
< body>
<audio control src="songfile.mp3" >Not supported</audio>
< /body>
< /html>
If you want to give the audio element a few choices of format, such as mp3, aac, or ogg, then you'll want to use the source elements.
<!doctype html>
< head>
<title>
Multiple format audio example
</title>
<!-- Uncomment the following meta tag if you have issues rendering this page on an intranet site. -->
<!-- <meta http-equiv="X-UA-Compatible" content="IE=9"/> -->
< /head>
< body>
<h1>
Using source to support multiple audio formats
</h1>
<!-- The browser will automatically choose the format it supports. -->
<audio controls="true">
<source src="demo.mp3" type="audio/mp3">
<source src="demo.ogg" type="audio/ogg">
<source src="demo.aac" type="audio/mp4">
<!-- If no support at all. -->
HTML5 audio not supported
</audio>
< /body>
< /html>
The source element takes a single src attribute, but you can stack up as many elements as you have formats for a given file. The only downside is that the <audio> element will only pick the first format it can play. If you try to put three different mp3 songs in <source> elements, only the first will play, every time. Unlike the track element, which similarly resides between the video element tags, you have no control, selection is automatic.
Swapping different audio source files
To set up multiple sources, like a playlist, you need to write a little JavaScript, very little. When you want to change songs on an audio control, you can simply assign a new URL to the src property and call play(). There is one gotcha that can pop up. If you originally specified a song with the source element, you need to add one step, call load() before calling play().
<!DOCTYPE html>
<html>
< head>
<title>Simple song switcher</title>
< /head>
< body>
<audio controls="controls" id="myaudio">
source src="firstaudiofile.mp3" type="audio/mp3">
Sorry, HTML5 audio isn't supported.
</audio><br />
<button id="mybutton">Change songs</button>
<script>
// Handle the button click and play new file
document.getElementById("mybutton").addEventListener("click", function () {
// Get audio object from audio element
var oAudio = document.getElementById('myaudio');
// double check support, and set the
if (oAudio) {
oAudio.src = "nextaudioURL.mp4";
oAudio.load();
oAudio.play();
}
}, false);
</script>
< /body>
< /html>
That's pretty much all you need to do. Where code could get complex is in the song switching algorithm.
A little more of a demo
Here's a dressed up version of the original sample from Using JavaScript to control the audio object.
Not much to look at, but you can choose between 5 songs, or load your own. The code is below.
The example has a simple UI that consists of an input field, a select box, and a few buttons. The songs are hard coded into the select box, with the text and URL for a song as a data pair on each option element.
All events are handled by addEventListeners in the JavaScript code. To switch the Play button between "Play" and "Pause", we've added event listeners to the pause and play events, rather than tracking it in the play button code itself. This allows the button to follow the actual state of the audio control. While the initial code doesn't expose the audio controls, you could add the controls="controls" attribute to the audio element and your play button would still stay in sync. Of course, every time the song changes, the load() method is called.
<!DOCTYPE html>
< html>
<head>
<title>HTML5 audio playlist demo </title>
<!-- Uncomment the following meta tag if you have issues rendering this page on an intranet site. -->
<!-- <meta http-equiv="X-UA-Compatible" content="IE=edge"/> -->
</head>
<body>
<h1>Audio playlist demo</h1>
<p><label>Enter an audio file URL:
<input type="text" id="audiofile" size="80" />
</label>
</p>
<p>Or pick from this list:</p>
<select id="myselect">
<option value="http://testdriveie9.wise.glbdns.microsoft.com/ietestdrivecontent/Musopen.Com Symphony No. 5 in C Minor, Op. 67 - I. Allegro con brio.mp3">Symphony No. 5 in C Minor, Op. 67 - I. Allegro con brio (Ludwig van Beethoven)</option>
<option value="http://testdriveie9.wise.glbdns.microsoft.com/ietestdrivecontent/Musopen.Com Symphony No. 5 in C Minor, Op. 67 - II. Andante con moto.mp3">Symphony No. 5 in C Minor, Op. 67 - II. Andante con moto (Ludwig van Beethoven)</option>
<option value="http://testdriveie9.wise.glbdns.microsoft.com/ietestdrivecontent/Musopen.Com Symphony No. 5 in C Minor, Op. 67 - III. Allegro.mp3">Symphony No. 5 in C Minor, Op. 67 - III. Allegro (Ludwig van Beethoven)</option>
<option value="http://testdriveie9.wise.glbdns.microsoft.com/ietestdrivecontent/Musopen.Com Symphony No. 5 in C Minor, Op. 67 - IV. Allegro.mp3">Symphony No. 5 in C Minor, Op. 67 - IV. Allegro (Ludwig van Beethoven)</option>
<option value="http://testdriveie9.wise.glbdns.microsoft.com/ietestdrivecontent/Musopen.Com Piano Concerto in A Minor, Op. 16 - I. Allegro molto moderato.mp3">Piano Concerto in A Minor, Op. 16 - I. Allegro molto moderato (Edvard Grieg)</option>
</select>
<p>All selections performed by Skidmore College Orchestra</p>
<audio id="myaudio">
HTML5 audio not supported
</audio>
<button id="play">
Play
</button>
<button id="rewind">
Rewind
</button>
<button id="forward">
Fast forward
</button>
<button id="restart">
Restart
</button>
<script>
// Global variable to track current file name.
var currentFile = "";
var oAudio = document.getElementById('myaudio');
var btn = document.getElementById('play');
var audioURL = document.getElementById('audiofile');
var mySelect = document.getElementById("myselect");
document.getElementById("play").addEventListener("click", function () {
// Check for audio element support.
if (oAudio) {
try {
// Tests the paused attribute and set state.
if (oAudio.paused) {
//Skip loading if current file hasn't changed.
if (audioURL.value !== "") {
if (audioURL.value !== currentFile) {
oAudio.src = audioURL.value;
currentFile = audioURL.value;
oAudio.load(); // load the file
}
} else {
var index = mySelect.selectedIndex;
var playThis = mySelect.options[index].value;
if (playThis !== currentFile) {
oAudio.src = playThis;
currentFile = playThis;
oAudio.load(); // load the file
}
}
oAudio.play();
}
else {
oAudio.pause();
}
}
catch (e) {
// Fail silently but show in F12 developer tools console
if (window.console && console.error("Error:" + e));
}
}
}, false);
// These two event listeners handle changing the play button from Pause to Play and back.
oAudio.addEventListener("pause", function () { btn.textContent = "Play"; }, false);
oAudio.addEventListener("play", function () { btn.textContent = "Pause"; }, false);
// Rewinds the audio file by 30 seconds.
document.getElementById("rewind").addEventListener("click", function () {
if (oAudio) { // Check for audio element support.
try {
oAudio.currentTime -= 30.0;
}
catch (e) {
// Fail silently but show in F12 developer tools console
if (window.console && console.error("Error:" + e));
}
}
}, false);
// Fast forwards the audio file by 30 seconds.
document.getElementById("forward").addEventListener("click", function () {
if (oAudio) { // Check for audio element support.
try {
oAudio.currentTime += 30.0;
}
catch (e) {
// Fail silently but show in F12 developer tools console
if (window.console && console.error("Error:" + e));
}
}
}, false);
// Restart the audio file to the beginning.
document.getElementById("restart").addEventListener("click", function () {
if (oAudio) { // Check for audio element support.
try {
oAudio.currentTime = 0;
}
catch (e) {
// Fail silently but show in F12 developer tools console
if (window.console && console.error("Error:" + e));
}
}
}, false);
// On changing songs, pause video and call Play function again
mySelect.addEventListener("change", function () {
oAudio.pause();
btn.click();
}, false);
</script>
</body>
< /html>