I have a root instance that has several CustomVideo
-components in it (amongst a bunch of other components). The CustomVideo
-component implements VideoJS, but it’s not on all pages that there is a CustomVideo
-component, so I don’t want to import VideoJS globally. Here is an example of components on a page:
App.js | |-- CustomVideo |-- FooComponent |-- CustomVideo |-- BarComponent |-- CustomVideo
In the top of CustomVideo, I import VideoJS, like so:
import videojs from 'video.js'; import abLoopPlugin from 'videojs-abloop' export default { name: "FeaturedVideoPlayer", props: { videoUrl: String } mounted() { let videoOptions = { sources: [ { src: this.videoUrl, type: "video/mp4" } ], plugins: { abLoopPlugin: { 'enabled': true } } }; this.player = videojs(this.$refs.featuredVideoPlayer, videoOptions, function onPlayerReady() {}); }
But if there are more than one CustomVideo
, then I get a console warning:
VIDEOJS: WARN: A plugin named “abLoopPlugin” already exists. You may want to avoid re-registering plugins!
I tried looking into conditional imports, but it doesn’t seem like it’s the way to do it.
Even if I try and import it in app.js
, even though I would rather import it CustomVideo
, then I get another console error:
Attempt
import abLoopPlugin from 'videojs-abloop' Vue.use( abLoopPlugin );
Then I get the error:
Uncaught TypeError: Cannot read property ‘registerPlugin’ of undefined
How do I ensure that a plugin is registered only once?
Advertisement
Answer
Check videojs.getPlugins().abLoopPlugin
videojs.getPlugins()
returns a symbol table of all loaded plugin names. You could simply check that abLoopPlugin
is not in that table before loading it in your component:
import videojs from 'video.js' if (!videojs.getPlugins().abLoopPlugin) { abLoopPlugin(window, videojs) }
Await $nextTick
before using ref
You’ll notice that your videos are initially not visible in your specified <video>
element. This is because the ref
is undefined when you pass it to videojs
in mounted()
.
The ref
docs state:
An important note about the ref registration timing: because the refs themselves are created as a result of the render function, you cannot access them on the initial render – they don’t exist yet!
The solution is to wait until the $nextTick()
:
async mounted() { // this.$refs.featuredVideoPlayer is undefined here await this.$nextTick() // this.$refs.featuredVideoPlayer is the <video> here this.player = videojs(this.$refs.featuredVideoPlayer) }