question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

destroying before removing element causes error with youtube

See original GitHub issue

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 beforeDestroy hook of the component
  • Make parent component(s) for testing
  • Put the plyr component inside of the parents
  • Destroy the parent component.
  • See error.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:17

github_iconTop GitHub Comments

6reactions
fridaycommented, Sep 15, 2018

@qikkeronline This type of comment is discouraged in the FAQ and contribution guidelines. Anyone has the right to fork Plyr, fix this issue and submit a PR. No one has, and afaik no one is working on it.

I think (at least hope) my previous comment is helpful if someone wants to have a try. Speaking of “try”, the simples solution is probably adding a try/catch somewhere in the code or wrapping your destroy() calls.

I’m no longer helping out with Plyr development so I’m going to unsubscribe (so @mention me if you need to reach me).

Update: You can dislike this all you want. Doesn’t change anything.

2reactions
fridaycommented, Jun 7, 2018

Youtube and Vimeo events are async.

destroy() restores the element to how it was before Plyr transformed it (removes event listeners and Plyr elements). It also stops the media playback. With youtube you may not have any original element (see the part about “progressive enhancement”: https://github.com/sampotts/plyr/#youtube-embed), in which case the error may happen (not sure), or like in your case, Vue may be removing the element before stopVideo is executed in which case this may also happen.

I’d say it’s a bug on our side. We should either not stop from destroy, add an optional argument to control it, or handle errors in stop due to being called from destroy.

You may not need destroy though, if you’re going to remove the plyr container element, and have no other references to Plyr. Event listeners and such gets destroyed along with their elements, and garbage collection kicks in when there are no more references to something.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to successfully destroy a MediaElementPlayer and create ...
You can use the remove() method of medialementjs, set the type and src attribute of your video element and then reinitialize mediaelementjs if...
Read more >
Why I HAD to DESTROY the World - YouTube
Why I HAD to DESTROY the WorldGo check out my new cape on Mantle: https://mantle.gg/shop/kjmasterLevels SMP ...
Read more >
YouTube Player API Reference for iframe Embeds
This function creates an <iframe> (and YouTube player) ... This error occurs when a video has been removed (for any reason) or has...
Read more >
You should never delete YouTube videos – Why I still did!
What happens when you delete a YouTube video? When you pull a video from your channel, it can hurt other videos' performance and...
Read more >
(Case 1426900) Error "Destroy may not be called from edit ...
Hi. I found that when I stop play mode in editor, an error "Destroy may not be called from edit mode!" is shown...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found