Mux

The Mux Developer Hub

Welcome to the Mux developer hub. You'll find comprehensive guides and documentation to help you start working with Mux as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started

Integration Guide: Web

1. Choose your SDK

This documents integration instructions for JavaScript-based web video players. For other players, see the additional Integration Guides.

For web players, Mux has specific integrations with the following common players:

  • HTML5 Video Element. Can also be used with:
    • HLS.js
    • Dash.js
    • Any player that provides access to the HTML5 video element
  • Video.js. Can also be used with:
    • Brightcove (5.x & 6.x)
    • Azure Media Player
  • JW Player (7 & 8)
  • Bitmovin Player (5.x, 6.x, and 7.x)
  • Ooyala Player (v4)
  • THEOplayer (2.x)
  • Flowplayer (7.x)
  • Comcast Technology Solutions/thePlatform PDK (5 & 6)
  • Akamai Media Player
  • Shaka Player

2. Include the Mux Data SDK

Include the Mux JavaScript SDK on every page of your site/app that includes video. You can use the Mux-hosted version of the script to receive automatic updates. (The API will not change within major versions, as in core/MAJOR_VERSION/mux.js).

If possible, use the SDK for your particular player (e.g. Video.js or JW Player). While the HTML5 SDK works with any modern HTML5 video player, Mux also offers deeper integrations with the most common open source and commercial video players. Certain players include the Mux SDK directly as plugins in the player (e.g. CTS PDK and Akamai Media Player), so you may be able to skip this step. If you don't see your player listed, use the base HTML5 SDK.

<script src="https://src.litix.io/core/2/mux.js"></script>
<script src="https://src.litix.io/core/2/mux.js"></script>
<script src="https://src.litix.io/core/2/mux.js"></script>
<!-- Include videojs-mux after Video.js -->
<script src="/path/to/video.js"></script>
<!-- Include other videojs plugin files here -->
<script src="https://src.litix.io/videojs/2/videojs-mux.js"></script>
To include the plugin through the Brightcove Studio, add
"https://src.litix.io/videojs/2/videojs-mux.js" as a new 
JavaScript line in your Plugins configuration.

Alternatively, you can include the plugin at runtime in 
the embed (see Video.js instructions).
<!-- Include videojs-mux after azuremediaplayer.min.js -->
<script src="https://amp.azure.net/libs/amp/1.0.0/azuremediaplayer.min.js"></script>
<!-- Include other plugin files here -->
<script src="https://src.litix.io/videojs/2/videojs-mux.js"></script>
<!-- Include jwplayer-mux after the core JW Player javascript file -->
<!--  Note that the KEY in the example should be replaced with the key 
provided by JW Player for your account. -->
<script src="https://content.jwplatform.com/libraries/KEY.js"></script>
<script src="https://src.litix.io/jwplayer/2/jwplayer-mux.js"></script>
<!-- Include bitmovin-mux after the core Bitmovin javascript file -->
<script src="https://bitmovin-a.akamaihd.net/bitmovin-player/stable/7/bitmovinplayer.js"></script>
<script src="https://src.litix.io/bitmovin/2/bitmovin-mux.js"></script>
<!-- Include ooyala-mux after the core Ooyala javascript files -->
<script src="https://player.ooyala.com/static/v4/stable/latest/core.min.js"></script>
<!-- Insert other Ooyala plugin files here -->
<script src="https://src.litix.io/ooyala/2/ooyala-mux.js"></script>
<!-- Include theoplayer-mux after the core THEOplayer javascript files -->
<script type="text/javascript" src="https://cdn.theoplayer.com/latest/~yourlicense~/theoplayer.loader.js"></script>
<script src="https://src.litix.io/theoplayer/2/theoplayer-mux.js"></script>
<!-- include flowplayer-mux after the other flowplayer libraries -->
<link rel="stylesheet" href="https://releases.flowplayer.org/7.2.1/skin/skin.css">
<!-- include flowplayer -->
<script src="https://releases.flowplayer.org/7.2.1/flowplayer.min.js"></script>
<script src="https://src.litix.io/flowplayer/1/flowplayer-mux.js"></script>
<!-- 
The PDK SDK is loaded as a plugin directly in the MPX Console or in 
the player embed, and is hosted at https://src.litix.io/cts/1/cts-mux.js 
-->
<!-- The Akamai Media Player SDK is loaded as a plugin directly in the player embed -->
<script src="https://src.litix.io/shakaplayer/1/shakaplayer-mux.js"></script>

Alternatively, for some video players, you can bundle Mux into your own app or player javascript using npm/yarn. If you choose this path we suggest that you update often to make sure you have the latest features.

