Integration Guide for Bitmovin Mediaplayer

Introduction

This is a guide to help you integrate Streamlyzer plug-in for Bitmovin player to your service.

Supported browsers

Streamlyzer JavaScript plugin supports the following browsers:
– Chrome
– Internet Explorer ( version 7+)
– Firefox
– Safari

Streamlyzer supports the current and previous major release of Chrome, Internet Explorer, Firefox and Safari on a rolling basis. Each time a new version is released, we begin supporting that version.

Browser settings

All browsers must have cookies and JavaScript enabled to use Streamlyzer Plugin

Requirements

  • JSON3 library – Some of old version browsers do not support JSON implementation. In order to keeping a modern JSON implementation compatibility with a variety of JavaScript platform, JSON3 library is used for Streamlyzer JavaScript plug-in.
    Bitmovin library 4.0 or later

Observers and Properties

Overview

There are 4 types of events to track (aka Observer components),

  • playbackObserver for tracking media playback.
  • userDefinedObserver for tracking user defined events.
  • sharedContentObserver for tracking sharing contents.
  • pageReferrerObserver for tracking page referrer.

Prior to initialization of Observers, you need to set properties as it needs. For your convenience, we group them into 5 categories. Depending on which observers you use, some of properties are required and some of them could be optional.

  • Audience properties
  • Content properties
  • Service properties
  • Platform properties
  • Customer properties

Properties

Audience properties
Variables Default Required Description
userId ‘Unset’ O User Unique ID. You should specify user unique id for each users. It shall be unique string or e-mail address or user id. It should be unique string so that data can be grouped by user id.
userType ‘Unset’ User Type. You can define the type of user. For example, “free user”, “non-free user” or “premium”.
gender ‘Unset’ User’s Gender. For example, “male” or “female”.
yearOfBirth ‘Unset’ User’s year of birth. This is for calculating user’s age. For example, “1995”.
Content properties
Variables Default Required Description
thumbnailImage ‘Unset’ URL of thumbnail image. You can specify thumbnail image of the contents. This thumbnail url will be used for displaying thumbnail image on Dashboard
seriesName ‘Unset’ Series name of movie. You can define series name of asset. For example, “Heroes”, “House of Cards”
episodeName ‘Unset’ Season/Episode name of movie. User can define Episode information into log. For example, Season 1 Episode 10 shall be “S1:E10”.
liveChannelName ‘Unset’ Live channel Name. If the media is not a live channel, you can input the movie id.
movieId ‘Unset’ O Movie ID. The tile of movie. This should be unique string so that metrics will be grouped by movie id.
movieCategory ‘Unset’ O Movie Category. You can define unique key string for grouping movie category. For example, this value can be “drama”, “comedy”, “horror” or “anime”.
movieSubcategory ‘Unset’ Movie Subcategory. You can define unique key string for grouping movie subcategroy. For example, this value can be “romantic drama”,”crime drama”, classic drama” or “teen drama”.
movieContentsProvider ‘Unset’ Movie Content providers. User can define unique key string for grouping contents providers. For example, this value can be “abc”, “desiney”, “time wanner”, “kbs” and so on.
movieRate ‘Unset’ Movie Rate. You can define movie rate. For example, “R”, “PG-13”, “PG”
Service properties
Variables Default Required Description
live false O Is Live Service or not. If the service is Live, it shall be true, If not, it shall be false. For example, if the content is VOD, it shall be “false”.
serviceType ‘Unset’ Serivce Type. You can define the type of service. For example, “TV” or “Radio”.
sessionId ‘Unset’ O Session ID. You could set session id based on each session.
streamingServerName ‘Unset’ O You can specify streaming server URL or CDN urls. It can be used for metrics grouped by streaming edge.
abTestMark ‘Unset’ O A/B test mark. This for A/B testing. You can put “A” or “B” or other unique string for A/B testing.
Platform properties
Variables Default Required Description
playerPlatformVersion ‘Unset’ O Player Platform Version. You can define user specific version information to group data. For example, you can specify player version information such flash 7, flash 8
mediaPlayerVersion ‘Unset’ O Media Player Version. You can define user specific version information to group data. For example, you can specify player version information such as jwplayer 7.5, jwplayer 9.8
Customer properties
Variables Default Required Description
customerKey ‘Unset’ O Customer Key. This value is given by Streamlyzer. It is used for identifying logs you send. The log with invalid key value will be rejected.

