Overview

Boclips Player is a framework agnostic HTML5 video player that enables playing Boclips supplied videos on all our supported devices. It features core functionality that can be expected of modern video players, such as analytics, closed captions, and adaptive bit rate streaming.

We are fully committed to providing partners with a complete player solution that also provides insights into how their users watch our videos.

Getting Started

There are a number of ways to use the boclips-player, either via a script tag or importing as a module.

Before getting started, please ensure you are able to authenticate with and use the Boclips API. You must pass a boclips video URI endpoint to Player.loadVideo. See Video Access for more information.

You also must provide a valid boclips-token to the player, as we require all requests to be authenticated. See Authentication for more information.

Our API is protected by several methods, one of these is CORS. Since the boclips-player makes API requests to our server you’ll need to ensure we’ve whitelisted any domains where you load our player.

In order to do this, please get in touch with us with a list of domain names (including protocols and any port numbers — if required) that will host this player.

Importing as a module

You can use the boclips-player as a module in your JavaScript application. You can install it using npm, yarn, or any other javascript package manager

npm i boclips-player

Below is a minimal example of using the Boclips player. The Player requires providing an HTML container, which will encapsulate the HTML5 video player.

import { PlayerFactory } from "boclips-player";

const playerContainer = document.createElement('div');
playerContainer.id = 'player-container';
document.body.appendChild(playerContainer);


// This is for fetching a boclips token
const tokenFactory = (): Promise<string> => {
  return fetch("your-service.com/boclips-token")
    .then(response => response.json())
    .then(data => data.token);
};

function renderPlayer() {
  const player: Player = PlayerFactory.get(playerContainer, {
    api: { tokenFactory }
  });

  // See https://docs.boclips.com/docs/api-guide.html#resources-video-access for more info on this URI.
  player.loadVideo("https://path.to.boclips.video.from.the.api");
}

renderPlayer();

A full definition of player type can be found here

Loading via a script tag

You can also load the boclips-player via a script tag. Either using the unpkg CDN or hosted by yourself. You should include both boclips-player.js and boclips-player.css to get the full experience. When this library is loaded via a script tag it exposes the PlayerFactory under the global variable Boclips.

<html>
  <head>
    <title>Plain Demo</title>
    <script
      src="https://unpkg.com/boclips-player/dist/boclips-player.js"
      type="text/javascript"
    ></script>
    <link
      rel="stylesheet"
      href="https://unpkg.com/boclips-player/dist/boclips-player.css"
      type="text/css"
    />
  </head>
  <body>
    <div id="container"></div>
    <script type="text/javascript">

      // This is for fetching a boclips token
      const tokenFactory = () => {
        return fetch("your-service.com/token")
          .then(response => response.json())
          .then(data => data.token);
      };

      const container = document.querySelector("#container");
      const player = Boclips.PlayerFactory.get(container, {
        api: { tokenFactory }
      });
      player.loadVideo("https://path.to.our/video/endpoint/1");
    </script>
  </body>
</html>

Authentication

The Boclips API requires authentication in order to accurately track viewer attribution and user engagement.

The player requires a token factory which is needed for generating a valid boclips token. We recommend the token factory sends a request to your backend service, which then handles getting a token from boclips. More details about generating a boclips token can be found here

The types required for authenticating the player with the Boclips API are shown below. See Importing as a module for an example of using a token factory.

interface PlayerOptions {
  api: Partial<ApiOptions>;

  // other options...
}

interface ApiOptions {
  /**
   * This callback should return a Promise which resolves a string to be used as the users authentication token.
   * For more information on generating a token see https://docs.boclips.com/docs/api-guide.html#authentication-overview
   *
   * If this callback rejects the promise for whatever reason, an error will be displayed to the user.
   */
  tokenFactory: () => Promise<string>;
}

options.api.tokenFactory is important as tokens do expire. It is your responsibility to ensure that the token that is returned by options.api.tokenFactory is a valid token — failure to do so may result in a poor experience for the user.

Analytics

In order for us to provide you with insights into the way in which your users watch our curated videos, you can provide the player with user IDs.

This allows us to provide you with usage statistics for each of your users. This information will also allow us to personalise and tailor your Boclips experience and content to your user’s usage patterns.

We also expose an onSegmentPlayback callback that you can use for your own internal analytics

Any information provided will strictly be processed in accordance with our Privacy Policy.

Analytics Options