npm install --save mux-embed
npm install --save mux-embed
npm install --save mux-embed
npm install --save videojs-mux
If you desire an NPM package for other SDKs, reach out! help@mux.com

3. Initialize Mux Data

To monitor the performance of a specific video element, initialize the SDK. This is done differently in different players.

<script>
  window.muxPlayerInitTime = Date.now();
</script>
<video id="myVideo" src="http://path/to/awesomeVideo.mp4" controls width="960" height="400"></video>

<script>
  // Initialize Mux Data monitoring
  if (typeof mux !== 'undefined') {
    mux.monitor('#myVideo', {
      debug: false,
      data: {
        env_key: 'EXAMPLE_ENV_KEY', // required

        // Metadata
        player_name: 'Custom Player', // ex: 'My Main Player'
        player_init_time: window.muxPlayerInitTime // ex: 1451606400000

        // ... and other metadata
      }
    });
  }
</script>
<script>
  window.muxPlayerInitTime = Date.now();
</script>
<video id="myVideo" controls width="960" height="400"></video>

<script>
  // Initialize Mux Data monitoring
  if (typeof mux !== 'undefined') {
    var vid = document.querySelector('#myVideo');
    if (Hls.isSupported()) {
      var hls = new Hls();
      hls.loadSource('http://path/to/awesomeVideo/master.m3u8');
      hls.attachMedia(vid);
    }
    
    mux.monitor('#myVideo', {
      debug: false,
      
      // Pass in the HLS.js instance
      hlsjs: hls,
      
      // Optionally, if Hls is not available on the window globally
      // you need to pass Hls as well.
      Hls: Hls,
      
      data: {
        env_key: 'EXAMPLE_ENV_KEY', // required

        // Metadata
        player_name: 'Custom Player', // ex: 'My Main Player'
        player_init_time: window.muxPlayerInitTime // ex: 1451606400000

        // ... and other metadata
      }
    });
  }
</script>
<script>
  window.muxPlayerInitTime = Date.now();
</script>
<video id="myVideo" controls width="960" height="400"></video>

<script>
  // Initialize Mux Data monitoring
  if (typeof mux !== 'undefined') {
    var vid = document.querySelector('#myVideo');
    var url = 'http://path/to/awesomeVideo/manifest.mpd';
    var dashjsPlayer = dashjs.MediaPlayer().create();
    dashjsPlayer.initialize(vid, url, true);

    mux.monitor('#myVideo', {
      debug: false,
      
      // Pass in the Dash.js instance
      dashjs: dashjsPlayer,
      
      data: {
        env_key: 'EXAMPLE_ENV_KEY', // required

        // Metadata
        player_name: 'Custom Player', // ex: 'My Main Player'
        player_init_time: window.muxPlayerInitTime // ex: 1451606400000

        // ... and other metadata
      }
    });
  }
</script>
<video id="videojs-mux-player" class="video-js vjs-default-skin"  controls>
  <source src="//path/to/awesomeVideo.mp4" type='video/mp4'>
  <source src="//path/to/awesomeVideo.webm" type='video/webm'>
</video>

<script>
  // Record the player init time
  var playerInitTime = Date.now();

  // EITHER initialize Mux Data monitoring like this
  videojs('my-player', {
    plugins: {
      mux: {
        debug: false,
        data: {
          env_key: 'EXAMPLE_ENV_KEY', // required

          // Metadata
          player_name: '', // ex: 'My Main Player'
          player_init_time: playerInitTime // ex: 1451606400000

          // ... and other metadata
        }
      }
    }
  });


  // OR call the mux function on the player instance
  // var player = videojs('my-player');
  // player.mux({ 
  //   debug: false,
  //   data: { ... }
  // });
</script>
// We strongly suggest initializing the player at runtime, so that you can pass metadata from the page.
<video id="player"
  data-video-id="..."
  data-account="..."
  data-player="..."
  data-embed="default"
  data-application-id
  class="video-js"
  controls></video>

<script>
  var playerInitTime = Date.now();
  var player = videojs('player');
  player.mux({
    debug: false,
    data: {
      env_key: 'EXAMPLE_ENV_KEY', // required

      // Metadata
      player_name: '', // ex: 'My Main Player'
      player_init_time: playerInitTime // ex: 1451606400000

      // ... and other metadata
    }
  });
</script>

// If desired, you can configure this in the Studio (though you will not have certain metadata such as video_title, etc), by setting the Name as `mux`, and the options as the object passed in the example above.
  
<video id="player" class="azuremediaplayer amp-default-skin" autoplay controls width="640" height="400" poster="poster.jpg">
  <source src="..." type="..." />
  <p class="amp-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video</p>
</video>

