Skip to content

Safari+FF+Opera bug: Ended callback not firering after 2nd playback #71

Closed
nitriques opened this Issue Feb 7, 2012 · 3 comments

2 participants

@nitriques

It took me more than 5 hours to find this, since I really need to be able to make my current project work on the iPad.

The bug happens in a very particular way, on both desktop and mobile version of Safari, Opera, and FF. Chrome just seems to not be affected while I still did not bother testing anything on IE yet.

I have a html5 audio player that has BOTH a ended and timeupdate handler. The thing is the timeupdate always fires as it suppose too, but the ended callback was only called on the first media, not the other ones. Since my animation is based on the ended callabck, I tried to 'recreate' the ended event in the timeupdate one.

if (status.currentTime != 0 && status.currentTime >= status.duration) { ... }

Everything works now perfectly. I even got rid of the unnecessary ended call when setting the media. But I am sure the bug resides elsewhere in jPlayer's code.

@nitriques

I have had this issue again today and found this post via Stack Overflow!

This occurs only when playing small medias files that are played completly during "load" time.
The thing is, timeupdate events reports 0 duration while playing and then 2 events with duration = currentTime.

Since the audio can not go any further, the browsers reports the actual duration of the medis, not the one specified by the metas and does not fire the 'ended' event.

So, this is a problem with the browser, not with the actuel jPlayer code. You can fix it by usign the timeupdate event with this code.

timeupdate: function (event) {
    var status = event.jPlayer.status;
    if (!!status && !status.waitForPlay && !status.waitForLoad && !!status.srcSet) {
        //console.log(status.currentTime + ' ' + status.duration);

        var hasCurrentTime = !isNaN(status.currentTime) && status.currentTime > 0,
            hasDuration = !isNaN(status.duration) && status.duration > 0,
            isEnded = status.currentTime >= status.duration;

        if ( (hasCurrentTime && hasDuration  && isEnded) ) {
            console.log('timeupdate ended');
        }
    }
}

This will work most of the time (And sometimes too much, you have 2 pseudo-ended events...)

@nitriques nitriques closed this Nov 5, 2012
@vguzev
vguzev commented Dec 4, 2014

@nitriques I found another one workaround for this problem that do not generate pseudo-ended events. See http://stackoverflow.com/a/27284512/2079326
Hope this can save some hours for someone in the future.

@nitriques

Great, thanks for sharing @vguzev !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.