Video.js 指南

这些指南涵盖了 Video.js 用户的各种主题

React 和 Video.js

以下是几个 React 和 Video.js 播放器的实现和示例。

别忘了包含 Video.js 的 CSS,它位于 video.js/dist/video-js.css

React 函数式组件和 useEffect 示例

import React from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css';

export const VideoJS = (props) => {
  const videoRef = React.useRef(null);
  const playerRef = React.useRef(null);
  const {options, onReady} = props;

  React.useEffect(() => {

    // Make sure Video.js player is only initialized once
    if (!playerRef.current) {
      // The Video.js player needs to be _inside_ the component el for React 18 Strict Mode. 
      const videoElement = document.createElement("video-js");

      videoElement.classList.add('vjs-big-play-centered');
      videoRef.current.appendChild(videoElement);

      const player = playerRef.current = videojs(videoElement, options, () => {
        videojs.log('player is ready');
        onReady && onReady(player);
      });

    // You could update an existing player in the `else` block here
    // on prop change, for example:
    } else {
      const player = playerRef.current;

      player.autoplay(options.autoplay);
      player.src(options.sources);
    }
  }, [options, videoRef]);

  // Dispose the Video.js player when the functional component unmounts
  React.useEffect(() => {
    const player = playerRef.current;

    return () => {
      if (player && !player.isDisposed()) {
        player.dispose();
        playerRef.current = null;
      }
    };
  }, [playerRef]);

  return (
    <div data-vjs-player>
      <div ref={videoRef} />
    </div>
  );
}

export default VideoJS;

最后,像这样使用组件(参见 Video.js 选项参考

import React from 'react';

// This imports the functional component from the previous sample.
import VideoJS from './VideoJS'

const App = () => {
  const playerRef = React.useRef(null);

  const videoJsOptions = {
    autoplay: true,
    controls: true,
    responsive: true,
    fluid: true,
    sources: [{
      src: '/path/to/video.mp4',
      type: 'video/mp4'
    }]
  };

  const handlePlayerReady = (player) => {
    playerRef.current = player;

    // You can handle player events here, for example:
    player.on('waiting', () => {
      videojs.log('player is waiting');
    });

    player.on('dispose', () => {
      videojs.log('player will dispose');
    });
  };

  return (
    <>
      <div>Rest of app here</div>
      <VideoJS options={videoJsOptions} onReady={handlePlayerReady} />
      <div>Rest of app here</div>
    </>
  );
}

React 类组件示例

此示例组件在 componentDidMount 时实例化 Video.js 播放器,并在 componentWillUnmount 时销毁它。

import React from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css';

export default class VideoPlayer extends React.Component {

  // Instantiate a Video.js player when the component mounts
  componentDidMount() {
    this.player = videojs(this.videoNode, this.props, () => {
      videojs.log('onPlayerReady', this);
    });
  }

  // Dispose the player when the component will unmount
  componentWillUnmount() {
    if (this.player) {
      this.player.dispose();
    }
  }

  // Wrap the player in a `div` with a `data-vjs-player` attribute, so Video.js
  // won't create additional wrapper in the DOM.
  //
  // See: https://github.com/videojs/video.js/pull/3856
  render() {
    return (
      <div data-vjs-player>
        <video ref={node => this.videoNode = node} className="video-js"></video>
      </div>
    );
  }
}

最后,像这样使用组件(参见 Video.js 选项参考

const videoJsOptions = {
  autoplay: true,
  controls: true,
  sources: [{
    src: '/path/to/video.mp4',
    type: 'video/mp4'
  }]
}

return <VideoPlayer {...videoJsOptions} />

在 Video.js 组件中使用 React 组件

此示例演示了在 Video.js 播放器内的一个 Video.js 组件中使用 React 组件。通过这种方法,开发者可以通过 React 管理他们的自定义 Video.js 组件。

首先,创建一个普通的 React 组件

import {Component} from 'react';

export default class ExampleReactComponent extends Component {
  render() {
    return (
      <div>{this.props.text}</div>
    );
  }
};

在该组件中,vjsBridgeComponent 可通过其 props 获得。通过此对象,可以访问 vjsBridgeComponent 的方法。

Video.js 播放器可以通过相同的方式在此 React 组件中被引用

const player = this.props.vjsBridgeComponent.player();

接下来,创建一个 Video.js 组件。

此组件将 React 组件渲染到自身中。基本上,Video.js 组件充当了 Video.js 播放器和 React 组件之间的桥梁

import ExampleReactComponent from './example-react-component';
import ReactDOM from 'react-dom';
import videojs from 'video.js';

const VjsComponent = videojs.getComponent('Component');

class ExampleVjsBridgeComponent extends VjsComponent {

  constructor(player, options) {
    super(player, options);

    // Bind the current class context to the mountReactComponent method
    this.mountReactComponent = this.mountReactComponent.bind(this);

    // When player is ready, call method to mount the React component
    player.ready(() => this.mountReactComponent());

    // Remove the React root when this component is destroyed
    this.on('dispose', () => ReactDOM.unmountComponentAtNode(this.el()));
  }

  // This method renders the ExampleReactComponent into the DOM element of
  // the Video.js component, `this.el()`.
  mountReactComponent() {
    ReactDOM.render(
      <ExampleReactComponent vjsBridgeComponent={this} text='Example React Component' />,
      this.el()
    );
  }
}

// Make sure to register the Video.js component so Video.js knows it exists
videojs.registerComponent('exampleVjsBridgeComponent', ExampleVjsBridgeComponent);

export default ExampleVjsBridgeComponent;

最后,Video.js 桥接组件可以像这样添加到播放器中


// ...

  // Instantiate a Video.js player when the component mounts
  componentDidMount() {
    this.player = videojs(this.videoNode, this.props, () => {
      videojs.log('onPlayerReady', this);
    });

    // Add the ExampleVjsBridgeComponent as a child of the player (or
    // of another component within the player, such as the control bar).
    //
    // You can pass options to your bridge component using the second argument
    // to this method.
    this.player.addChild('exampleVjsBridgeComponent', {});
  }

// ...