Skip to content


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.


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 @redbeemedia/javascript-player

If you rather prefer to include the JavaScript from a CDN or download the files to be included in your project, you may include the files from the jsdelivr cdn or unpkg cdn

From jsdelivr

<script src=""></script>

<link rel="stylesheet" href="">

or from unpkg

<script src=""></script>

<link rel="stylesheet" href="">     


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 "@redbeemedia/javascript-player";
import "@redbeemedia/javascript-player/style.css";

const playerOptions = {
  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 player = new RedBeePlayer({ player: playerOptions });
player.load().catch((e) => {

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

import { PlayerEvents } from "@redbeemedia/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);

If you are including the player sdk from a cdn, all exports is set on the redBeeMedia object, to keep the global scope a little bit cleaner. I.e. instead of just RedBeePlayer you'll have to call redBeeMedia.RedBeePlayer


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 "@redbeemedia/javascript-player";

const exposureService = new ExposureService({

Then authenticate to get the session token.

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

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 Options

There are four different option categories player, skin, analytics && keyboard these are provided as separate objects when initializing the player.

new RedBeePlayer({
  player: { /* player options here */}
  skin: { /* skin options here */}
  analytics: { /* analytics options here */}
  keyboard: { /* keyboard options here */}

Player options, player


  • customer
  • businessUnit
  • exposureBaseUrl
  • wrapper

One of

  • assetId
  • externalAssetId, if configured to be used instead of the one from our platform
  • source, third party stream
  • playlist, a playlist of sources or assetIds in the following format [{ assetId: "<id here>", source: "<source here>"}] see playlist

For playback from the Red Bee platform you will need either

  • sessionToken


  • 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. This will otherwise be pulled from the token or auto generated.

If you initiate the player without credentials, nor sessionToken, the SDK will automatically try to do an anonymous login towards the platform.


  • autoplay, default true
  • muted, default false
  • preferredFormats, default ["hls", "dash"]
  • limitedMemory, default false
  • ads, default undefined
  • debug, default false, which rather log analytics into the console than sending it to the backend.
  • locale, the language to use for metadata when casting & for the browser MediaSession.
  • castAppId, defaults to the default unbranded RBM receiver.
  • disableCast, default false
  • disableAirPlay, default false
  • playlist, see playlist
  • fullscreenElement, the element that goes to fullscreen when pressing the fullscreen button, defaults to wrapper. Usable when you want to apply further elements in the full screen experience.
  • audioOnly, default false, will play an audio stream without any video being played.
  • poster, image to be used when autoplay is blocked or during playback of audio only sources.
  • maxResolution. Use this to filter out specific variants. Note that this requires a backend configuration for your organization, reach out to your Red Bee representative for help.
  • materialProfile, Use this to play a specific material variant.
  • metadataURIs, For MPEG-DASH streams, this is a list with the EventStream schemeIdURIs. Use this to expose one or more timed metadata events when present.
  • customShakaConfiguration, see shaka api documentation
  • customHlsJsConfiguration, see hls.js api documentation
  • customDashJSConfiguration, see dash.js api documentation

With v0.16.0 we've introduced simple support for a playlist using the new option playlist. This option is an array of items in the following format [{ assetId: "<id here>", source: "<source here>"}], if an assetId or source is provided as well it will be added to the beginning of the playlist.

Once an item has finished playing completely the next item will automatically start, this is currently the only feature of the playlist but we're evaluating additional features so please contact your RBM representative to provide feedback.


If the user is casting or airplaying the playback will stop on the device and continue in the browser when a new item starts.

Ads options

export interface IAdsOptions {
  uid?: string;
  latitude?: string;
  longitude?: string;
  mute?: boolean;
  autoplay?: boolean;
  consent?: string;
  deviceMake?: string;
  deviceType?: TAdDeviceType;
  ifa?: string;
  gdprOptin?: boolean;
  width?: number;
  height?: number;
  pageUrl?: string;
  domain?: string;
   * These custom parameters will be added to the querystring of the play request.
   * e.g. ?customParam1=value1&customParam2=value2 etc
  [key: string]: any;

Skin Options, skin

Our basic skin 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.

If you want to use it there are some additional settings available to adjust its behavior.


const redbeePlayer = new RedBeePlayer({
  player: { ... },
  skin: {
    disabled: true 

Available settings

  • disabled, default false. Set to true to disable the default skin
  • hideControlsTimer, default 2500. How many milliseconds until the skin hides when there's no activity.
  • showMetadata, default true. Whether to show the image, title, duration and description for the ongoing asset.
  • showQualitySelector, default true. Whether to show the quality selector or just go by auto quality selection.
  • showJumpButtons, default true. Whether to show buttons that allows the end user to jump back and forth 30 seconds in the stream.
  • allowPictureInPicture, default true.
  • locale, default en.
  • showWallClock, to show wall clock rather than zero based when applicable data is available. Will default to the client's timezone.
  • timeZone, to have a set timezone for the wall clock timestamp to be shown. (The tz database name standard, e.g. Europe/London)

Keyboard Shortcuts, keyboard

Keyboard shortcuts to allow users to control the player using their keyboard.

These are the currently available shortcuts:

  • Spacebar: Toggle play/pause
  • Right Arrow: Forward 15 seconds
  • Left arrow: Rewind 15 seconds
  • m: Toggle mute/unmute
  • f: Toggle fullscreen/window

Available settings

  • disabled, default false. Set to true to disable keyboard shortcuts.

Analytics, 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.

Available settings

  • disabled, default false. Set to true to disable analytics. NOTE! This is not recommended and should only be done if you understand the consequences.
  • analyticsBaseUrl, default set to the value of exposureBaseUrl set as player options. For some big events Red Bee will distribute a custom analytics base url for scaling purpose.
  • appName. To be used when you have multiple applications that will be reported to the same analytics bucket.


Contextual data

  • getPlayerInfo, fetches player engine and its version
  • getSession, fetches assetId, sessionToken, playSessionId, requestId etc. (see session object)
  • 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
  • getVideoElement
  • getState see state object
  • getTimelineSpriteCues see Timeline SpriteCues

Set data or trigger behavior

  • load({ assetId?: string, src?: string, startTime?: number }), this will kill the current session and create a new one with the provided asset or src.
  • 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
  • seekToUTC(utcTime: number), seek to a time in UTC given in milliseconds since epoch
  • seekToLive, alias for seekTo with seekable end as time argument
  • setPlaybackRate
  • setAudioTrack(track: ITrack)
  • setSubtitleTrack(track: ITrack)
  • setQualityLevel(level: IQualityLevel)
  • setVolume({ percentage } set volume to a percentage between 0 and 100, this is not supported on iOS devices. See Apple Developer website
  • togglePictureInPicture
  • toggleAirPlay

Get data or state

  • getSeekable
  • getCurrentTime
  • getVolume
  • getAudioTrack
  • getAudioTracks
  • getSubtitleTrack
  • getSubtitleTracks
  • getQualityLevels

  • isLive

  • isPlaying
  • isPictureInPictureSupported, check if PiP is supported, currently works on later version of Chrome & Safari
  • isPictureInPicture
  • isAirplaySupported, check if AirPlay is supported, currently works on Safari.
  • isAirplaying

  • isBrowserSupported, might be used by your site to check whether this is a user that we will be able to officially support or not.

  • destroy, kill the player

Session Object

export interface IPlayerSession {
  assetId?: string;
  initOptions?: IPlayerCoreOptions;
  sessionToken?: string;
  playSessionId?: string;
  requestId?: string;
  playbackFormat?: FormatType;
  playerEngine: IPlayerEngine;
  cdnProvider?: string;
  analyticsPostInterval?: number;
  analyticsBucket?: number;
  analyticsTag?: string;

Contract Restrictions Object

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

State Object

interface IPlayerState extends IInternalPlayerState {
  isCasting: boolean;
  isCastAvailable: boolean;
  isAirPlaying: boolean;
  isAirPlayAvailable: boolean;
  contractRestrictions?: ContractRestrictions;
  contentMarkers?: MarkerPoint[];

interface IInternalPlayerState {
  state: State;
  contentType?: ContentType;

  currentTime: number;
  duration: number;
  seekable: ISeekable;

  utcCurrentTime: number;
  utcDuration: number;
  utcSeekable: ISeekable;

  adMarkers?: IAdBlockMarker[];

  contentMarkers?: MarkerPoint[];

  volume: number;

  subtitleTrack: ITrack | null;
  subtitleTracks: ITrack[];

  audioTrack: ITrack;
  audioTracks: ITrack[];

  qualityLevel: IQualityLevel;
  qualityLevels: IQualityLevel[];

  droppedFrames: number;
  bufferingEvents: number;

  hasStarted: boolean;
  isMuted: boolean;
  isLive: boolean;
  isSeekable: boolean;
  isAtLiveEdge: boolean;

enum State {
    IDLE = "idle",
    LOADING = "loading",
    PLAYING = "playing",
    PAUSED = "paused",
    BUFFERING = "buffering",
    SEEKING = "seeking",
    ENDED = "ended",
    ERROR = "error"

enum ContentType {
    VOD = "vod",
    LIVE = "live",
    AD = "ad",
    PODCAST = "podcast"

interface ISeekable {
  start: number;
  end: number;

interface IAdBlockMarker {
  startTime: number;
  duration: number;
  watched: boolean;

interface ITrack {
  id: string;
  language: string;
  label: string;

interface IQualityLevel {
  id: number;
  name?: string;
  bandwidth?: number;
  width?: number;
  height?: number;
  framerate?: number;

Timeline SpriteCues

The method getTimelineSpriteCues is used to get an array of SpriteCues which are objects describing a sprite within a spritesheet that represents the playing content at a specific time.

This is used to in the included skin to show thumbnails above the progressbar when seeking.

The SpriteCue object looks like this

interface ISpriteCue {
  image: string; // URL to the spritesheet image
  start: number; // The first second on the timeline that this SpriteCue represents
  end: number; // The last second on the timeline that this SpriteCue represents
  dimensions: {
    x: number; // The X coordinate in the spritesheet of the sprite, in px
    y: number; // The Y coordinate in the spritesheet of the sprite, in px
    width: number; // The width of the sprite, in px
    height: number; // The height of the sprite, in px

The size of the sprites varies depending on content. By default getTimelineSpriteCues will look for Sprites that are as close as possible to a quarter of the width of the player, the most common size available is 160px wide.


Only VOD assets have SpriteCues.


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(PlayerEvents).find((key) => PlayerEvents[key] === event);
  console.log(`[Red Bee Player] ${eventName}`, data);

If you want to add type information to the event handler you can use a type variable. You currently need to manually create the handlers, in the future these will be provided for you

player.addEventListener<(data: IPlayerState) => void>(
  (data) => {
    // data will now have the type IPlayerState

available events when not casting

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",
  LOAD_START = "player:load_start",
  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",
  BLACKOUT = "player:blackout",
  EMPTY_SLOT = "player:empty_slot",
  CAST_START = "player:cast:start",
  CAST_STOP = "player:cast:stop",
  AIRPLAY_START = "player:airplay:start",
  AIRPLAY_STOP = "player:airplay:stop",
  AD_START = "player:ad:start",
  AD_COMPLETE = "player:ad:complete",
  ADBLOCK_START = "player:adblock:start",
  ADBLOCK_COMPLETE = "player:adblock:complete",
  INTRO_START = "player:intro:start",
  INTRO_END = "player:intro:end",
  CHAPTER_START = "player:chapter:start",
  CHAPTER_END = "player:chapter:end",
  MARKER = "player:marker",
  METADATA_EVENT = "player:metadata_event",
  SESSION_ACQUIRED = "player:session_acquired",
  PLAYER_SETUP_COMPLETED = "player:setup_completed",
  ENTITLEMENT_GRANTED = "player:entitlement_granted",

available events when casting

export enum PlayerEvents {
  ALL = "*",
  STATE_CHANGED = "player:state_changed",
  PROGRAM_CHANGED = "player:program_changed",
  CAST_START = "player:cast:start",
  CAST_STOP = "player:cast:stop",

Timed metadata events

The player will emit a METADATA_EVENT when a EXT-X-DATERANGE tag is encountered in the HLS manifest. Similarly, the player will emit a METADATA_EVENT when a period with an EventStream schemeIdUri appears in the schema that matches the metadataURIs that can be set in the Player options. Important to note is that if the metadataURIs is set to an empty list, the player will emit all events that appear in the MPEG-DASH stream. if the metadataURIs option is not set the player will not emit any METADATA_EVENT events.

The event will have the following properties:

interface IMetadataEvent {
  event: any; // The event
  engineName: string; // The name of the player engine that generated the event
  engineVersion?: string; // The version of the player engine that generated the event

Depending on the engine type the event will have different properties. The default behavior of the player is to prioritize the use of the MPEG-DASH stream when available over the HLS stream for non Safari browsers.

For HLS on non Safari browsers the event will be a list with the following properties:

engineName: "Hls.js"
engineVersion: "1.1.5"
event: [

For HLS on Safari browsers the event object will have the following properties:

engineName: "Native HTML Video"
event: [
  DataCue {
    data: null,
    value: {key: "X-COM-DAICONNECT-TRACK", data: "abc1234"},
    type: "",

For MPEG-DASH the event object will have the following properties: See: for more information.

engineName: "Shaka Player"
engineVersion: "v4.1.2"
event: {
  endTime: 1661864509.842636
  eventElement: Event, // The event with the tracking elements
  schemeIdUri: "urn:daiconnect:dai:2019:xml",
  startTime: 1661864509.842636,
  timeStamp: 870455.3000000119,
  type: "timelineregionenter",
  seekable: {start: 1661863914.943625, end: 1661864514.943625},
  utcCurrentTime: 1661864514572.273,
  utcDuration: 1661864519445.625,
  utcSeekable: {start: 1661863919445.625, end: 1661864519445.625},

Player Cue Points

The asset may contain an array of MarkerPoints. Depending on the type of Marker, it gets treated differently:

A marker of type INTRO will trigger PlayerEvents of either INTRO_START or INTRO_END. The trigger PlayerEvents.INTRO_START will, as part of the SDK player, present a button inside the video element containing a skip icon and whatever title is given to the intro marker. This button give the user an option to skip the intro marker duration and seek to the endOffset of the intro marker, if clicked.

Similarly, a marker of type CHAPTER will trigger PlayerEvents of either CHAPTER_START or CHAPTER_END. However, these events are not presented to the endusers as a button but are merely there as a convenience for third party skins to take action on. If present, marker of type CHAPTER does however get listed in the Content Marker Menu, next to Settings, where if clicked will seek the user to the starttime, i.e. offset of said Chapter. In this list, whatever title is given to the content marker is presented next to the time of the content marker offset.

A marker of type POINT, does not have an endOffset. These are simply a point of interest in time. i.e a goal in a fotball game. These markers are, similarly to markers of type CHAPTER, presented in the Content Marker Menu of the video element and, if clicked, will seek the user to that point in time. Whatever title is given to the content marker is presented next to the time of the content marker offset. Marker of type POINT triggers a PlayerEvent of type MARKER so that third party skins can take action on it.

Lastly, a marker of type CREDITS does not, like POINT, hold an endOffset. They are also simply a point of interest in time, but can be used to trigger events like "Push Next Content" or "Watch Next" suggestions. They are also available on PlayerEvents.Marker but are not presented in the list of Content Markers in the Content Marker Menu.

On all PlayerEvents, the actual content marker is available so that developers can do additional checks of type, offset etc.

enum MarkerType {
    INTRO = "INTRO",
    POINT = "POINT",

class MarkerPoint extends WithLocalized {
    offset: number; //start point in millisecond
    endOffset?: number; //end point in milliseconds, omitted in MarkerType "POINT" and "CREDITS"
    type: MarkerType;

If you do not want to listen to the different PlayerEvents, or need the markers up front to show an index or mark on the timeline, all available content markers are exposed on playerState.contentMarkers. If there are no content markers on the specific asset, playerState.contentMarkers will return an empty array.

As you may have multiple intros, for example one being recap and the other being the actual intro, a state of the active intro marker is exposed on metadata.activeIntro. This will default to null if there is no active Intro at that point in time.

the skip intro button is visible for 2.5 times the time set for settings.hideControlsTimer. If omitted, the button gets hidden after 7 seconds.


Chromecast support is enabled by default using the default unbranded RBM receiver.


The player will include the Google Cast API library if needed, do not manually include that script on your site.

Custom skin

To implement chromecast support in your custom skin please use the google-cast-launcher webcomponent, more information is available here.

If you want to build a custom cast button please contact your RBM representative.

Custom receiver

To build a custom receiver follow the instruction here


Do you want to customize the subtitle style? Simply override the CSS for the CSS class .redbee-player-skin-container and the <span> elements within it. .redbee-player-skin-container contains all the subtitle cues and by default covers the screen. Each <span> element represent a subtitle cue, there is usually just one.

Example SCSS

.redbee-player-subtitle-container {
  span {
    // show a background under the subtitle cues.
    background: rgba(0, 0, 0, 0.5);
    border-radius: 0.5em;
    padding: 0.5em;


The WebVTT spec is a living standard, and therefore will have partial support in browsers and player engines. We try to work around this and support as much of the spec as we can, but it's not possible for us to support all subfeatures of styling and positioning for all engines and browsers.

Error handling

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

The first one can be catched through a async await, e.g.

const player = new RedBeePlayer(options);
try {
  await player.load();
} catch (e) {

or as a promise chain

const player = new RedBeePlayer(options);
player.load().catch((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 concatenation 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",

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

Release Notes

v0.57.0 (15 Nov 2022)

Features - Stream metadata is now included in the payload in the Mux Data plugin.

v0.56.1 (15 Nov 2022)


  • Better visibility of buffering events in player analytics.
  • A couple of new player events have been added these are: SESSION_ACQUIRED, PLAYER_SETUP_COMPLETED, ENTITLEMENT_GRANTED.

Bug fixes

  • Fixed loading event not being emitted on certain live to vod assets.

v0.56.0 (7 Nov 2022)


  • Add LOAD_START event

v0.55.1 (28 October 2022)

Bug fixes

  • Fixed issue where PLAYER_READY event not triggering in some scenarios.

v0.54.1 (25 October 2022)


  • Add dropped frames to analytics events.

v0.53.1 (19 October 2022)

Bug fixes

  • Fixed an issue where the player UI wouldn't properly show selected audio tracks when using the Shaka Player engine.
  • Fixed an issue where ads could be skipped on iOS 16 and Safari.

v0.53.0 (17 October 2022)


  • Added support for subtitle positioning.

Bug fixes

  • Fixed Shaka player removing subtitle color data.
  • Fixed subtitles auto-selecting for hls.js
  • Support multiple subtitle/caption tracks with the same language if the kind differs.

v0.52.0 (21 September 2022)


  • Added method seekToUTC. See Methods.

Bug fixes

  • Check for metadataURIs in initOptions.

v0.51.0 (13 September 2022)


Bug fixes

  • Set heartbeat depending on the analyticsPostInterval setting. This will make sure that the heartbeat event from the player is sent at the correct interval.

v0.50.1 (6 September, 2022)

Bug fixes

  • Better subtitle handling on dashjs and ssai streams
  • Upgrade shaka player
  • Fix bug in progressive download of .mp3 sources.

v0.49.2 (29 June, 2022)

Bug fixes

  • SSAI support on LG Smart TV 2017-2019.
  • Adjusted the minimum dvr window threshold for when the player considers live-streams seekable.
  • Subtitle fixes for SSAI streams.

v0.48.0 (13 June, 2022)


  • New player option locale added. Used to determine asset locale when casting and for the MediaSession metadata.

v0.47.1 (7 June, 2022)

Bug fixes

  • Default Subtitle styling not included in the exported css.

v0.47.0 (23 May, 2022)


v0.46.0 (13 May, 2022)


Bug fixes

  • Line height adjustments on multiline subtitles
  • Minor adjustments to ad counter terminology

v0.45.0 (10 May, 2022)


  • Ad Countdown
  • Full player area clickthrough on ads

Bug fixes

  • Adjusted subtitle default size on mobile
  • Infinite buffering on live SSAI
  • Multiple ad impression tracking url's
  • Send first analytics dispatch asap, instead of after set analytics interval
  • Render subtitles with line breaks

v0.43.0 (22 March, 2022)


  • Subtitles are now customizable, see the docs

Bug fixes

  • Subtitles sometimes not showing in firefox

v0.42.0 (22 March, 2022)


  • Enriched payload to analytics (incl page url, referrer, app name)

Bug Fixes

  • Hardening to event pool dispatch on page close
  • Analytics heartbeat vs dispatch fixes
  • Use duration in milliseconds, instead of microseconds, for bookmarks

v0.41.0 (22 February, 2022)


  • Max resolution as init option
  • Support for custom engine configuration (Please read public documentation for Shaka, Hls.js and Dash.js)

Bug Fixes

  • Typescript signature to signal null as valid data in subtitle methods (to disable subtitle)
  • SSAI loaded and start tracking
  • Reset playbackrate to 1, during ads
  • Pause ad playback on visibility hidden

v0.40.0 (26 January, 2022)


  • Live delay (distance from edge) support on drm free hls live events
  • Exposing media type (video vs audio) in player state

Bug fixes

  • Improve cleanup of chromecast analytics
  • Fix for custom analytics endpoint
  • Live delay on dash live events
  • Report manual bitrate changes, through bitrate selector, to analytics
  • Improve subtitle rendering

v0.38.0 (7 December, 2021)


  • Click through on ads

Bug fixes

  • Better error communication on casting
  • Minor Analytics fixes
  • Minor fixes to playback of SSAI Dash streams

v0.37.1 (6 October, 2021)


  • Support the default WebVTT color classes
  • TypeScript: interface IPlayerState is now exported
  • TypeScript: event handlers can now be typed. See Events

Bug fixes

  • Fix quality levels not being sorted.

v0.36.0 (22 September, 2021)


  • Support content markers on assets
  • Support playlists when AirPlaying
  • Support for encrypted SSAI
  • Selected subtitle and audio track languages is stored between sessions

Bug fixes

  • Retaining cast session between playlist content
  • Seek to 0 did not work
  • FPS included in quality level labels when applicable

v0.32.0 (25 August, 2021)


  • Support SSAI VOD content

Bug fixes

  • Fix some Huawei phones not playing encrypted content.
  • Fix mobile skin not toggling on touch
  • Improved stability when embedding the player using an iframe.


  • Player version number is now aligned with internal versions for simpler follow up on analytics sent in.

v0.18.8 (10 August, 2021)


  • Expose dropped frames & number of buffering events in the state object

Bug Fixes

  • Fix player going to loaded state before finishing loading in chrome & firefox.
  • Fix player not throwing an error event when DRM errors occur during startup.

v0.18.7 (14 July, 2021)

Bug Fixes

  • Support for sprite offset, to get them right in trimmed videos.
  • Fix for preferred keysystem to go outside our definition of supported formats for a browser.

v0.18.5 (7 July, 2021)

Bug Fixes

  • Preview thumbnail will now always be constrained to be viewed inside the player wrapper.
  • Solved a rare issue with Fairplay encryption in Safari, not being able to fetch the license.

v0.18.4 (2 July, 2021)


  • Support for preferring a set keysystem for encrypted videos, overriding the default. (Should not be used without knowledge about its impact)
  • Possible to set Poster image

Bug Fixes

  • Don't pause on single tap on touch devices, when skin should be shown.
  • Desktop will always use full skin, not mobile skin, whatever size of the video element.


  • Hover effect on buttons in the skin
  • Background color on the time text while hovering the timeline, to now conflict visually with the buttons.

v0.18.3 (9 June, 2021)


Bug Fixes

  • Minor initial entry delay on the skin to avoid falsy initialization visualization
  • Require a proper deviceId to be sent in for analytics to work, as this was either way blocked in the backend.


  • Changed the buttons for jumping backward and forward to jump 10 seconds instead of 30, since it is easy to click multiple times for longer seeks.

v0.18.1 (24 May, 2021)


  • Support for dynamic analytics endpoint, analyticsBaseUrl, see analytics options.
  • Support for multiple audio and subtitle tracks for the same language, e.g. Audio description.
  • Ability to initiate the player in audio only mode, playing just the audio stream from an asset.

Bug Fixes

  • Check whether stream is seekable on live.
  • Disable HEVC if the decoder can't initialize.
  • Removing some forgotten event listeners on player destroy.


  • Bundled generated types for simpler SDK integration.

v0.17.3 (26 April, 2021)


  • Support for showing wall clock time instead of relative time, where applicable data is available.
  • Updated hls.js and Shaka engines.

Bug Fixes

  • Sprites not working
  • Cast sender not being destroyed due to reference error

v0.16.0 (7 April, 2021)


  • New simplified initialization (>> Breaking change <<)
  • Streaming Protocol and CDN Vendor included in Analytics and in session info (exposed by the getSession method)
  • Playlist support

Bug Fixes

  • Some minor Chromecast related fixes

This release introduces a single change which is a new and simplified player initialization.


const redBeePlayer = new redBeeMedia.RedBeePlayer(options, skinSettings);
const { playerInstance } = redBeePlayer.create().catch((e) => {

playerInstance.on(PlayerEvents.ERROR, () => { ... })


const redBeePlayer = new redBeeMedia.RedBeePlayer({ player: { ... },  skin: { ... } });
redBeePlayer.load().catch((e) => {
redBeePlayer.on(PlayerEvents.ERROR, () => { ... })

Read the documentation available here for more information. The old way is still supported but will removed in a future release, you simply need to change your import for it to work.


import { RedBeePlayer } from '@redbeemedia/javascript-player'


import { RedBeePlayerDeprecated } from '@redbeemedia/javascript-player'

v0.15.2 (30 Mar, 2021)


  • Possible to disable Airplay through init param disableAirPlay.
  • Airplay state exposed in the state object during playback.
  • Airplay state sent to Analytics.
  • Added external events for Airplay & Ads.

Bug Fixes

  • Skin timeline not showing correct span when the video lacked subtitle tracks.
  • Minor visual fixes in the skin.
  • Support for in manifest license url for Fairplay DRM.
  • Using ResizeObserver rather than a window resize listener for level cap in Shaka, as it is a more sensible approach.
  • Level cap in Shaka to meet contract restrictions set.

v0.14.1 (24 Mar, 2021)


  • Support for Adobe Primetime Token
  • Support for the new CAF Chromecast Receiver
  • Quality selector in the skin.
  • Buttons in the skin, to jump back and forth.
  • Possible to send in som skin settings into the sdk.

Bug fixes

  • Some minor fixes regarding metadata visualization
  • Some minor fixes regarding analytics.

v0.13.0 (2 Mar, 2021)


  • Timeline Sprites, in both SDK and in the skin.
  • SSAI tracking of Nowtilus SSAI streams.
  • Analytics always enabled. Enhanced with more data as well.

Bug fixes

  • Better PiP handling, closing PiP when player is destroyed.
  • Some minor fixes for Chromecast and Airplay.

v0.6.1 (19 Jan, 2021)


  • Mobile Skin
  • Possible to disable Cast through init param disableCast

Bug fixes

  • Fix for setMuted method
  • Fix for AirPlay of DRM content

< v0.6.0

  • Initial release to customers