-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
fix: validation for stalled and suspended event in iOS when headphones disconnect #6199
Conversation
…ones are disconnected
💖 Thanks for opening this pull request! 💖 Things that will help get your PR across the finish line:
We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can. |
src/js/tech/html5.js
Outdated
(this.el_.buffered.end(this.el_.buffered.length - 1) + SAFE_TIME_DELTA >= this.el_.currentTime)) { | ||
this.el_.pause(); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there's much benefit in having this as a separate function. The body of it can probably go directly into the callback below.
src/js/tech/html5.js
Outdated
|
||
const disconnectionIOSListener = () => { | ||
if ((!this.el_.paused && window.navigator.onLine) && | ||
(this.el_.buffered.end(this.el_.buffered.length - 1) + SAFE_TIME_DELTA >= this.el_.currentTime)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to have some explanatory comments about this condition and the TIME_FUDGE_FACTOR
and SAFE_TIME_DELTA
(and that those come from VHS).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably have a local variable here for buffered and check if buffered has length, before trying to get the end of the buffer. Also would it make sense to use tech methods instead of el_
methods here: IE this.pause()
or this.buffered()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, it's possible that there are multiple buffered regions, and we're current in the first or a middle buffered region instead of the last one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good points!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gkatsev Can you explain a little more, since we try to get the end time buffered. (length - 1) and if we have multiple regions it does not matter that means that we still have buffered time and we are not experiencing a Stalled
or suspend
due another problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marcodeltorob basically, we could be at the end of a buffered region which isn't the last buffered region available, so, currentTime will end up being less than the buffered region.
For example, we're at 10 seconds in (marked by |
, and our buffer looks something like:
[0-10|----20-30----60-70----]
Reading the last buffered region, would give us 70 but our currentTime is 10. However, we still can't play because we've run out of buffer.
But, if the currentTime is say 5, and our buffered region has extra buffer, then we should be fine.
[0-5|5-10----20-30----60-70----]
…ody inside event funcion
Updates needed related to buffered regions.
src/js/tech/html5.js
Outdated
|
||
// Establish if we have an extra buffer in the current time range playing. | ||
for (let i = 0; i < buffered.length; i++) { | ||
if (buffered.start(i) <= this.currentTime() <= buffered.end(i) + SAFE_TIME_DELTA) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I think what we want is to check if there is anything in the forward buffer. It seems that if the
currentTime
is equal to thebuffered.end
, then we don't have anything in the forward buffer. Maybe justbuffered.start <= currentTime < buffered.end
? - Should we adjust the
buffered.start
usingSAFE_TIME_DELTA
as well? Maybe not. - We might as well
break
out of the loop when we setextraBuffer = true
.
src/js/tech/html5.js
Outdated
|
||
// Establish if we have an extra buffer in the current time range playing. | ||
for (let i = 0; i < buffered.length; i++) { | ||
if (buffered.start(i) <= this.currentTime() < buffered.end(i) + SAFE_TIME_DELTA) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just verified and buffered.start(i) <= this.currentTime() < buffered.end(i)
doesn't work.
It'll get evaluated as if there are parenthesis around the buffered.start(i) <= this.currentTime()
and evaluate it to true (potentially) which will end up being smaller than any buffered.end(i)
.
> [2, 4, 6, 8, 10].map((f) => 2 <= f < 8)
< [true, true, true, true, true]
> [2, 4, 6, 8, 10].map((f) => 2 <= f && f < 8)
< [true, true, true, false, false]
src/js/tech/html5.js
Outdated
} | ||
|
||
// if tech is not paused, browser has internet connection & player has extraBuffer inside the timeRange | ||
if ((!this.paused() && window.navigator.onLine) && extraBuffer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the extra parens are necessary as the expression will just evaluate each item in turn.
if ((!this.paused() && window.navigator.onLine) && extraBuffer) { | |
if (!this.paused() && window.navigator.onLine && extraBuffer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, should we check extraBuffer first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sense and we can decide quicker the state of the playback.
…, extraBuffer is compared first
src/js/tech/html5.js
Outdated
this.on(['stalled', 'suspend'], (e) => { | ||
const buffered = this.buffered(); | ||
|
||
if (buffered.length > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should do
if (!bufferred.length) {
return;
}
to eliminate the scope here.
…ave any buffer region.
Congrats on merging your first pull request! 🎉🎉🎉 |
Description of the problem:
When playback is ongoing in iOS + Safari and the user disconnect headphones (wired or Bluetooth) the player will throw 'suspend' or 'stalled' after a couple of seconds and 'progress' events.
Solution: Validation for stalled and suspended event for iOS browser when headphones are disconnected