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

How to recover from media errors? #9

Closed
jhilden opened this issue May 23, 2016 · 9 comments · Fixed by #13
Closed

How to recover from media errors? #9

jhilden opened this issue May 23, 2016 · 9 comments · Fixed by #13

Comments

@jhilden
Copy link
Contributor

jhilden commented May 23, 2016

We are experiencing MEDIA_ERR_DECODE errors that are caught by the videojs player. It would seem like a sensible thing trying to call hls.recoverMediaError() in that situation, but I haven't been able to figure out how access the hls instance from the context of the videojs player, yet. Do you have any idea how to do that?

It looks like a Hls.Events.ERROR is never raised in our case so it is not possible to handle the error inside the providers _onError function. However, I think it would still be a good idea to implement something like this https://github.com/dailymotion/hls.js/blob/master/API.md#fatal-error-recovery inside this plugin.

Any help on this would be greatly appreciated. Let me know what further information could be useful for you.

@mikeRead
Copy link

I was looking for the same thing today.
It's a bit of a hack but I'm sending the objects I need back to vidojs like so

in videojs-hls.js/lib/vjs-hls.js inside the function initialize() (on line 10 for me) rewrite the function as

function initialize() {
            var hlsjsConfig = tech.options_.hlsjsConfig || {};

            _hls = new Hls(hlsjsConfig);
            _hls.on(Hls.Events.ERROR, _onError);
            _hls.on(Hls.Events.MANIFEST_PARSED, _onMetaData);
            _hls.attachMedia(_video);

            //return the new hls object that is linked to a videojs player and the dailymotion's Hls Object itself
            if(typeof hlsjsConfig.onLoad == "function"){
                hlsjsConfig.onLoad(_hls, Hls)
            }
}

build the changes grunt build
include the new script (in /dist/vjs.hls.min.js) in to your player code
when creating a player you can use onLoad option that will pass everything you need

 videojs('#video', {
        html5: {
            hlsjsConfig: {
                onLoad:function(thisHls, Hls){
                  thisHls.on(Hls.Events.ERROR, function(event, data){
                    console.log(event, data)
                  });
                }
            }
        },function(){...})

@jhilden
Copy link
Contributor Author

jhilden commented May 31, 2016

thanks a lot for sharing your solution @mikeRead

my approach ended up adding a function to the plugin to pass through native hls methods

this.callNativeHlsMethod = function (methodName) {
  if (typeof _hls.methodName === "function) {
    _hls[methodName]();
  }
};

and then using callNativeHlsMethod('recoverMediaError') from the videojs context.

However, unfortunately it did not fix the media errors I was experiencing. It will just detach/reattach the current media, but not start the player again or something, so not really a very nice user experience.

If other people have found other ways to deal with MEDIA_ERR_DECODE errors, I would be curious to hear about it. On the videojs-contrib-hls plugin I found this issue dealing with the same topic videojs/videojs-contrib-hls#708

@AxelDelmas
Copy link
Contributor

@jhilden : that's a great idea. PR is welcome to integrate media error recovery mechanism in _onError.

@mikeRead : Having a way to pass the hls.js instance in an optional callback seems great too. Can you make a PR with your solution? Small semantic detail, I would not put the callback as a property of hlsjsConfig, but rather at the same level in the html5 object (and then you can get it inside the tech through tech.options_.onLoad

@AxelDelmas
Copy link
Contributor

@jhilden : regarding your media error, did you find anything in hls.js issues ?

If this decode error happens on chrome, it's always a good thing to check the media logs in chrome://media-internals .

What I'm not sure I understood right is: there is never an Error event coming from Hls.js? Are you sure this is a decode error (it should appear in media-internals) ? What are the symptoms of your bug? If playback is stuck it might also be a timestamp issue (small buffer hole, although hls.js has mechanisms to work around this in quite a few cases) ? I would advise that you try playing your stream in the latest version of a vanilla hls.js here, see if you can reproduce your bug, and file an issue in hls.js if you do

@jhilden
Copy link
Contributor Author

jhilden commented Jun 13, 2016

thanks for your help @AxelDelmas

I was not able to find the root cause of the decode errors I was seeing, but I found out that they only happen when using hls.js version 0.6.x (before I didn't know that this is still considered a "prerelease"). Switching to v0.5.x fixed those issues.

@jhilden
Copy link
Contributor Author

jhilden commented Jun 22, 2016

@AxelDelmas I created a PR for the error handling described in the HLS.js documentation in #13

In the meantime I progressed with our setup and now I'm getting actual errors (this time network errors when an .m3u8 URL is not accessible) which are caught in the context of this plugin. My question is now: How can make these errors bubble up to the video.js Player, or how can I raise a new videojs error in order to be able to handle them at the player level. In this case, where the .m3u8 is not accessible I would like to provide the player with a .mp4 fallback video version. Any help on this would be appreciated.

@jhilden
Copy link
Contributor Author

jhilden commented Jun 22, 2016

Before we were trying to use videojs-contrib-hls and with that the errors were correctly arriving in the scope of the player scope. Unfortunately I'm not really sure how they do it. Here they are triggering an error on the playlist loader https://github.com/videojs/videojs-contrib-hls/blob/02b31a5ee953f08919862b102f41871ac30bafb6/src/playlist-loader.js#L416-L425, but I can't find how/where this gets passed further.

@AxelDelmas
Copy link
Contributor

@jhilden I tried to look how to bubble up errors to videojs from source handlers, and ran into this issue: videojs/video.js#2517

I tried to call tech.error("error message") but it had no effect. I'ill take another look in the next days.

@jhilden
Copy link
Contributor Author

jhilden commented Jun 27, 2016

Will take another look into this now. @AxelDelmas if you have any additional ideas, pointers I would love to hear them.

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

Successfully merging a pull request may close this issue.

3 participants