<script>
  var playerInitTime = Date.now();
  // Get a reference to your player, and pass it to the init function
  var player = amp("player");
  player.mux({
    debug: false,
    data: {
      env_key: 'EXAMPLE_ENV_KEY', // required

      // Metadata
      player_name: '', // ex: 'My Main Player'
      player_init_time: playerInitTime // ex: 1451606400000

      // ... and other metadata
    }
  });
</script>
<div id="myPlayer"></div>
<script>
  var conf = {
    // Insert JW Player configuration here
  };

  var playerInitTime = Date.now();
  var player = jwplayer('myPlayer').setup(conf);

  // Initialize Mux Data monitoring
  initJWPlayerMux(player, {
    debug: false,
    data: {
      env_key: 'EXAMPLE_ENV_KEY', // required

      // Metadata
      player_name: '', // ex: 'My Main Player'
      player_init_time: playerInitTime // ex: 1451606400000
          
      // ... and other metadata
    }
  });
</script>
<div id="playerdiv"></div>
<script>

  // Record the player init time
  var playerInitTime = Date.now();

  var conf = {
      // Insert player configuration here
  };

  // It is preferred to retrieve the reference from the return of bitmovin.player(id) rather than on a player callback so that Mux can track events as soon as possible.
  // For 5.x of Bitmovin's player, use `bitdash.('playerdiv')`
  var player = bitmovin.player('playerdiv');
  player.setup(conf);

  initBitmovinMux(player, {
    debug: false,
    data: {
      env_key: 'EXAMPLE_ENV_KEY', // required

      // Metadata
      player_name: '', // ex: 'My Main Player'
      player_init_time: playerInitTime // ex: 1451606400000
          
      // ... and other metadata
    }
  });
</script>
<div id="playerdiv"></div>
<script>
  var playerInitTime;

  // Use a callback for when the player is created to register Mux Data
  var onPlayerCreated = function (player) {
    initOoyalaMux(player, {
      debug: false,
      data: {
        env_key: 'EXAMPLE_ENV_KEY', // required

        // Metadata
        player_name: '', // ex: 'My Main Player'
        player_init_time: playerInitTime // ex: 1451606400000
        
        // ... and other metadata
      }
    }
  });
  
  var asset = {
    // Insert Ooyala asset configuration here
  };
  var playerConfig = {
    "onCreate": onPlayerCreated,
    // Insert other Ooyala player configuration (e.g. autoplay etc) here
  };

  // Create the player with the Mux callback
  OO.ready(function() {
    playerInitTime = Date.now();

    OO.player.create('playerdiv', asset, playerConfig)
  });
</script>
<div id='playerwrapper' class='video-js theoplayer-skin theo-seekbar-above-controls'></div>
<script>
  // Record the player init time
  var playerInitTime = Date.now();
  var element = document.querySelector('#playerwrapper');

  // Get a reference to your player, and pass it to the init function
  var player = new THEOplayer.Player(element, {
      // Insert player configuration here
  });

  player.src = '/path/to/video';

  var monitor = initTHEOplayerMux(player, {
    debug: false,
    data: {
      env_key: 'EXAMPLE_ENV_KEY', // required

      // Metadata
      player_name: '', // ex: 'My Main Player'
      player_init_time: playerInitTime // ex: 1451606400000
        
      // ... and other metadata
    }
  });
</script>
<div id='playerwrapper'></div>
<script>
  var initTime = Date.now();
  var container = document.getElementById('playerwrapper');
  var player = flowplayer(container, {
    /// ... flowplayer config
  });

  // Make sure to call this immediately after the return to `flowplayer` in 
  // order to track the player correctly
  initFlowplayerMux(player, container, {
    debug: false,
    data: {
      env_key: 'EXAMPLE_ENV_KEY', // required

      // Metadata
      player_name: '', // ex: 'My Main Player'
      player_init_time: initTime

      // ... and other metadata
    }
  });
</script>
<div class="tpPlayer" 
     id="player"
     // ... other configuration options
     tp:muxPlugin = "priority=1|URL=https://src.litix.io/cts/1/cts-mux.js|env_key=EXAMPLE_ENV_KEY|debug=false|player_name='EXAMPLE_PLAYER_NAME'|...other metadata separated by `|`">
</div>
<script>
  // Creates the Player object that builds the component.
  var player = new Player("player");
  player.bind("player");
</script>
<div id="akamai-media-player"></div>
<script>
  akamai.amp.AMP.create("#akamai-media-player", {
    // ... other player configuration
    plugins: {
      mux: {
        resources: [
          {src: "http://src.litix.io/akamai/1/akamai-mux.js", type: "text/javascript"},
        ],
        debug : false,
        data: {
          env_key: 'EXAMPLE_ENV_KEY', // required

          // Metadata
          player_name: '', // ex: 'My Main Player'
          player_init_time: playerInitTime // ex: 1451606400000

          // ... and other metadata
        }
      }
    }
  });
