Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why is '_canPlayEvent' default value set to 'canplaythrough'? #1072

Closed
LaCollision opened this issue Nov 12, 2018 · 4 comments
Closed

Why is '_canPlayEvent' default value set to 'canplaythrough'? #1072

LaCollision opened this issue Nov 12, 2018 · 4 comments

Comments

@LaCollision
Copy link

LaCollision commented Nov 12, 2018

Hi,

For html5 mode, why is Howler._canPlayEvent default value set to canplaythrough?

Wouldn't it be faster to use canplay instead?

Thanks!

@goldfire
Copy link
Owner

We decided that for most use-cases it makes sense to use canplaythrough so that the audio won't have to stop halfway through and buffer further.

@schleimschein
Copy link

Hey,

I was considering to use Howler for a web radio player. I very much would like for the radio stream to start immediately after clicking the play button. Unfortunately, with canplaythrough as the _canplayEvent this seems not to be possible if the user hasn't spend enough time on the website to prebuffer what is needed to trigger oncanplaythrough . I therefore tried to replace canplaythrough with canplay, so that the stream starts immediately. However, after replacing replace canplaythrough with canplay, the pause() method is not working anymore in Chrome. I looked into it and it seems like the node.play() promise is never resolved, so that _playLock is not changed to true. Weirdly, this problem can be solved by setting breakpoints after the creating the node.play() promise or by setting a canplay event listener breakpoint. My guess would have been, that some sort of race condition arises but I haven't been able to pinpoint where - I tried altering the playHtml5 function to a async function and await for node.play() but this didn't work, which I'm not surprised by, considering the fact that canplay is beingt triggered immediately upon load.
I would be very grateful if you could help me with this issue, even if it is not the intended purpose of Howler.

Thanks!

@jbgomez
Copy link

jbgomez commented Apr 17, 2022

I also have a need to replace canplaythrough with canplay for the same reasons. After changing the _canPlayEvent value from canplaythrough to canplay, I was also observing that the play promise would never resolve. After some investigation, I discovered what may seem to be a browser bug. Essentially, once the canplay event is emitted, if currentTime is updated (before play is called), but currentTime is already assigned to the "updated" value (i.e., currentTime is 0, and currentTime is set, again, to 0), the play promise will never resolve. The fix I found was to update this line:

https://github.com/goldfire/howler.js/blob/master/src/howler.core.js#L900

to:

if (node.currentTime !== seek) {
  node.currentTime = seek;
}

The fix being that currentTime is only updated if seek is truly a new value. I have a CodePen here that demonstrates this behavior:

https://codepen.io/jbgomez/pen/jOYQeKQ?editors=1010

I will push up a feature branch for this shortly and create a PR.

@jbgomez
Copy link

jbgomez commented Apr 17, 2022

I'd also like to propose a new feature flag (e.g., eagerPlayback, set to false by default) that uses canplay in lieu of canplaythrough. I can create a PR for that as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants