videojs / videojs-contrib-ads

A Tool for Building Video.js Ad Plugins
http://videojs.github.io/videojs-contrib-ads/
Other
384 stars 257 forks source link

player.ads is not a function when use react js #313

Closed deysuman closed 6 years ago

deysuman commented 6 years ago

show player.ads is not a function

import React from 'react';
import videojs from 'video.js';
import 'videojs-contrib-ads';
import ads from  'videojs-contrib-ads/dist/videojs.ads.min.js';

export default class MediaPlayer extends React.Component {

   constructor(props){
    super(props);
    this.togglePlayback = this.togglePlayback.bind(this);
   }

  componentDidMount() {

    videojs.plugin('examplePlugin', function(options) {
        this.ads();
    });

    // instantiate video.js
    this.player = videojs(this.videoNode, this.props, function onPlayerReady() {
      //console.log('onPlayerReady', this)

        //this.ads(); // initialize the ad framework

    });

    this.player.examplePlugin();
    console.log('player.ads', this.player.ads);
  }

  // destroy player on unmount
  componentWillUnmount() {
    if (this.player) {
      this.player.dispose()
    }
  }
incompl commented 6 years ago

Could you paste the exact error you're getting?

Also, you shouldn't need both of these lines:

import 'videojs-contrib-ads';
import ads from  'videojs-contrib-ads/dist/videojs.ads.min.js';

I suggest trying with each individually.

FullstackJack commented 6 years ago

I also have this same problem.

VideoPlayer.js:77 Uncaught TypeError: _this.player.ads is not a function

Is this the right module configuration in the package.json?

  "main": "dist/videojs.ads.js",
  "module": "dist/videojs-contrib-ads.es.js",

Should we be pointing module to dist/videojs-contrib-ads.cjs.js?

FullstackJack commented 6 years ago

Scratch that. Just saw the export default contribAdsPlugin at the bottom of dist/videojs-contrib-ads.es.js.

I also tried this.ads(); and same problem. The HLS plugin works fine so I'm bewildered why this plugin does not seem to get registered.

FullstackJack commented 6 years ago

Ok, I've discovered that you should not use a arrow function class method as the callback and you have to manually register the plugin after import.

The this context of an arrow function is the React component and a regular class method has scope of the calling context.

The next part I don't understand, I manually register the plugin after importing it. At the bottom of the imported file, it does this so maybe this is not the same videojs object reference.

video-contrib-ads.es.js

var registerPlugin = videojs.registerPlugin || videojs.plugin;

// Register this plugin with videojs
registerPlugin('ads', contribAdsPlugin);

export default contribAdsPlugin;

Here is some working code (sans ad logic):

import React from 'react';
import videojs from 'video.js';
import ads from 'videojs-contrib-ads';

// Registers ads plugin... why not handled by imported module?
videojs.registerPlugin('ads', ads);

class VideoPlayer extends React.Component {
  componentDidMount() {
    const options = {
      // ...
    };
    this.player = videojs(this.videoNode, options, this.onPlayerReady);
  }

  onPlayerReady() {
    this.ads();
  }

  render() {
    return (
      <div data-vjs-player>
        <video
          id="video-player"
          ref={c => {this.videoNode = c;}}
          className="video-js"
        />
      </div>
    );
  }
}

Now I get a new error.

Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause(). 

https://goo.gl/LdLk22
incompl commented 6 years ago

I posted information on this issue here: https://github.com/videojs/videojs-contrib-ads/issues/314

The "Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause()." message is normal, it happens because of how cancelContentPlay.js and it will go away when we update this plugin to use middleware.

incompl commented 6 years ago

@FullstackJack Still need help? Hoping the DOMException ended up being a non-issue.

incompl commented 6 years ago

Closing this for now as a duplicate of #326 but please let us know if we can help!