</script>
<script>
  window.muxPlayerInitTime = Date.now();
</script>

<video id="myVideo" controls width="960" height="400"></video>

<script>
  var vid = document.querySelector('#myVideo');
  // initialize the shaka player
  var player = new shaka.Player(vid);

  // calling initShakaPlayerMux will return a shakaPlayerMux object
  // you will need this for handling any errors when calling
  // player.load()
  var shakaPlayerMux = initShakaPlayerMux(player, {
    debug: false,
    data: {
      env_key: 'EXAMPLE_ENV_KEY',
      // Metadata
      player_name: 'Custom Player', // ex: 'My Main Player',
      player_init_time: window.muxPlayerInitTime // ex: 1451606400000
     // ... and other metadata
    }
  });

  player.load('your-manifest-url-to-play').then(function () {
    // Successfully loaded the manifest. Mux data will begin tracking
  }).catch(function (error) {
    // There was an error loading this manifest. Call shakaPlayerMux.loadErrorHandler(error) so that Mux data can track this error.
    shakaPlayerMux.loadErrorHandler(error);
    // Do the rest of your error handling logic
  })

// if you have other events custom you want to emit, there are two ways to do that
//   1. player.mux.emit
//   2. shakaPlayerMux.emit
</script>

HTML5: call mux.monitor, passing a valid CSS selector for your video element or the element itself, along with SDK options and metadata. If you use a CSS selector that matches multiple elements, the first matching element in the document will be used.

HLS.js: call mux.monitor, passing a valid CSS selector for your video element or the element itself, along with SDK options and metadata. If you use a CSS selector that matches multiple elements, the first matching element in the document will be used. Also, ensure that you pass your HLS.js instance (as well as, optionally, the global Hls object) to Mux in the metadata. Note: In order to auto-detect the CDN being used, see CDN Configuration for Request-Level Metadata.

Alternatively, if your player does not immediately have access to the HLS.js player instance, you can start monitoring HLS.js at any time in the future. In order to do this, you can call either of the following:

  • mux.addHLSJS(<id or el>, options)
  • el.mux.addHLSJS(options)

where id is a valid CSS selector for your video element, el is the video element itself, and options is an object with hlsjs and Hls passed as above in the call to mux.monitor. You can stop monitoring HLS.js with either of the following:

  • mux.removeHLSJS(<id or el>)
  • el.mux.removeHLSJS()

Dash.js: call mux.monitor, passing a valid CSS selector for your video element or the element itself, along with SDK options and metadata. If you use a CSS selector that matches multiple elements, the first matching element in the document will be used. Also, ensure that you pass your Dash.js player instance to Mux in the metadata. Note: In order to auto-detect the CDN being used, see CDN Configuration for Request-Level Metadata.

Alternatively, if your player does not immediately have access to the Dash.js player instance, you can start monitoring Dash.js at any time in the future. In order to do this, you can call either of the following:

  • mux.addDashJS(<id or el>, options)
  • el.mux.addDashJS(options)

where id is a valid CSS selector for your video element, el is the video element itself, and options is an object with dashjs as above in the call to mux.monitor. You can stop monitoring Dash.js with either of the following:

  • mux.removeDashJS(<id or el>)
  • el.mux.removeDashJS()

Video.js: initialize the videojs-mux plugin by including options in the player plugin options. This can be in the options passed to the videojs function (or the data-setup attribute) or by calling the mux function directly on the player instance.

Brightcove: You can initialize the videojs-mux plugin at runtime in the player (preferred, so that you can pass it updated metadata), or you can configure it within the Brightcove Studio as mentioned in the code above.

Azure Media Player: Register videojs-mux as a plugin on the amp player as you would any other plugin.

JW Player: pass that player reference to initJWPlayerMux along with the options for the SDK. We recommend you retrieve the reference from the return of jwplayer(id).setup({...}) so that Mux can track events as soon as possible.

Bitmovin: pass that player reference to initBitmovinMux along with the options for the SDK. It is preferred to retrieve the reference from the return of bitmovin.player(id) rather than on a player callback so that Mux can track events as soon as possible.

Ooyala: you must register an onCreate handler when you create the Ooyala player, and in that callback simply pass that player reference to initOoyalaMux along with the options for the SDK.

THEOplayer: pass the player reference to initTHEOplayerMux along with the options for the SDK. We recommend you retrieve the reference from the return of new THEOplayer.Player(...) so that Mux can track events as soon as possible. As of version 2.4.0 (and newer), the call to initTHEOplayerMux returns an object with a single property, emit. This emit(eventName, data) can be used to emit events for the player that is currently being tracked (such as programchange).

