3

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?

1
  • Look into the instruction in npm: videojs-abloop, the plugin is one general javascript library, it is not one valid Vue plugin (How to write one plugin. Try to use below codes in app.js. Example: import videojs from 'video.js' import abLoopPlugin from 'videojs-abloop' abLoopPlugin(window,videojs) Refer to Github: Videojs-abloop Commented Jul 9, 2020 at 21:15

2 Answers 2

1
+100

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)
}

Edit Using videojs-abloop in Vue

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for weighing in. I still got the error, when I did what you suggested ( if( !abLoopPlugin.loaded ) { . When I console.logged abLoopPlugin, then I could see that it was a function (and therefore didn't have any loaded-property. But your answer got me to find the answer, which is to do this: if( ! videojs.getPlugins().abLoopPlugin ){ abLoopPlugin( window, videojs ); } . If you edit your answer to include this (and keep the nice comment on nextTick, then I'll mark your answer as the correct solution.
@Zeth Ah, I see that now that I log it. Updated answer and demo.
0

Try creating instance of abLoopPlugin. I followed the same approach for vue-i18n and other plugins to use globally. Something like:

import AbLoopPlugin from 'videojs-abloop'

Vue.use(AbLoopPlugin) // CHECK IF REGISTER PLUGIN ERROR PERSIST

const abLoopPlugin = new AbLoopPlugin({
   ---your settings---
})
export default abLoopPlugin

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.