Ωmega
Ωmega

Reputation: 43663

HTML5 audio start over

Having

var audio = new Audio("click.ogg")

I play the click sound when needed by

audio.play()

However, sometimes user is so fast that a browser does not play the audio at all (probably when still playing a previous play request). Is this issue related to preload?

How can I force a browser to stop playing and start over? There is no stop, just pause in HTML5 audio component, correct? What workaround can be used here?


Update - Additional note:

I have multiple checkbox-like div elements with a touchend event. When such event is triggered, the elements visually change, a sound is played and an internal variable is set accordingly. If user tap on these elements slowly, everything works nicely. If tap fast, the sound is often completely skipped...

Upvotes: 34

Views: 27298

Answers (4)

Maciej Bukowski
Maciej Bukowski

Reputation: 3348

The simplest solution is to just reset the audio currentTime and ensure it's playing using the play() method. Checking if the audio is playing is not necessary as subsequent play() invocations will not do anything.

audio.currentTime = 0;
audio.play();

Upvotes: 68

Flame
Flame

Reputation: 7561

I noticed that on Firefox, playing a sound again and again really fast (like a short ticking sound) will skip beats often. The best solution I got was to simply call cloneNode and play each sound that way. Its not perfect (compared to Chrome where it sounds flawless):

var audio = document.getElementById('myaudio');
setInterval(function() {
    audio.cloneNode().play();
}, 100);

Upvotes: 2

lipsumar
lipsumar

Reputation: 981

The only way i found how to play a short sound very quickly (so quick that the 2nd sound starts before the first ends) is to actually load 5 or 10 and if you have to play again but are already playing, just go to the next, which is not playing:

    var soundEls = [];//load 10 audios instead of 1
    for(var i=0;i<10;i++){
        var soundEl = document.createElement('audio');
        soundEl.src = url;
        soundEl.preload = 'auto';
        $(this._soundEl).append(soundEl);
        soundEls.push(soundEl);
    }

    var soundElIndex = 0;

    return {play:function(){
        var soundEl = soundEls[soundElIndex];

        if(soundEl.duration > 0 && !soundEl.paused){

            //already playing, switch to next soundEl
            soundElIndex++;
            if(!soundEls[soundElIndex]) soundElIndex=0;
            soundEls[soundElIndex].play();

        }else{

            //not playing
            soundEl.play();    

        }

    }};

Result of this is you can actually play the same sound over itself.

Probably not the right way to do it though.

Upvotes: -1

Drew
Drew

Reputation: 3234

This is the code I've been using and it's working for me:

            if(audioSupport.duration > 0 && !audioSupport.paused){

                //already playing
                audioSupport.pause();
                audioSupport.currentTime = 0;
                audioSupport.play();

            }else{

                //not playing

                audioSupport.play();    

            }

Upvotes: 9

Related Questions