Flowplayer: pass the player reference to initFlowplayerMux, along with the container (so Mux can determine the player size and full-screen properties) and the options for the SDK. It is important to pass this reference to initFlowplayerMux immediately upon return, rather than waiting for any event from Flowplayer, so Mux can track the entire lifecycle of the player.

Comcast Technology Solutions / PDK Player: Include cts-mux.js as a plugin within the player embed parameters. Ensure to pass at least the env_key as a parameter as shown in the example above, and you may pass any other metadata along. While Mux will automatically gather certain information from the player itself (such as video ID, video title, etc), you can override these values at run-time in the plugin parameters. If you would prefer to configure the Mux plugin within the MPX console, please reach out to us!

Akamai Media Player: Register mux as a plugin for the AMP player that you create, passing the options for the SDK along.

Shaka Player: pass the player reference to initShakaPlayerMux along with the options for the SDK. We recommend you retrieve the reference from the return of new shaka.Player(...) so that Mux can track events as soon as possible. The call to initShakaPlayerMux returns an object with a two properties, emit and loadErrorHandler. The emit(eventName, data) function can be used to emit events for the player that is currently being tracked (such as programchange). Use the loadErrorHandler property to catch and report any errors after calling player.load(...) with your manifest URL (see the code example above).

IMPORTANT NOTE ABOUT AUTOPLAY

If you are autoplaying videos, without requiring the user to click the play button, then make sure you read: Autoplaying Your Videos

4. Test it

After you've finished integration, the quickest way to see that the SDK is loaded is to pass debug: true in the options passed to each SDK. With this flag enabled, you can open your browser developer tools, and you should start seeing debug statements from [mux] when you click play on the video.

The next step in the debugging process if this is working is to select the network tab, and then clicking 'play' on the video you've set to be monitored. You should begin to see beacons being sent to the Mux servers (litix.io) like in the example image.

You can also test that Mux is receiving data in the Mux Data dashboard. Login to the dashboard and find the environment that corresponds to your env_key and look for video views.

Note that it may take a few minutes for views to show up in the Mux Data dashboard.

If you aren't seeing data, check to see if you have Do Not Track enabled in your browser. Mux does not send analytics data in this case.

5. Add Metadata

Detailed Documentation

The only required field in the data object is env_key. However, to really take advantage of Mux Data, you should pass as much metadata as you can. This gives you more metrics and metadata about video streaming, and allows you to search and filter on important fields like the player version, CDN, and video title.