Observers

playbackObserver

Description

Playback Observer will be attached with media player, and monitor playback event based on user’s interaction.

How to initialize

To initialize PlaybackObserver, you should do below three things.

  1. Set proper properties on creation of the Observer.
  2. Register callback for dynamic information.
  3. Add Event API for tracking media player.

First, provide all of the required properties and you can initialize the observer:


var playbackObserver;

playbackObserver = new szrpg.PlaybackObserver({
    // key provided by Streamlyzer
    customerKey : "<Key Provided by Streamlyzer>",

    // end user related properties
    userId : '<User ID>',
    userType : '<User Type>',
    gender  : '<User Gender>',
    yearOfBirth : '<User Year of Birth>',

    // service related properties
    serviceType : '<Service Type>',
    sessionId : "<Session ID>",
    streamingServerName : "<Streaming Server Name>",  /* Server name or source URL */
    abTestMark : "<AB Test Marking>",

    // contents related properties
    islive : boolean,
    seriesName : "<Series Name>",
    episodeName : "<Episode Name>",
    movieId : "<Movies ID or File Name>",
    movieCategory : '<Movie Category>',
    movieSubcategory : '<Movie Subcategory>',
    movieContentsProvider : '<Contents Provider>',
    movieRate : "<Movie Rating>",
    thumbnailImage : "<Movie Thumbnail Image>" , /* Thumbnail url */
    // ....register callback process

Event API

Function Signiture Description
onPlayerReady() It is called when the player is loaded and ready to playback. If this does not get called for 30 sec after client API instant is initiated, player load fail message will be sent.
onPlayerPlay() It is called when player is done with data buffering and starts to play (video and audio) or start to render video/audio. All buffering log will be sent when this function is called.
onPlayerSeek(position, offset) It is called when the viewer clicks & drags the progress bar of player (seek event).’position’ should be passed with millisecond time, ‘offset’ should be also. i.e. user seek from 1min 10s to 12min 30s, ‘onPlayerSeek(70000, 750000)’ should be called. And ‘position’, ‘offset’ should be Number, not String.
onPlayerPaused() It is called when player gets paused.
onBufferingStart() It is called when the player start buffering.
onPlayerComplete() It is called when playback has been completed.
onPlayerStop() It is called when playback is completely finished.
onPlayerBitrateChange(bitrate) It is called when delivering video bitrate changes. ‘bitrate’ should be sent with ‘kbps’ unit. for instance, the bitrate change to ‘512kbps’, ‘onPlayerBitrateChange(512)’ should be called. And ‘bitrate’ should be Number, not String.
onPlayerErrorMessage(message) It is called when getting playback error, any your defined error, or buffering time limit exceeded. Streamlyzer will count the number of errors or categorize errors with error message. error message has to be passed as the argument ‘message’.
onChangeChannel(options) It is called when channel is changed. ‘options’ is an object that has configuration options mentioned above.

Callback API

Note that these API have to be called by the application (e.g: media player or HTML5 player) explicitly. If you don’t implement this callback, the default value will be used in plug-in.

Function Signiture Default Return Description
cbGetBitrate 0 If there is any bitrate or video quality info available, this has to return current video bitrate in kbps (kilobits per seconds). For example, if current bitrate is “256kbps”, you should return “256”. The return value should be Number, not String.
cbGetPosition 0 It gets called to get the current position of media file. It can be the absolute position in millisecond unit. The return value should be Number, not String.
cbGetBuffer 0 It returns buffering rate as number(0~100) The return value should be Number, not String.
cbGetDuration 1 It returns the total length in millisecond of the viewed media file. The return value should be Number, not String.
cbGetResolution ‘Unset’ It returns video resolution. Display resolutions. For example, “720×480”, “360×240”, “1080×900”, “720p”, “1080p”, “480p”

Example

Here is full example with Bitmovin player.


var player;
var playbackObserver;

// to detect bitrate changes
var prevBitrate = -1;

// to save last position
var lastTimeStamp = 0.0;

// to save last playback status
var isLastStatePaused = false;

// to calculate bitrate in Kbs
function getCurrentBitrate()
{
    return Math.floor((parseInt(player.getPlaybackVideoData()['bitrate'])
            + parseInt(player.getPlaybackAudioData()['bitrate'])) / 1024);
}

/**
 *  Mapping Player Event to Plug-in
 */
  var conf = {
    key:              'YOUR-BITDASH-PLAYER-KEY',
    source: {
      dash:        '//bitdash-a.akamaihd.net/content/MI201109210084_1/mpds/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.mpd',
      hls:         '//bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8',
      progressive: '//bitdash-a.akamaihd.net/content/MI201109210084_1/MI201109210084_mpeg-4_hd_high_1080p25_10mbits.mp4',
      poster:      '//bitdash-a.akamaihd.net/content/MI201109210084_1/poster.jpg',
      tracks: [{
        file: 'https://bitdash-a.akamaihd.net/content/MI201109210084_1/thumbnails/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.vtt',
        kind: 'thumbnails'
      }]
    },
    style: {
      width:          '100%',
      aspectratio:    '16:9',
      controls:       true
    }
        , events: {
                onReady : function() {
                        // to notify player ready state
                        playbackObserver.onPlayerReady();
                }
                , onPlay : function() {
                        // to notify play state
                        playbackObserver.onPlayerPlay();
                        isLastStatePaused= false;
                }
                , onPause : function() {
                        // to notify pause state
                        playbackObserver.onPlayerPaused();
                        isLastStatePaused = true;
                }
                , onSeek : function() {
                        // to notify seek action
                        var tPos = player.getCurrentTime();
                        var diff = tPos - lastTimeStamp;
                        if (diff != 0)
                                playbackObserver.onPlayerSeek(Math.floor(lastTimeStamp * 1000), Math.floor(diff * 1000))
;
                        lastTimeStamp = tPos;
                }
                , onPlaybackFinished : function() {
                        // to notify playback is completed
                        playbackObserver.onPlayerComplete();
                }
                , onStartBuffering : function() {
                        // to notify buffering is started
                        playbackObserver.onBufferingStart();
                }
                , onStopBuffering : function() {
                        // to notify buffering is stopped
                        if (isLastStatePaused)
                                playbackObserver.onPlayerPaused();
                        else
                                playbackObserver.onPlayerPlay();
                }
                , onVideoPlaybackQualityChange : function() {
                        // to notify bitrate is changed
                        var cbr = getCurrentBitrate();
                        if (cbr != prevBitrate) {
                                playbackObserver.onPlayerBitrateChange(cbr);
                                prevBitrate = cbr;
                        }
                }
                , onAudioPlaybackQualityChange : function() {
                        // to notify bitrate is changed
                        var cbr = getCurrentBitrate();
                        if (cbr != prevBitrate) {
                                playbackObserver.onPlayerBitrateChange(cbr);
                                prevBitrate = cbr;
                        }
                }
                , onTimeChanged : function() {
                        // to save current time
                        lastTimeStamp = player.getCurrentTime();
                }
                , onError : function(data) {
                        // to notify error
                        playbackObserver.onPlayerErrorMessage(data.code + ':' + data.error);
                }

  };

  // Setup player
  player = bitdash('player');
  player.setup(conf);

  // Setup playbackObserver
  playbackObserver = szrpg.PlaybackObserver({
    // Setup properties ...
    ...
  });

userDefinedObserver

Description

userDefinedObserver allows you to define any events you want to collect for your application and your business.

  • Event group is for classifying your User Defined Event.
  • All properties, keys and values should be string. If value is number, you should pass as number. For example, 120, “Mike”, “false”, “true”, 14.23
  • All should not include any spaces or special characters. For example,
    • “Media Player” – Wrong Expression (x)
    • “Media_Player” – Wrong Expression (x)
    • “MediaPlayer” – Correct Expression (o)

Please notice this, If you include any spaces or special characters, then plug-in will delete spaces and special characters. for example, plug-in send all keys as “MediaPlayer” when you try to send above properties.

How to initialize

To initialize UserDefinedEventObserver, you should set up proper properties. You can initialize observer like:


var userDefinedObserver = szrpg.UserDefinedObserver({
    // key provided by Streamlyzer
    customerKey : "<Key Provided by Streamlyzer>",

    // end user related properties
    userId : '<User ID>',
    userType : '<User Type>',
    gender  : '<User Gender>',
    yearOfBirth : '<User Year of Birth>',

    // service related properties
    serviceType : '<Service Type>',
    sessionId : "<Session ID>",
    streamingServerName : "<Streaming Server Name>",  /* Server name or source URL */
    abTestMark : "<AB Test Marking>"

});

Event API

Function Signiture Description
postUserDefinedCountEvent(eventGroup, keyName) Count Event is an event that you want to count the number of event. 1. eventGroup: Group name of the event. 2. keyName: Name of the event
postUserDefinedSumEvent(eventGroup, sumKey, sumValue) Sum Event is an event that you want to sum sumProperty of event. 1. eventGroup: Group name of the event. 2. keyName: The key name to be summed. 3. sumValue: The value to be summed. This should be Number, not String.
postUserDefinedRevenueEvent(eventGroup, keyName, revenueValue) Revenue Event is an event that you want to analyze revenue you make from individual users. By associating with users, you can analyze revenue across different user segment and calculate key business metrics such as lifetime value. 1. eventGroup: Group name of the event 2. keyName: The key name of Revenue type 3. revenueValue: The value of Revenue. This should be Number, not String.

Example


// trigger UserDefinedEvent
function szrUCE() {
  userDefinedObserver.postUserDefinedCountEvent("CntGroup", "click");
  return false;
}
function szrUSE(number) {
  userDefinedObserver.postUserDefinedSumEvent("SumGroup", "coin", number));
  return false;
}
function szrURE(amount) {
  userDefinedObserver.postUserDefinedRevenueEvent("RvnGroup", "revenue", amount);
  return false;
}

pageReferrerObserver

Description

pageReferrerObserver analyzes your service traffic as well as in-site moving.

How to initialize

To initialize pageReferrerObserver, you should set up proper properties. you can initialize observer like:


var pageReferrerObserver = new szrpg.pageReferrerObserver({
    // key provided by Streamlyzer
    customerKey : "<Key Provided by Streamlyzer>",

    // end user related properties
    userId : '<User ID>',
    userType : '<User Type>',
    gender  : '<User Gender>',
    yearOfBirth : '<User Year of Birth>',

    // service related properties
    serviceType : '<Service Type>',
    sessionId : "<Session ID>",
    streamingServerName : "<Streaming Server Name>",  /* Server name or source URL */
    abTestMark : "<AB Test Marking>"
});

Once finishing initialization, yon don’t have to set up any callbacks. It just works.

sharedContentObserver

Description

sharedContentObserver analyzes your service out-bound traffic. For example, your audience shares your video. You will be able to tack which video is shared with this Observer.

How to initialize

To initialize sharedContentObserver, you should set up proper properties. you can initialize observer like:


var sharedContentObserver = new szrpg.sharedContentObserver({
    // key provided by Streamlyzer
    customerKey : "<Key Provided by Streamlyzer>",

    // end user related properties
    userId : '<User ID>',
    userType : '<User Type>',
    gender  : '<User Gender>',
    yearOfBirth : '<User Year of Birth>',

    // service related properties
    serviceType : '<Service Type>',
    sessionId : "<Session ID>",
    streamingServerName : "<Streaming Server Name>",  /* Server name or source URL */
    abTestMark : "<AB Test Marking>"
});

Event API

Function Signiture Description
postSharedEvent(eventGroup, destination) eventGroup: Group name of the event. destination: Shared Destination. with this property. you can send any string, however, we strongly recommend to use below list. Twitter: “twitter” Facebook: “facebook” Google+: “googleplus” Blogger: “blogger” Tumblr: “tumblr” reddit: “reddit” Pinterest: “pinterest” LiveJournal: “livejournal”

Example


// trigger SharedEvent
function szrPostSharedEvent() {
  sharedObserver.postSharedEvent(eventGroup, destination);
  return false;
}