JavaScript

The Red Bee Media Managed OTT JavaScript SDK enables the customer to implement, in their own HTML and JavaScript environment, a simple JavaScript module to authenticate and play content against the Red Bee platform as well as implement the analytics to later on get reports on the consumption of their end users behavior and experience.

Installation

The simplest way to install the SDK is to use npm and install the all inclusive package including all our modules that you might need for implementing the player as well as enhancing the experience over the basic playback.

npm install redbee-javascript-player

Usage

The SDK can be used from the simplest used case out of the box, with a great default, to more complex use cases building your skin and applying multiple of our modules.

Getting Started

This example will cover most of the your needs and is a great base to start at.

Set up the wrapper element in which the player will render

  <div id="video-wrapper"></div>

Then in your JavaScript. If you already have a sessionToken since before the username and password can be changed for a sessionToken property. See Available Player Options

import { RedBeePlayer } from "redbee-javascript-player";
import "redbee-javascript-player/style.css";

const options = {
  customer: "DemoCustomer",
  businessUnit: "DemoBusinessUnit",
  username: "MyEndUser",
  password: "MyPassword123",
  exposureBaseUrl: "" // Provided by Red Bee Media,
  wrapper: "div#video-wrapper",
  assetId: "e720d1da-0915-411b-807c-3e83f451bbb7_29C72F",      
}
const redBeePlayer = new RedBeePlayer(options);
try {
  const { playerInstance, moduleInstances } = await redbeePlayer.create();
} catch (e) {
  console.error(e);
}

To log events from the player, that you may act on

import { PlayerEvents } from "redbee-javascript-player";

player.addEventListener(PlayerEvents.ALL, (event, data) => {
  const eventName = Object.keys(PlayerEvents).find((key) => PlayerEvents[key] === event);
  console.log(`[Red Bee Player] ${eventName}`, data);
});

Authentication

If you just need to get a sessionToken for other authorization required scenariros (such as personalized calls against the Exposure API) there is an exposed service to be used. The ExposureService.

First, get an instance of the Exposure service set up.

import { ExposureService } from "redbee-javascript-player";

const exposureService = new ExposureService({
  customer,
  businessUnit,
  exposureBaseUrl
});

Then authenticate to get the session token.

const { sessionToken, deviceId } = await exposureService.authenticate({
  username,
  password
});

If you want to create an anonymous session your can either call the authentication method without username and password

const { sessionToken, deviceId } = await exposureService.authenticate();

Or you can directly call the method authenticateAnonymous

const { sessionToken, deviceId } = await exposureService.authenticateAnonymous();

Available Player Options

Required

  • customer
  • businessUnit
  • exposureBaseUrl
  • wrapper
  • assetId (source available for free third party streams)

For playback from the Red Bee platform you will need either

  • sessionToken

or

  • username
  • password

If you initiate the player with a sessionToken instead of credentials, you can choose to provide a deviceId to align the analytics session with your definition of the user's device in other contexts of your application.

Optional

  • autoplay, default true
  • muted, default false
  • preferredFormats, default ["hls", "dash"]
  • limitedMemory, default false
  • ads, default undefined;

Ads options

export interface IAdsOptions {
  latitude?: string;
  longitude?: string;
  mute?: boolean;
  consent?: string;
  deviceMake?: string;
  ifa?: string;
  gdprOptin?: boolean;
}

Modules

More than the basic implementation, we have a set of modules that is available to apply. These are exposed as an enum

export enum PlayerModules {
  KeyboardShortcuts, // enabled default
  Analytics, // enabled default
  Skin, // enabled default
}

and can be implemented as including in the instantiation according to Getting Started

e.g.

import { RedBeePlayer, PlayerModules } from "redbee-javascript-player";

const redBeePlayer = new RedBeePlayer(options);
const { playerInstance, moduleInstances } = await redbeePlayer.create({
  modules: [
    PlayerModules.Analytics,     
  ],
});

So to initiate without any modules enabled

const { playerInstance } = await redbeePlayer.create({
  modules: [],
});

Keyboard Shortcuts

Shortcuts enabled by default

export const KeyboardShortcuts = {
  TOGGLE_PLAY: "space",
  FORWARD: "right",
  BACKWARD: "left",
  VOLUME_UP: "up",
  VOLUME_DOWN: "down",
  TOGGLE_MUTE: "m",
  TOGGLE_FULLSCREEN: "f",
};

Analytics

Analytics will automatically connect to the Red Bee Platform to send Analytics according to the backend expectation enabling you as a customer to dive deep into the data of your end user's consumption behavior.

Skin

Enables our basic skin that creates a great default experience for everything from VOD to Live and Channels.

It also brings some functionality in terms of showing Metadata related to the ongoing asset as well as possibility to AirPlay or Cast your content to big screen.

Methods

These are the methods exposed on the player instance received when initiating a player.