// Additional metadata under `data` can be used for HTML5, HLS.js, and Dash.js
mux.monitor('#myVideo', {
  debug: false,
  data: {
    env_key: 'EXAMPLE_ENV_KEY', // required

    // Site Metadata
    viewer_user_id: '', // ex: '12345'
    experiment_name: '', // ex: 'player_test_A'
    sub_property_id: '', // ex: 'cus-1'

    // Player Metadata
    player_name: '', // ex: 'My Main Player'
    player_version: '', // ex: '1.0.0'
    player_init_time: '', // ex: 1451606400000

    // Video Metadata (cleared with 'videochange' event)
    video_id: '', // ex: 'abcd123'
    video_title: '', // ex: 'My Great Video'
    video_series: '', // ex: 'Weekly Great Videos'
    video_duration: '', // in milliseconds, ex: 120000
    video_stream_type: '', // 'live' or 'on-demand'
    video_cdn: '' // ex: 'Fastly', 'Akamai'
  }
});
videojs('my-player', {
  plugins: {
    mux: {
      debug: false,
      data: {
        env_key: 'EXAMPLE_ENV_KEY', // required
        
        // Site Metadata
        viewer_user_id: '', // ex: '12345'
        experiment_name: '', // ex: 'player_test_A'
        sub_property_id: '', // ex: 'cus-1'

        // Player Metadata
        player_name: '', // ex: 'My Main Player'
        player_version: '', // ex: '1.0.0'
        player_init_time: playerInitTime, // ex: 1451606400000

        // Video Metadata (cleared with 'videochange' event)
        video_id: '', // ex: 'abcd123'
        video_title: '', // ex: 'My Great Video'
        video_series: '', // ex: 'Weekly Great Videos'
        video_duration: '', // in milliseconds, ex: 120000
        video_stream_type: '', // 'live' or 'on-demand'
        video_cdn: '' // ex: 'Fastly', 'Akamai'
      }
    }
  }
});
player.mux(debug: false,
  data: {
    env_key: 'EXAMPLE_ENV_KEY', // required

    // Site Metadata
    viewer_user_id: '', // ex: '12345'
    experiment_name: '', // ex: 'player_test_A'
    sub_property_id: '', // ex: 'cus-1'

    // Player Metadata
    player_name: '', // ex: 'My Main Player'
    player_version: '', // ex: '1.0.0'
    player_init_time: playerInitTime, // ex: 1451606400000

    // Video Metadata (cleared with 'videochange' event)
    video_id: '', // ex: 'abcd123'
    video_title: '', // ex: 'My Great Video'
    video_series: '', // ex: 'Weekly Great Videos'
    video_duration: '', // in milliseconds, ex: 120000
    video_stream_type: '', // 'live' or 'on-demand'
    video_cdn: '' // ex: 'Fastly', 'Akamai'
  }
});
player.mux(debug: false,
  data: {
    env_key: 'EXAMPLE_ENV_KEY', // required

    // Site Metadata
    viewer_user_id: '', // ex: '12345'
    experiment_name: '', // ex: 'player_test_A'
    sub_property_id: '', // ex: 'cus-1'

    // Player Metadata
    player_name: '', // ex: 'My Main Player'
    player_version: '', // ex: '1.0.0'
    player_init_time: playerInitTime, // ex: 1451606400000

    // Video Metadata (cleared with 'videochange' event)
    video_id: '', // ex: 'abcd123'
    video_title: '', // ex: 'My Great Video'
    video_series: '', // ex: 'Weekly Great Videos'
    video_duration: '', // in milliseconds, ex: 120000
    video_stream_type: '', // 'live' or 'on-demand'
    video_cdn: '' // ex: 'Fastly', 'Akamai'
  }
});
initJWPlayerMux(player, {
  debug: false,
  data: {
    env_key: 'EXAMPLE_ENV_KEY', // required

    // Site Metadata
    viewer_user_id: '', // ex: '12345'
    experiment_name: '', // ex: 'player_test_A'
    sub_property_id: '', // ex: 'cus-1'

    // Player Metadata
    player_name: '', // ex: 'My Main Player'
    player_version: '', // ex: '1.0.0'
    player_init_time: playerInitTime, // ex: 1451606400000

    // Video Metadata (cleared with 'videochange' event)
    video_id: '', // ex: 'abcd123'
    video_title: '', // ex: 'My Great Video'
    video_series: '', // ex: 'Weekly Great Videos'
    video_duration: '', // in milliseconds, ex: 120000
    video_stream_type: '', // 'live' or 'on-demand'
    video_cdn: '' // ex: 'Fastly', 'Akamai'
  }
});
var player = bitmovin.player('playerdiv');
player.setup(conf);

initBitmovinMux(player, {
  debug: false,
  data: {
    env_key: 'EXAMPLE_ENV_KEY', // required

    // Site Metadata
    viewer_user_id: '', // ex: '12345'
    experiment_name: '', // ex: 'player_test_A'
    sub_property_id: '', // ex: 'cus-1'

    // Player Metadata
    player_name: '', // ex: 'My Main Player'
    player_version: '', // ex: '1.0.0'
    player_init_time: playerInitTime, // ex: 1451606400000

    // Video Metadata (cleared with 'videochange' event)
    video_id: '', // ex: 'abcd123'
    video_title: '', // ex: 'My Great Video'
    video_series: '', // ex: 'Weekly Great Videos'
    video_duration: '', // in milliseconds, ex: 120000
    video_stream_type: '', // 'live' or 'on-demand'
    video_cdn: '' // ex: 'Fastly', 'Akamai'
  }
});
var onPlayerCreated = function (player) {
  initOoyalaMux(player, {
    debug: false,
    data: {
      env_key: 'EXAMPLE_ENV_KEY', // required

      // Site Metadata
      viewer_user_id: '', // ex: '12345'
      experiment_name: '', // ex: 'player_test_A'
      sub_property_id: '', // ex: 'cus-1'

      // Player Metadata
      player_name: '', // ex: 'My Main Player'
      player_version: '', // ex: '1.0.0'
      player_init_time: playerInitTime, // ex: 1451606400000

      // Video Metadata (cleared with 'videochange' event)
      video_id: '', // ex: 'abcd123'
      video_title: '', // ex: 'My Great Video'
      video_series: '', // ex: 'Weekly Great Videos'
      video_duration: '', // in milliseconds, ex: 120000
      video_stream_type: '', // 'live' or 'on-demand'
      video_cdn: '' // ex: 'Fastly', 'Akamai'
    }
  }
});
initTHEOplayerMux(player, {
  debug: false,
  data: {
    env_key: 'EXAMPLE_ENV_KEY', // required

    // Site Metadata
    viewer_user_id: '', // ex: '12345'
    experiment_name: '', // ex: 'player_test_A'
    sub_property_id: '', // ex: 'cus-1'

    // Player Metadata
    player_name: '', // ex: 'My Main Player'
    player_version: '', // ex: '1.0.0'
    player_init_time: playerInitTime, // ex: 1451606400000

    // Video Metadata (cleared with 'videochange' event)
    video_id: '', // ex: 'abcd123'
    video_title: '', // ex: 'My Great Video'
    video_series: '', // ex: 'Weekly Great Videos'
    video_duration: '', // in milliseconds, ex: 120000
    video_stream_type: '', // 'live' or 'on-demand'
    video_cdn: '' // ex: 'Fastly', 'Akamai'

  }
});
initFlowplayerMux(player, {
  debug: false,
  data: {
    env_key: 'EXAMPLE_ENV_KEY', // required

    // Site Metadata
    viewer_user_id: '', // ex: '12345'
    experiment_name: '', // ex: 'player_test_A'
    sub_property_id: '', // ex: 'cus-1'

    // Player Metadata
    player_name: '', // ex: 'My Main Player'
    player_version: '', // ex: '1.0.0'
    player_init_time: playerInitTime, // ex: 1451606400000

    // Video Metadata (cleared with 'videochange' event)
    video_id: '', // ex: 'abcd123'
    video_title: '', // ex: 'My Great Video'
    video_series: '', // ex: 'Weekly Great Videos'
    video_duration: '', // in milliseconds, ex: 120000
    video_stream_type: '', // 'live' or 'on-demand'
    video_cdn: '' // ex: 'Fastly', 'Akamai'
  }
});
<div class="tpPlayer" 
     id="player"
     // ... other configuration options
     tp:muxPlugin = "priority=1|type=overlay|URL=cts-mux.js|env_key=EXAMPLE_ENV_KEY|experiment_name=EXAMPLE_EXPERIMENT_NAME|video_id=EXAMPLE_VIDEO_ID|...|debug=true">
