Skip to content

jwplayer/jwplayer-react

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

jwplayer-react

License Build Tests Test Coverage

<JWPlayer> is a React Component that creates an instance of JW Player's web player. It allows for the use of any player configuration options and/or event hooks that can be used on the standard player (as props), and provides access to player's API directly via a componentDidMount callback.

Contents

Installation

npm i @jwplayer/jwplayer-react

Usage

Standard player with file/library

import JWPlayer from '@jwplayer/jwplayer-react';
...
<JWPlayer
  file='https://path-to-my.mp4'
  library='https://path-to-my-jwplayer-library.js'
/>
...

Platform-hosted playlist

import JWPlayer from '@jwplayer/jwplayer-react';
...
<JWPlayer
  library='https://path-to-my-jwplayer-library.js'
  playlist='https://cdn.jwplayer.com/v2/playlists/playlist_media_id'
/>
...

Custom playlist

import JWPlayer from '@jwplayer/jwplayer-react';
...
const playlist = [{
  file: 'myfile.mp4',
  image: 'myPoster.jpg',
  tracks: [{
    file: 'https://mySubtitles.vtt',
    label: 'English',
    kind: 'captions',
    'default': true
  }],
},
{
  file: 'mySecondFile.mp4',
  image: 'MysecondFilesPoster.jpg',
}];
...
<JWPlayer
  library='https://path-to-my-jwplayer-library.js'
  playlist={playlist}
/>
...

Required Props

These props are required to instantient an instance of JW Player:

  • library
    • Must be a url to a jwplayer web player library. Required if jwplayer library not already instantiated on page (ie. if window.jwplayer is undefined).
    • Type: string
    • Example: https://content.jwplatform.com/libraries/abcd1234.js

  • playlist OR file OR advertising block with oustream: true
    • Player will require content in order to instantiate. See more here.
    • Type: string (for file or playlist) or array (for playlist) or object for advertising
    • Example: https://cdn.jwplayer.com/v2/playlists/abcd1234

If you are not using a cloud hosted player you will need to provide a license key via the config prop. This prop can also be used to pass additional player config options.

  • config
    • JSON config object with all the available options/types available via standard player configuration
    • Type: object
    • Example: { key: "your-key-here" }

Optional Props

All JW Player config options can be used individually as props to configure a jwplayer-react player, i.e., advertising, analytics, playlist, related, width, and height. See the full list here. In addition, you may use the following props:

  • on<Event>, once<Event>
    • jwplayer-react dynamically supports all events in JW Player. Props beginning with on or once are parsed and added as JW Player event handlers. Find the full list of supported events here.
    • Type: (event: { type: string, [key: string]: any }) => void
    • Examples: const callback = (event) => console.log(event)
      • onReady={callback}: Executes callback every time ready event is triggered by player API. Identical to jwplayer(id).on('ready', callback).
      • onComplete={callback}: Executes callback every time complete event is triggered by player API. Identical to jwplayer(id).on('complete', callback).
      • onceTime={callback}: Executes callback the first time time event is triggered by player API. Identical to jwplayer(id).once('time', callback).

  • didMountCallback
    • A callback triggered after component mounts. Can be used to expose the player API to other parts of your app.
    • Type: ({ player: PlayerAPI, id: string }) => void
    • Example: See advanced implementation example

  • willUnmountCallback
    • A callback triggered before component unmounts. Can be used to fire any final api calls to player before it is removed, or to inform a higher order component that a player has been removed.
    • Type: ({ player: PlayerAPI, id: string }) => void
    • Example: See advanced implementation example

API Functionality

For advanced usage,jwplayer-react creates an instance of the player API when mounted, and sets it to this.player, exposing all api functionality listed here.

Advanced Implementation Examples

Interactive Example #1

import React from 'react';
import JWPlayer from '@jwplayer/jwplayer-react';

class PlayerContainer extends React.Component {
  constructor(props) {
    super(props);
    this.players = {};
    this.onBeforePlay = this.onBeforePlay.bind(this);
    this.onPlay = this.onPlay.bind(this);
    this.playerMountedCallback = this.playerMountedCallback.bind(this);
    this.playerUnmountingCallback = this.playerUnmountingCallback.bind(this);
  }
  
  // Registers players as they mount
  playerMountedCallback({ player, id }) {
    this.players[id] = player;
  }

  // Nulls registered players as they unmount
  playerUnmountingCallback({ id }) {
    this.players[id] = null;
  }

