Overview

Boclips Player is a framework agnostic HTML5 video player which serves to play Boclips supplied videos on all our supported devices. It will feature core functionality that is expected of modern video players, such as analytics, closed captions, and adaptive bit rate streaming.

It can be integrated into JavaScript applications with ease. We are fully committed to provide partners with a complete player solution that allows us to gain insights to how our consumers watch our videos.

Usage

In order to render the Boclips Player on your page you should load the Javascript and CSS assets in the head section.

Boclips Player is hosted in the unpkg.com CDN

In order to load a video you must have a Video URI pointing to our API.

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.

Loaded via a script tag

When this library is loaded via a script tag on a web page it exposes the PlayerFactory under the global variable Boclips. See Importing as a module for more information on the interface.

Programmatically

You can instantiate a Player by providing a HTML container, this will encapsulate the video player. The Player API allows you to load videos programmatically.

You must pass a video URI endpoint to Player.loadVideo. See Video Access for more information.

<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">
    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>

Importing as a module

You can use the boclips-player as a module in your JavaScript application.

interface PlayerFactory {
    get: (
        container: HTMLElement | string,
        options: Partial<PlayerOptions> = {}
    ) => Player;
}

interface Player {
    play: () => Promise<void>;
    pause: () => void;
    loadVideo: (videoUri: string, segment?: PlaybackSegment) => Promise<void>;
    destroy: () => void;
    getPlayerId: () => string;
    getOptions: () => Partial<PlayerOptions>;
}

interface PlayerOptions {
    analytics: Partial<AnalyticsOptions>;
    api: Partial<ApiOptions>;
    debug: boolean;
    interface: Partial<InterfaceOptions>;
}
import { PlayerFactory } from '../../src/index';

const tokenFactory = (): Promise<string> => {
    return fetch('your-service.com/token')
        .then(response => response.json())
        .then(data => data.token);
    };

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

    player.loadVideo('https://path.to.our/video/endpoint/1')
};

Authentication

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

The player takes a token factory which is responsible for generating a valid user token. We recommend the token factory sends a request to your backend service, that then handles getting a token from boclips.

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.

Player Options

The various modules within the player accept optional parameters to drive the behaviour of the player.

Interface Options

interface InterfaceOptions {
    controls: Controls[];
    addons: {
        seekPreview?: boolean | SeekPreviewOptions;
        hoverPreview?: boolean | HoverPreviewOptions;
        singlePlayback?: boolean | SinglePlaybackOptions;
    };
    ratio: '16:9' | '4:3';
}

type Controls =
  | 'play-large'
  | 'restart'
  | 'rewind'
  | 'play'
  | 'fast-forward'
  | 'progress'
  | 'current-time'
  | 'duration'
  | 'mute'
  | 'volume'
  | 'captions'
  | 'settings'
  | 'fullscreen';

interface SeekPreviewOptions {
    /**
     * Number of frames to retrieve for distribution over the length
     * of the video.
     *
     * Minimum: 10
     * Maximum: 20
     */
    frameCount: number;
}

interface HoverPreviewOptions {
    /**
     * Number of frames to retrieve for distribution over the length
     * of the video.
     *
     * Minimum: 4
     * Maximum: 15
     */
    frameCount: number;
    /**
     * Number of frames to retrieve for distribution over the length
     * of the video.
     *
     * Minimum: 200
     * Maximum: 1000
     */
    delayMilliseconds: number;
}

type SinglePlaybackOptions = boolean;

Playback Options

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

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 determines the video’s start and end time but does not prevent users from manually selecting other segments 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.

Boclips API 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>;
}

Analytics Options

interface AnalyticsOptions {
    metadata: { [key: string]: any };
    handleOnSegmentPlayback: (video: Video, startSeconds: number, endSeconds: number) => void;
}

Analytics

In order to gain insights into the way in which our users watch our curated videos, the player reports basic view stats back to our backend systems. This information helps us to personalise the Boclips experience in the long-term.

Detailed information on these tracking mechanisms may be gleaned by inspecting the source code of this project.

Where appropriate we will ask you to enrich these events with extra data. See Additional Metadata

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

Additional Metadata

To gain the best insights we ask that you provide extra data about the circumstance that this player is being used.

When initialising the player, you may pass metadata into the analytics module. For example, what user is watching the video:

const options = {
    analytics: {
        metadata: {
            userId: user.id
        }
    }
}

const player = Boclips.PlayerFactory.get(document.querySelector('#player-container'), options);
player.loadVideo(video);

All analytics data should be anonymised.

License

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

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