</div>
akamai.amp.AMP.create("#akamai-media-player", {
  // ... other player configuration
  plugins: {
    mux: {
      resources: [
        {src: "http://src.litix.io/akamai/1/akamai-mux.js", type: "text/javascript"},
      ],
      debug : false,
      data: {
        env_key: 'EXAMPLE_ENV_KEY', // required

        // Site Metadata
        viewer_user_id: '', // ex: '12345'
        experiment_name: '', // ex: 'player_test_A'
        sub_property_id: '', // ex: 'cus-1'

        // Player Metadata
        player_name: '', // ex: 'My Main Player'
        player_version: '', // ex: '1.0.0'
        player_init_time: playerInitTime, // ex: 1451606400000

        // Video Metadata (cleared with 'videochange' event)
        video_id: '', // ex: 'abcd123'
        video_title: '', // ex: 'My Great Video'
        video_series: '', // ex: 'Weekly Great Videos'
        video_duration: '', // in milliseconds, ex: 120000
        video_stream_type: '', // 'live' or 'on-demand'
        video_cdn: '' // ex: 'Fastly', 'Akamai'
      }
    }
  }
});
initShakaPlayerMux(player, {
  debug: false,
  data: {
    env_key: 'EXAMPLE_ENV_KEY', // required

    // Site Metadata
    viewer_user_id: '', // ex: '12345'
    experiment_name: '', // ex: 'player_test_A'
    sub_property_id: '', // ex: 'cus-1'

    // Player Metadata
    player_name: '', // ex: 'My Main Player'
    player_version: '', // ex: '1.0.0'
    player_init_time: playerInitTime, // ex: 1451606400000

    // Video Metadata (cleared with 'videochange' event)
    video_id: '', // ex: 'abcd123'
    video_title: '', // ex: 'My Great Video'
    video_series: '', // ex: 'Weekly Great Videos'
    video_duration: '', // in milliseconds, ex: 120000
    video_stream_type: '', // 'live' or 'on-demand'
    video_cdn: '' // ex: 'Fastly', 'Akamai'

  }
});

For more information, see the Metadata guide.

CTS PDK Customers: The Mux integration with the PDK players pulls the video_title and video_duration metadata directly from the asset that is loaded. You can override those values, as well as other metadata fields, in the metadata provided in the plugin config.

6. Changing the video

There are two cases where the underlying tracking of the video view need to be reset. First, when you load a new source URL into an existing player, and secondly when the program within a singular stream changes (such as a program change within a continuous live stream).

Note: You do not need to change the video info when changing to a different source of the same video content (e.g. different resolution or video format).

New Source

If your application plays multiple videos back-to-back in the same video player, you need to signal when a new video starts to the Mux SDK. Examples of when this is needed are:

  • The player advances to the next video in a playlist
  • The user selects a different video to play

