-
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
feat: Retry on error #7038
feat: Retry on error #7038
Conversation
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.
Not sure why tests are failing, I would ignore that for now.
src/js/player.js
Outdated
const retry = () => { | ||
// Remove the error modal | ||
this.error(null); | ||
this.retrying_ = true; |
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.
is it possible that we can re-use changingSrc_
here? It gets set to true when we set a new source and then is updated to false when a source gets set.
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.
Unfortunately I don't believe so. retrying_
signals that at least one retry has been attempted, so we don't add the removeRetryHandler
below more than once during any subsequent retries. At the point when we need to check whether to add that handler or not, changingSrc_
is always true
so it cannot serve the same purpose.
'last source remains' | ||
); | ||
|
||
player.dispose(); |
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.
can we add a final check that verifies that player.currentSources()
still contains the initial list?
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.
Good thinking
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.
Done
src/js/player.js
Outdated
// Remove the error modal | ||
this.error(null); | ||
this.retrying_ = true; | ||
this.src(sources.slice(1)); |
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 did notice that we do the same thing above in the mdidleware setSource callback. I assume that that only happens when a middleware handler returns an error all the way down?
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.
No, I think that piece only is actually badly named. The err
there is actually whether any techs can play the currently chosen source. So, this still makes sense. I think the other piece would trigger if we were to add say an RTMP source. Though, that's actually a good thing to verify that the two pieces don't step on each other's toes.
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.
There was an offline discussion about the issue of differentiating between a src()
call that comes from a user vs. one that comes from the retry process.
One potential avenue for that is to add another argument to src()
but I think a preferable approach would be to use a pseudo-private method to hide the second argument. Something like:
src(source) {
return this.src_(source);
}
src_(source, duringReset) {
// Everything from current src() method, using duringReset as a
// differentiator and calling src_() internally.
}
I know src_()
already exists, but I'm using it here for demonstration purposes.
…rom public source setting
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.
Looks good. I did find an infinite error loop that's not great. Let me investigate it some more first.
So, the infinite loop happens in this type of cases:
If I listen to the error with |
Hey! We've detected some video files in a comment on this issue. If you'd like to permanently archive these videos and tie them to this project, a maintainer of the project can reply to this issue with the following commands:
|
Co-authored-by: Gary Katsevman <[email protected]>
Co-authored-by: Gary Katsevman <[email protected]>
Co-authored-by: Gary Katsevman <[email protected]>
So, with the following thing we end up with a player that works but I think it works because our error handlers aren't getting cleared up properly: player.src([
{src: './oceans.foo', type: 'video/mp4'},
{src: './oceans.mp4', type: 'video/mp4'},
{src: 'https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8', type:'application/x-mpegurl'},
]);
player.on('error', () => {
console.log('iteration %d', ++i, DomData.get(player.el()).handlers.error.length);
player.src([
{src:'./oceans.bar', type:'video/mp4'},
{src:'./oceans.baz', type:'video/mp4'},
{src: 'https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8', type:'application/x-mpegurl'},
]);
}); I then added this line below where we add the error handler console.log('retry add', retry.guid) and then the following before removal (in both playing handler and the reset method) console.log('retry remove', retry.guid) I then end up with the following output:
Notice that 551, 1034, and 1046 haven't been removed. I'd expect that only 1046 wouldn't have a matching remove yet.
I think these extra error handlers end up making the above snippet work. |
Hey! We've detected some video files in a comment on this issue. If you'd like to permanently archive these videos and tie them to this project, a maintainer of the project can reply to this issue with the following commands:
|
I updated the reset logic so we remove all retry-related event handlers on every |
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.
Verified locally that the handlers get removed properly now and double-checked how this works for autoplay.
LGTM!
This PR fixes #1805! |
When can we expect the new release that will include this feature? |
@John2397 this is available now in v7.12. |
Looks like we forgot to document this option in https://github.com/videojs/video.js/blob/main/docs/guides/options.md |
Add a `retryOnError` option. When set, during source selection, if a source fails to load, we will retry the next item in the sources list. In the future, we may enable this by default. A source that fails during playback will *not* trigger this behavior. Fixes videojs#1805.
Add a `retryOnError` option. When set, during source selection, if a source fails to load, we will retry the next item in the sources list. In the future, we may enable this by default. A source that fails during playback will *not* trigger this behavior. Fixes videojs#1805.
Description
This adds support for a
retryOnError
option that will have the player select a new source from the source list when the selected one fails prior to playback. If a source fails during playback, no retry will be attempted.