Contextual data

  • getPlayerInfo, fetches player engine and its version
  • getSession, fetches assetId, sessionToken, playSessionId, requestId and the player engine data mentioned above.
  • getAssetInfo, fetches the asset object for the currently playing asset
  • getContractRestrictions, fetches the restrictions that might exist for timeshift etc (see contract restrictions object)
  • getWrapperElement, get the wrapper element in which the player is rendered. Any skin or overlay should probably be rendered into this wrapper element.
  • getContainerElement
  • getState (see state object)

Set data or trigger behavior

  • play, starts playback
  • pause

  • setMuted true|false

  • toggleMuted
  • toggleFullscreen
  • seekTo({ time?: number, change?: number }, seek to either a specific time or a change back or forth in seconds.
  • seekToOffset, alias for seekTo with change
  • seekToLive, alias for seekTo with seekable end as time argument
  • setAudioLanguage(language: string)
  • setSubtitle(language: string)
  • setVolume({ percentage }

Get data or state

  • getSeekable
  • getCurrentTime
  • getVolume
  • getAudioLanguage
  • getAudioLanguages
  • getSubtitleLanguage
  • getSubtitles

  • isLive

  • isPlaying

  • destroy, kill the player

Contract Restrictions Object

export interface IContractRestrictions {
  airplayEnabled?: boolean;
  ffEnabled?: boolean;
  maxBitrate?: number;
  maxResHeight?: number;
  minBitrate?: number;
  rwEnabled?: boolean;
  timeshiftEnabled?: boolean;
}

State Object

export interface IPlayerState {
  state: State;
  volume: number;
  subtitles: any[];
  subtitle: string | null;
  audioLanguage: any;
  audioLanguages: any[];
  isMuted: boolean;
  isLive: boolean;
  contractRestrictions?: IContractRestrictions;
  hasStarted: boolean;
}

Events

To listen on events from the player you can add an event listener to the player instance, e.g

player.addEventListener(PlayerEvents.ALL, (event, data) => {
  const eventName = Object.keys(events).find((key) => events[key] === event);
  console.log(`[Red Bee Player] ${eventName}`, data);
});

available events

export enum PlayerEvents {
  ALL = "*",
  PLAY = "player:play",
  PAUSE = "player:pause",
  STOP = "player:stopped",
  START = "player:start",
  RESUME = "player:resume",
  PLAYING = "player:playing",
  SEEKING = "player:seeking",
  SEEK_TIME_CHANGE = "player:seek_time_change",
  SEEKED = "player:seeked",
  TIME_UPDATE = "player:timeupdate",
  ENDED = "player:ended",
  VOLUME_CHANGE = "player:volumechange",
  ERROR = "player:error",
  LOADING = "player.loading",
  LOADED = "player:loaded",
  BUFFERING = "player:buffering",
  BUFFERED = "player:buffered",
  ID3 = "player:id3",
  BITRATE_CHANGED = "player:bitrate_changed",
  CDN_CHANGED = "player:cdn_changed",
  AUDIO_CHANGED = "player:audio_changed",
  SUBTITLE_CHANGED = "player:subtitle_changed",
  LICENSE_EXPIRED = "player:license_expired",
  DROPPED_FRAMES = "player:dropped_frames",
  DRM_UPDATE = "player:drm:update",
  STATE_CHANGED = "player:state_changed",
  PROGRAM_CHANGED = "player:program_changed",
  NOT_ENTITLED = "player:not_entitled",  
}

Error handling

Error can thrown, and catched, either from the asynchronous initiation process or during playback.

The first one can be catched through a try catch, e.g.

const redBeePlayer = new RedBeePlayer(options);
try {
  const { playerInstance, moduleInstances } = await redbeePlayer.create();
} catch (e) {
  console.error(e);
}

The latter can be catched on the error event mentioned above The data object in such scenario is structured in the following way

class PlayerError {
  error: string;
  code?: number;
  originalError?: string;
  message: string;
};

Where the error property will be a concatination of error group and error type according to the pattern ErrorGroup [ErrorType] from respective exported enums.

export enum ErrorGroups {
  INIT = "INIT",
  USER = "USER",
  API = "API",
  PLAYER = "PLAYER",
}

export enum ErrorTypes {
  GENERIC = "generic",
  OPTIONS = "init_options",
  API_AUTH = "auth_failed",
  API_AUTH_ANON = "auth_anon_failed",
  API_PLAY_REQUEST = "play_request_failed",
  API_ASSET = "asset_request_failed",
  DRM = "drm_error",
  NETWORK = "network_error",
  STREAM_NOT_AVAILABLE = "stream_not_available",
  STREAM_LIMIT = "stream_limit_reached",
  NOT_AUTHENTICATED = "session_not_authenticated",
  NOT_AUTHORIZED = "unauthorized",
  GEO_LOCATION = "geolocation",
  MANIFEST = "manifest_error",
  SEGMENT = "segment_error",
  MEDIA = "media_error",
  CODEC = "codec",
  PLAYER_ENGINE = "generic_playerengine_error",
  UNSUPPORTED_DEVICE = "unsupported_device",
  UNSUPPORTED_SCREEN = "unsupported_screen",
  OTHER = "other_error",
}