destroying before removing element causes error with youtube
#1001 opened on Jun 4, 2018
Description
This may not be an "issue" but any guidance would be helpful.
Expected behaviour
Using Plyr.js destroy method in Vue.js component lifecycle hooks should destroy Plyr instance before component is destroyed.
Actual behaviour
My app uses Plyr for two types of sources: HLS and YouTube.
I load Plyr inside of a Vue.js component and destroy it by calling instance.destroy() when the component is unloaded in its beforeDestroy lifecycle hook. This is how I used Plyr in v2 and it worked fine. Please note that Vue.js lifecycle hooks are synchronous and they are not interested in changing that at the moment.
Now, however, YouTube instances can't be destroyed without an error:
vue.runtime.esm.js?ff9b:1683 Error: The YouTube player is not attached to the DOM.
at Y.h.B (www-widgetapi.js:99)
at X (www-widgetapi.js:91)
at Y.(anonymous function).getCurrentTime.cb.(anonymous function) [as stopVideo] (https://s.ytimg.com/yts/jsbin/www-widgetapi-vflQSvpsZ/www-widgetapi.js:109:124)
at HTMLDivElement.player.media.stop (youtube.js?6edf:285)
at plyr_Plyr.stop (plyr.js?1bb6:403)
at plyr_Plyr.destroy (plyr.js?1bb6:1078)
at VueComponent.beforeDestroy (video-player.vue?53d5:335)
at callHook (vue.runtime.esm.js?ff9b:2813)
at VueComponent.Vue.$destroy (vue.runtime.esm.js?ff9b:2598)
at destroy (vue.runtime.esm.js?ff9b:4027)
A breakpoint in the YouTube plugin's stop method shows that the player DOM has been unloaded by Vue long before we get to this stop call.
The HLS.js plyr appears to destroy fine.
Guarding the call to this.media.stop inside destroy kept YouTube to check if the plyr was playing didn't prevent the error. It also caused the timeupdate event to continue firing on the HLS version.
if (this.playing) {
this.stop();
}
At first I thought this must be due to the destroy method being asynchronous in v3, but I'm not sure if that's the case for all source types.
Not sure where to go next. There's an async hook farther up in the application structure that I may be able to wire plyr into, but it would be a shame to not have the ability to wrap the plugin in a reusable component like I could before.
I am not using [https://github.com/redxtech/vue-plyr] but as of writing it looks like they have a similar issue: https://github.com/redxtech/vue-plyr/issues/9
Environment
- Browser: Chrome
- Version: 66
- Operating System: Mac OS
- Version: 10.13.4
Steps to reproduce
- Make a plyr instance in a Vue.js component with YouTube as a source
- Destroy the instance in the
beforeDestroyhook of the component - Make parent component(s) for testing
- Put the plyr component inside of the parents
- Destroy the parent component.
- See error.