MonkeyShoulder
MonkeyShoulder

Reputation: 83

Audio ended event doesn't work

Have some trouble with catch this event. Have:

<div id="click_me"></div>    
<audio class="fo_audio">
       <source src="track1.mp3" type="audio/mpeg; codecs='mp3'">
    </audio>
    <audio class="fo_audio">
       <source src="track2.mp3" type="audio/mpeg; codecs='mp3'">
    </audio>
    <audio class="fo_audio">
       <source src="track3t.mp3" type="audio/mpeg; codecs='mp3'">
    </audio>

and try to do smth:

song_number = 0;
$("#click_me").click(function(){
$("audio").get(song_number).play()
    });     
$("audio").get(song_number).ended(function(){
    song_number++;
    $("audio").get(song_number).play();
    }); 

How to do it work?

Upvotes: 0

Views: 3688

Answers (4)

PSerru
PSerru

Reputation: 1

I also believed that the event "ended" worked badly. It was an edge effect (considering my context) of not using the removeEventListener. So, be aware : if you remove an AudioElement, do not forget to remove the concerned installed event handlers, too.

Upvotes: 0

MonkeyShoulder
MonkeyShoulder

Reputation: 83

Answer is:

var count = $("audio").length;
$("audio").each(function (song_number) {
  if (song_number < count-1) {
    this.addEventListener("ended", function () {
      $("audio")[song_number+1].play();
    });
  }
});

Upvotes: 0

Beetroot-Beetroot
Beetroot-Beetroot

Reputation: 18078

After playing around for a bit I ended up with this :

HTML:

<audio class="fo_audio" controls="controls">
   <source src="http://cache.gizmodo.com/assets/resources/mp3/Woman64.mp3" type="audio/mpeg" />
   <source src="http://cache.gizmodo.com/assets/resources/mp3/WomanWAV.wav" type="audio/wav" />
</audio>
<audio class="fo_audio" controls="controls">
   <source src="http://cache.gizmodo.com/assets/resources/mp3/FeelGood64.mp3" type="audio/mpeg" />
   <source src="http://cache.gizmodo.com/assets/resources/mp3/FeelGoodWAV.wav" type="audio/wav" />
</audio>
<audio class="fo_audio" controls="controls">
   <source src="http://cache.gizmodo.com/assets/resources/mp3/Carmen64.mp3" type="audio/mpeg" />
   <source src="http://cache.gizmodo.com/assets/resources/mp3/CarmenWAV.wav" type="audio/wav" />
</audio>
<div>
<button class="play" data-which="0">Play 0</button>
<button class="play" data-which="1">Play 1</button>
<button class="play" data-which="2">Play 2</button>
<button class="play" data-which="all">Play all</button>
</div>

Javascript:

var playing = false;
function playCascade(e) {
    if(playing) { return; }
    var song_number = e.song_number || 0;
    var $a = $("audio").eq(song_number);
    if($a.length) {
        $a.get(0).play();
        $a.off('ended').on('ended', function(){
            playing = false;
            if(e.continu) {
                playCascade($.extend(e, {
                    'song_number': song_number + 1
                }));
            }
        });
        playing = true;
    }
    else {
        playing = false;
    }
}
$(".play").on('click', function(e) {
    var which = $(this).data('which');
    playCascade($.extend(e, {
        'song_number': Number($(this).data('which')) || 0,
        'continu': which == 'all'
    }));
});

DEMO

Notes:

  • Play sequence is achieved with recursion.
  • Event object e is extended to pass custom data.
  • A new 'ended' handler is attached to the audio objects at each play.
  • 'continue' is a javascript reserved word, therefore best avoided. Hence 'continu'.
  • The demo has an extra line which causes just the last 5 seconds of each clip to be played.
  • To hide the audio elements, remove controls="controls" from the <audio> tags.
  • Tested in Opera 12.02 .

And here's a variant of the code : http://jsfiddle.net/bbPCk/3/

Upvotes: 0

Carl Raymond
Carl Raymond

Reputation: 4479

Your code is only assigning an ended() handler to the first audio clip. Try this:

var count = $("audio").size();
$("audio").each(function (song_number) {
  if (song_number < count-1) {
    this.ended(function () {
      $("audio")[song_number+1].play();
    });
  }
});

This is untested. It loops over each audio clip, and attaches an ended() event that will start playing the next clip. The last clip does not get an event handler.

Upvotes: 1

Related Questions