HTML5 Audio Loops
One of the neatest things about HTML5 is support for the new <audio> tag. Like <video> it allows you to natively support media in good browsers like Chrome, FireFox, Opera and Safari. Add a touch of JavaScript and a new era of media applications become possible.
Synthesizers, music trackers and games require seamless audio loops though so we need something a bit simpler for our first foray into HTML5 audio.
Oooh, how about a retro beatbox with individual track adjustments (start/stop/loop/volume) that could be used to build a unique soundscape from many separate instruments. Perfect!
Fantasy can only become reality through hard work so let’s get started with some tests first.
Loop Method 1
Uses the ‘loop’ property.
<audio id="audio_1" controls preload loop> <source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg"> <source src="/wp-content/uploads/2010/04/html5-audio-loop.wav"> <source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3"> </audio>
Loop Method 2
Uses a JavaScript function to loop when an ‘ended’ event is called.
<audio id="audio_2" controls preload> <source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg"> <source src="/wp-content/uploads/2010/04/html5-audio-loop.wav"> <source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3"> </audio>
document.getElementById('audio_2').addEventListener('ended', function(){
this.currentTime = 0;
}, false);
Loop Method 3
Uses two JavaScript functions and two audio elements with the same source to alternate playback duties.
<audio id="audio_3" controls preload> <source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg"> <source src="/wp-content/uploads/2010/04/html5-audio-loop.wav"> <source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3"> </audio> <audio id="audio_4" controls preload> <source src="/wp-content/uploads/2010/04/html5-audio-loop.ogg"> <source src="/wp-content/uploads/2010/04/html5-audio-loop.wav"> <source src="/wp-content/uploads/2010/04/html5-audio-loop.mp3"> </audio>
document.getElementById('audio_3').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio_4').play();
}, false);
document.getElementById('audio_4').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio_3').play();
}, false);
Browser Support
Tests were done on Windows 7 with Chrome 5.0.342.9 beta, FireFox 3.6.3, Internet Explorer 9.0 Preview, Opera 10.51 and Safari 4.0.5.
Chrome seems to trigger loops before the current sound is completely finished leading to some odd jumpiness. All loop methods are affected.
FireFox doesn’t seem to like the ‘loop’ property of method 1, odd. Method 2 has the slightest of delays between loops and method 3 was actually perfect! I didn’t believe it until verification at the millisecond level with Audacity. Hooray Mozilla!
Internet Explorer 9 doesn’t support the audio tag yet. Hopefully it will before an official release.
Opera performs almost as well as FireFox although there is still a small delay even when using method 3.
Safari seems slow to start playback which is very easy to detect once you hear a loop. All loop methods affected.
Feedback on other browsers/OS compatibility would be very interesting so please feel free to discuss any findings in the comments below.
Final Thoughts
As of right now (April 11, 2010) only FireFox can do a perfect loop by cheating a bit and using two <audio> elements with JavaScript.
So yeah, it’s a bit too early for HTML5 audio loops but don’t let that stop you from creating sound boards, media players and other fun things.
Hopefully with some more optimizations audio support will continue to improve and a HTML5 beatbox fantasy can become reality.
Until then there are plenty of other fun things to play with.
Cheers!
April 11th, 2010 at 7:14 pm
The issue with Chrome firing the ended before the true end is a Chromium bug, issue #30452.
http://code.google.com/p/chromium/issues/detail?id=30452
This will likely be resolved in an upcoming Chrome 5 release.
April 11th, 2010 at 7:44 pm
Very good to know. Thanks for the info.
April 11th, 2010 at 11:31 pm
Looks like Firefox doesn’t currently respect the loop or preload attributes. Time to file a Bugzilla report?
May 3rd, 2010 at 10:55 am
works well.
May 3rd, 2010 at 10:57 am
onended=’this.play();’ may be another choice
May 19th, 2010 at 1:22 pm
I’m getting a seconds delay for methods 2 and 3 in Firefox 3.6.3 on Ubuntu 10.04 64bit
And no looping in Chrome at all
May 19th, 2010 at 2:27 pm
Aww, sorry to hear that.
Seems that HTML5 media really needs to be baked more in all the browsers before we can use it reliably.
Is Chrome on Ubuntu good overall? (besides the missing looping of course)
I love it in Windows and just started using it on a Mac too so I’m curious about any differences between platforms.
May 22nd, 2010 at 4:53 pm
Mac OS X 10.6
Opera 10.54 is the best, a perfect loop, using both methods 1 and 2 (also method 3).
Firefox 3.6 methods 2 and 3 are not too bad, but a small pause is audible.
Safari 4.0.5 and Chrome 5.0.375 both have longer pause period.
June 1st, 2010 at 8:12 pm
why you have .ogg .mp3 and .wav
do I need to have the 3 formats???
June 1st, 2010 at 9:58 pm
Yep, but only if you want to make sure you cover the widest audience. Firefox likes .ogg, Chrome/Safari likes .mp3 and Opera 10 likes .wav.
If you are pressed for space I would say go with .ogg and .mp3. I’m sure Opera will add support for these in the future anyway.
Emerging web standards are not always so standard?
June 13th, 2010 at 5:12 am
Excellent info, thanks!
July 2nd, 2010 at 6:40 pm
all good cross browser
shame ff is buggy with loop tho. can still be done anyway
document.getElementById(‘video_2′).addEventListener(‘ended’, function(){
this.currentTime = 0;
}, false);
July 8th, 2010 at 2:17 pm
Drat! Around mid-May they fixed how Chrome was firing Ended early … but unfortunately a few releases later Chrome now doesn’t fire Ended at all!
http://code.google.com/p/chromium/issues/detail?id=45074
(Please “star” the issue if it affects you.)