For most players (except THEOplayer and CTS PDK players), this is done by emitting a videochange event via mux.emit (in page for HTML5 (and HLS.js/Dash.js), or added to the player object in other players). When this is emitted it removes all previous video data and resets all metrics for the video view.

For THEOplayer, this is handled automatically via the sourcechange event that is fired when you update the source property of the player. In order to change the video within Mux, you should pass the updated metadata under metadata.mux, as shown in the example below. When this is done it removes all previous video data and resets all metrics for the video view. Note: the previous method using changeMuxVideo has been deprecated, but will continue to work for 2.x versions of this plugin.

For the CTS PDK player integration, handling the video change is done automatically, there is no need to make any additional calls.

See metadata for the list of video details you can provide. You can include any metadata when changing the video but you should only need to update the values that start with video_.

It's best to change the video info immediately after telling the player which new source to play.

// Example of changing the source of a video element
// Should happen before emitting the videochange event
var myVideo = document.querySelector('#myVideo');
myVideo.src = 'nextVideo.mp4';

if (typeof mux !== 'undefined') {
  mux.emit('#myVideo', 'videochange', {
    video_id: 'abc345',
    video_title: 'My Other Great Video',
    video_series: 'Weekly Great Videos',
    ...
  });
}
player.source = {
  sources: {
    // ...your source
  },
  metadata: {
    mux: {
      video_id: 'new-ID',
      video_title: 'New title',
      // ... other metadata
    }
  }
}
player.mux.emit('videochange', {
  video_id: 'abc345',
  video_title: 'My Other Great Video',
  video_series: 'Weekly Great Videos',
  ...
});

New Program

In some cases, you may have the program change within a stream, and you may want to track each program as a view on its own. An example of this is a live stream that streams multiple programs back to back, with no interruptions.

In this case, you emit a programchange event, including the updated metadata for the new program within the continuous stream. This will remove all previous video data and reset all metrics for the video view, creating a new video view. See Metadata for the list of video details you can provide. You can include any metadata when changing the video but you should only need to update the values that start with video.

Note: The programchange event is intended to be used only while the player is currently not paused. If you emit this event while the player is paused, the resulting view will not track video startup time correctly, and may also have incorrect watch time. Do not emit this event while the player is paused.

// To be used when the underlying program changes
// within a continuous stream.
if (typeof mux !== 'undefined') {
  mux.emit('#myVideo', 'programchange', {
    video_id: 'abc345',
    video_title: 'My Other Great Video',
    video_series: 'Weekly Great Videos',
    ...
  });
}
var monitor = initTHEOplayerMux(player, config);

// To be used when the underlying program changes
// within a continuous stream.
monitor.emit('programchange', {
  video_id: 'abc345',
  video_title: 'My Other Great Video',
  video_series: 'Weekly Great Videos',
  ...
});
// To be used when the underlying program changes
// within a continuous stream.
player.mux.emit('programchange', {
  video_id: 'abc345',
  video_title: 'My Other Great Video',
  video_series: 'Weekly Great Videos',
  ...
});

7. Advanced Options

Cookies

By default, Mux plugins for HTML5-based players use a cookie to track playback across subsequent page views. This cookie includes information about the tracking of the viewer, such as an anonymized viewer ID that Mux generates for each user. None of this information is personally-identifiable, but you can disable the use of this cookie if desired. For instance, if your site or application is targeted towards children under 13, you should disable the use of cookies.

This is done by setting disableCookies to true in the options passed to the Mux plugin. For instance, using mux-embed, it looks like the following:

mux.monitor('#myVideo', {
  debug: false,
  disableCookies: true,
  data: {
    env_key: 'EXAMPLE_ENV_KEY',
    // ... rest of metadata
  }
}

Do Not Track

While not technically required, Mux's HTML5-based player integrations currently respect Do Not Track when set within browsers, disabling tracking of video playback. This can be disabled in the options passed to Mux, via a setting named respectDoNotTrack. The default for this today is true, though this may change in a future release.

mux.monitor('#myVideo', {
  debug: false,
  respectDoNotTrack: false, // Track browsers even where Do Not Track is enabled
  data: {
    env_key: 'EXAMPLE_ENV_KEY',
    // ... rest of metadata
  }
}

Note: Setting this to false (either directly, or in the future where Mux makes this the default) may increase the number of video views tracked within Mux, and thus could potentially impact the cost of your Mux subscription. Set this explicitly to true if you want to ensure that this does not change behind the scenes.

Custom Errors

Mux integrations automatically track errors that are exposed by the player itself. However, in certain cases, this may not be ideal. See Custom Errors for more information on these situations and the options available.

Integration Guide: Web


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.