const options: AnalyticsOptions = {
  metadata: {
    userId: user.id,
  },
  handleOnSegmentPlayback: (
    video: Video,
    startSeconds: number,
    endSeconds: number,
  ) => {},
};
const player = Boclips.PlayerFactory.get(
  document.querySelector('#player-container'),
  options,
);
player.loadVideo(video);

Configuring Boclips Player

Many aspects of the player are customisable. Below are some of the ways you can tailor the Boclips player to your liking.

Player Controls

When configuring the player, you have the ability to specify which player controls the user can see.

const player = PlayerFactory.get(playerContainer, {
  interface: {
    controls: [
      'play-large',
      'play',
      'progress',
    ],
  },
});

// valid controls are
type Controls =
    | 'play-large' // The large play button in the center
    | 'restart' // Restart playback
    | 'rewind' // Rewind by the seek time (default 10 seconds)
    | 'play' // Play/pause playback
    | 'fast-forward' // Fast forward by the seek time (default 10 seconds)
    | 'progress' // The progress bar and scrubber for playback and buffering
    | 'current-time' // The current time of playback
    | 'duration' // The full duration of the media
    | 'mute' // Toggle mute
    | 'volume' // Volume control
    | 'captions' // Toggle captions
    | 'settings' // Settings menu
    | 'fullscreen'; // Toggle fullscreen

If you don’t specify any controls the player defaults to the below controls

[
    'play-large',
    'play',
    'progress',
    'current-time',
    'mute',
    'volume',
    'captions',
    'fullscreen',
]

Addons

The player comes with the ability to add extra functionality with addons. These help fine tune the player experience.

interface InterfaceOptions {
  addons: {
    seekPreview?: boolean | SeekPreviewOptions;
    hoverPreview?: boolean | HoverPreviewOptions;
    singlePlayback?: boolean;
  };

  // other options
}

Seek Preview addon

Seek preview shows a thumbnail when the user hovers over the seek bar. This is enabled by default (which uses a frameCount of 15), you can fine tune the number of frames loaded using the interface below.

interface SeekPreviewOptions {
  /**
   * Number of frames to retrieve for distribution over the length
   * of the video. The minimum value is 10 and the maximum value is 20
   */
  frameCount: number;
}

Hover Preview addon

Hover preview shows a timelapse of thumbnails when the user hovers over the video before they start playing. This is disabled by default.

interface HoverPreviewOptions {
  /**
   * Number of frames to retrieve for distribution over the length
   * of the video. The minimum value is 4 and the maximum value is 15
   */
  frameCount: number;
  /**
   * Number of ms each thumbnail is displayed for. The minimum value is 200 and the maximum value is 1000
   */
  delayMilliseconds: number;
}

Single Playback addon

This is used if you have multiple boclips players on the page and only want to limit playback to one at a time. When this is on, only a single boclips video will be played at a time, if the user starts playing a second video the first video will be paused. Useful for displaying a list of playable videos.

Loading a section of a video

The PlaybackSegment interface is a wrapper for two params specifying when a video should start and end, and can be provided as the second argument when calling loadVideo. This will prevent the user being able to see any other part of the video.

start defines when the video begins in seconds. The value must be positive. Giving it a negative value results with the player displaying the spinner and no video.

end defines when the video stops. Giving is a negative value doesn’t affect the behaviour of the player. It needs to be greater than the value for start field to restrict the video length.

player.load(videoUri, {start: 10, end: 100})


interface PlaybackSegment {
  /**
   * The number of seconds into the video that the segment starts
   */
  start?: number;

  /**
   * The number of seconds into the video that the segment ends
   */
  end?: number;
}

Player interface

interface PlayerFactory {
  /**
   * Will return a player instance, mounted into the supplied container with the given player options
   */
  get: (
    container: HTMLElement | string,
    options: Partial<PlayerOptions> = {}
  ) => Player;
}

interface Player {
   /**
   * Will play the currently loaded video
   */
  play: () => Promise<any>;

  /**
   * Will pause the currently playing video
   */
  pause: () => void;

  /**
   * Will load a given boclips video into the player
   */
  loadVideo: (videoUri: string, segment?: PlaybackSegment) => Promise<void>;

  /**
   * Destroys the current player instance
   */
  destroy: () => void;

  /**
   * Will execute the given callback if the player encounters any errors
   */
  onError: (callback: (error: BoclipsError) => void) => void;
}

License

BSD 3-Clause "New" or "Revised" License

Copyright (c) 2021, Knowledgemotion Ltd All rights reserved.