  // Prevent multiple players from playing simultaneously
  onBeforePlay(event) {
    Object.keys(this.players).forEach(playerId => {
      const player = this.players[playerId];
      const isPlaying = player.getState() === 'playing';
      if (isPlaying) {
        player.pause();
      }
    });
  }
  
  // Put teal colored outline on currently playing player, remove it from all other players.
  onPlay(event) {
    Object.keys(this.players).forEach(playerId => {
      const player = this.players[playerId];
      const container = player.getContainer();
      if (player.getState() === 'playing') {
        container.style.border = '15px solid #00FFFF';
      } else {
        container.style.border = '';
      }
    });
  }

  render() {
    // Re-usable defaults to use between multiple players.
    const configDefaults = { width: 320, height: 180 };

    return (
      <div className='players-container'>
        <JWPlayer
          config={configDefaults}
          onBeforePlay={this.onBeforePlay}
          onPlay={this.onPlay}
          didMountCallback={this.playerMountedCallback}
          willUnmountCallback={this.playerUnmountingCallback}
          playlist='https://cdn.jwplayer.com/v2/media/1g8jjku3'
          library='https://cdn.jwplayer.com/libraries/lqsWlr4Z.js'
        />
        <JWPlayer
          config={configDefaults}
          onBeforePlay={this.onBeforePlay}
          onPlay={this.onPlay}
          didMountCallback={this.playerMountedCallback}
          willUnmountCallback={this.playerUnmountingCallback}
          playlist='https://cdn.jwplayer.com/v2/media/QcK3l9Uv'
          library='https://cdn.jwplayer.com/libraries/lqsWlr4Z.js'
        />
        <JWPlayer
          config={configDefaults}
          onBeforePlay={this.onBeforePlay}
          onPlay={this.onPlay}
          didMountCallback={this.playerMountedCallback}
          willUnmountCallback={this.playerUnmountingCallback}
          playlist='https://cdn.jwplayer.com/v2/playlists/B8FTSH9D'
          playlistIndex="1"
          library='https://cdn.jwplayer.com/libraries/lqsWlr4Z.js'
        />
      </div>
    );
  }
}
export default PlayerContainer;

Interactive Example #2

import React from 'react';
import JWPlayer from '@jwplayer/jwplayer-react';

class PlayerContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loaded: false
    };
    this.players = {};
    this.onBeforePlay = this.onBeforePlay.bind(this);
    this.didMountCallback = this.didMountCallback.bind(this);
    this.loadPlayerLibrary();
  }

  // Load a player library
  loadPlayerLibrary() {
    const src = "https://cdn.jwplayer.com/libraries/lqsWlr4Z.js";
    const script = document.createElement("script");
    script.src = src;
    script.type = "text/javascript";
    script.onload = () => this.setState({ loaded: true }); // On load, we're ready to set up our player instances
    document.body.append(script);
  }

  // Registers players to container as they mount
  didMountCallback({ player, id }) {
    this.players[id] = player;
    const eventLog = document.getElementById("log");

    // Log all events by player id.
    player.on("all", (event) => {
      const li = document.createElement("li");
      li.innerText = `${id}: ${event}`;
      eventLog.prepend(li);
    });
  }

  // Prevent simultaneous playbacks
  onBeforePlay(event) {
    Object.keys(this.players).forEach((playerId) => {
      const player = this.players[playerId];
      const isPlaying = player.getState() === "playing";
      if (isPlaying) {
        player.pause();
      }
    });
  }

  render() {
    // Re-usable defaults to use between multiple players.
    const configDefaults = { width: 320, height: 180 };

    return this.state.loaded ? (
      <div className="players-container">
        <JWPlayer
          config={configDefaults}
          onBeforePlay={this.onBeforePlay}
          didMountCallback={this.didMountCallback}
          playlist="https://cdn.jwplayer.com/v2/media/1g8jjku3"
        />
        <JWPlayer
          config={configDefaults}
          onBeforePlay={this.onBeforePlay}
          didMountCallback={this.didMountCallback}
          playlist="https://cdn.jwplayer.com/v2/media/QcK3l9Uv"
        />
        <JWPlayer
          config={configDefaults}
          onBeforePlay={this.onBeforePlay}
          didMountCallback={this.didMountCallback}
          playlist="https://cdn.jwplayer.com/v2/playlists/B8FTSH9D"
          playlistIndex="1"
        />
      </div>
    ) : (
      "loading..."
    );
  }
}
export default PlayerContainer;

Contributing

Post issues, or put up PRs that solve pre-existing issues.