HTML5 Audio Looping

152,019

Solution 1

While loop is specified, it is not implemented in any browser I am aware of Firefox [thanks Anurag for pointing this out]. Here is an alternate way of looping that should work in HTML5 capable browsers:

var myAudio = new Audio('someSound.ogg'); 
myAudio.addEventListener('ended', function() {
    this.currentTime = 0;
    this.play();
}, false);
myAudio.play();

Solution 2

To add some more advice combining the suggestions of @kingjeffrey and @CMS: You can use loop where it is available and fall back on kingjeffrey's event handler when it isn't. There's a good reason why you want to use loop and not write your own event handler: As discussed in the Mozilla bug report, while loop currently doesn't loop seamlessly (without a gap) in any browser I know of, it's certainly possible and likely to become standard in the future. Your own event handler will never be seamless in any browser (since it has to pump around through the JavaScript event loop). Therefore, it's best to use loop where possible instead of writing your own event. As CMS pointed out in a comment on Anurag's answer, you can detect support for loop by querying the loop variable -- if it is supported it will be a boolean (false), otherwise it will be undefined, as it currently is in Firefox.

Putting these together:

myAudio = new Audio('someSound.ogg'); 
if (typeof myAudio.loop == 'boolean')
{
    myAudio.loop = true;
}
else
{
    myAudio.addEventListener('ended', function() {
        this.currentTime = 0;
        this.play();
    }, false);
}
myAudio.play();

Solution 3

Your code works for me on Chrome (5.0.375), and Safari (5.0). Doesn't loop on Firefox (3.6).

See example.

var song = new Audio("file");
song.loop = true;
document.body.appendChild(song);​

Solution 4

Simplest way is:

bgSound = new Audio("sounds/background.mp3");
bgSound.loop = true;
bgSound.play();

Solution 5

var audio = new Audio("http://rho.nu/pub/Game%20Of%20Thrones%20-%20Main%20Theme%20-%20Soundtrack.mp3");

audio.addEventListener('canplaythrough', function() {
    this.currentTime = this.duration - 10;
    this.loop = true;
    this.play();
});

Just set loop = true in the canplaythrough eventlistener.

http://jsbin.com/ciforiwano/1/edit?html,css,js,output

Share:
152,019
pr3sidentspence
Author by

pr3sidentspence

Chrome WebGL implementor

Updated on March 18, 2020

Comments

  • pr3sidentspence
    pr3sidentspence over 4 years

    I've been playing with HTML5 audio recently, and though I can get it to play the sound it only ever will play once. No matter what I try (setting the properties, event handlers, etc) I can't seem to get it to loop.

    Here's the basic code I'm using:

    //myAudio is declared at a global scope, so it doesn't get garbage collected.
    myAudio = new Audio('someSound.ogg');
    myAudio.loop = true;
    myAudio.play();
    

    I'm testing using Chrome (6.0.466.0 dev) and Firefox (4 beta 1), both of which seem happy to ignore my requests for looping. Any ideas?

    UPDATE: The loop property is now supported in all major browsers.

  • pr3sidentspence
    pr3sidentspence almost 14 years
    Hm... interesting. I didn't have much luck with this method previously but I wasn't setting the current time. When I try this, however I get: "Uncaught Error: INDEX_SIZE_ERR: DOM Exception 1" on the line "this.currentTime = 0"
  • kingjeffrey
    kingjeffrey almost 14 years
    @Toji Here is the documentation for the INDEX_SIZR_ERR error. It means the beginning of the song is outside the range the browser can seek. This sometimes occurs if the browser thinks it is streaming media, or if the server lacks certain capabilities (I forget offhand what this specific capability is, but I will try to track it down). You can also use this.startTime to return to the earliest available time.
  • kingjeffrey
    kingjeffrey almost 14 years
    @Toji The reason .currentTime is needed has to do with how the spec handles the end of a song. Browsers are supposed to just pause the song. So reinitiating play does so at the end of the song. The playhead must be reset.
  • kingjeffrey
    kingjeffrey almost 14 years
    @Toji Here is another thought if you are unable to get .currentTime working. Inside the callback function, you could simply redeclare myAudio with the same file and play it again. Redeclaring it should also reset the playhead to the beginning of the song.
  • kingjeffrey
    kingjeffrey almost 14 years
    +1 Very cool. I was unaware loop was implemented in webkit.
  • pr3sidentspence
    pr3sidentspence almost 14 years
    setting it to this.startTime gives me the same error, though now I'm starting to wonder if it's a server issue. I'm serving static files from a local django server (which is not django's most robust feature). Pair that with the fact that Anurag's does work and I think it's probably just me. I'll toy with it a bit more and let you know the results.
  • Christian C. Salvadó
    Christian C. Salvadó almost 14 years
    +1, you can also detect if loop is supported, e.g. by: typeof new Audio().loop == 'boolean';
  • pr3sidentspence
    pr3sidentspence almost 14 years
    Whoops! Forgot about this question! The core issue was that I was using a local Django test server to serve up my media files, and apparently it's not too happy about providing streaming information. Uploading and trying scripts like the one listed here to my site's server allows looping.
  • Admin
    Admin over 12 years
    Thx. this worked perfectly for Opera, Firefox, Chrome... so how can we add more sounds(mp3) for Safari.... ??? adding more variables would probably cause duplicates for Chrome (which supports ogg and mp3)...
  • mgiuca
    mgiuca over 12 years
    @pixelass I'm not entirely sure how to do it in code. In HTML, you would nest the <audio> tags inside one another, and the browser would choose the outermost one that matches. I don't know if you can do that nesting in the programmatic Audio object. But you can certainly program it yourself: check out the Audio.canPlayType method.
  • Admin
    Admin over 12 years
    i am aware of the html method. I might try around with the Audio.canPlayType method. right now I'm using 2 variables, so in chrome 2 files are played. this actually doesn't matter too much since it's only some oceanwaves loop I made. ... but simply adding 2 sources would be a lot nicer,. pixelass.com if you care.
  • Lee Goddard
    Lee Goddard almost 12 years
    FF does support loop, but at the date of this comment (Sept 2012), not very well. The bug report is here: bugzilla.mozilla.org/show_bug.cgi?id=449157
  • Josh Bedo
    Josh Bedo over 10 years
    Having a issue with audio only looping when it's cached anyone else have this issue?
  • Alex Char
    Alex Char over 9 years
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient reputation you will be able to comment on any post.
  • Anthony Grist
    Anthony Grist over 9 years
    @AlexChar I disagree. This is at the least an attempt to answer the question. It could benefit from some expanding to show exactly what the code might look like, and it's probably not the best way to solve the problem, but it's not "not an answer".
  • Klaider
    Klaider over 8 years
    @CMS Avoid the use of == and use ===, it's a better operator to beginners and better to performance.
  • Klaider
    Klaider over 8 years
    Doing it so get experience troubles.
  • Ryan Coolwebs
    Ryan Coolwebs about 8 years
    This code works great in all the desktop browsers I tested it on. Although I did not have any luck on mobile browsers (Android, safari or chrome) for both iOS and Android phones. I think it's a widely known issue of support for mobile browsers being inconsistent and/or fragmented? pupunzi.open-lab.com/2013/03/13/… (does anyone have suggestions as to a workaround?)
  • Mostafiz Rahman
    Mostafiz Rahman almost 4 years
    Is this compatible with Firefox 80?