This guide explains Phenix’s recommendations for gathering timing information for the purpose of optimizing video experiences. Following this methodology will allow for clear conversations and data comparisons (apples to apples) to enable quicker resolutions to issues and a faster path toward optimized experiences.

Instructions

Phenix recommends using the Performance API built into modern browsers. Specifically, the performance.measure(name) function is used in several places to mark specific points in the video delivery process.

  1. Add performance.measure() calls at key measurement points

  2. Gather the resulting data as JSON or CSV (JSON/HTTP POST example shown below)

Key Measurement Points

Place calls to performance.measure with an appropriate text identifier in at least these places:

A) First line of your JavaScript.

performance.measure("firstLineOfJS");

B) Just before the joinChannel call is made.

  performance.measure("joinChannel");
  channel.joinChannel(joinChannelOptions, function joinChannelCallback(error, response) {

C) First thing in the joinChannelCallback.

  channel.joinChannel(joinChannelOptions, function joinChannelCallback(error, response) {
    performance.measure("joinChannelCallback");

D) First thing in the subscriberCallback

    }, function subscriberCallback(error, response) {
      performance.measure("subscriberCallback");

E) Set a callback on the videoElement.ontimeupdate

var videoElement = document.getElementById('myVideoId');
videoElement.ontimeupdate = function () {
    performance.measure("firstFrameOfVideo");
    videoElement.ontimeupdate = null;
}

Gathering Results

After your player experience is completely loaded and in a steady state gather the information from the performance.measure() calls and send them to a backend for recording.

    var measures = performance.getEntriesByType("measure");
    var timingJson = new Object();
    timingJson.timestamp = Date.now();
    for (var m = 0; m < measures.length; m++) {
        timingJson[measures[m].name] = measures[m].duration;
    } 
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "https://logging-endpoint.com/path");
    xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
    xhr.send(JSON.stringify(timingJson));

Once gathered on a backend the data can be shared in JSON or CSV format.

Example:

[
  {
    "firstLineOfJS": 305.4450000054203,
    "joinChannel": 317.17000000935514,
    "joinChannelCallback": 727.820000000065,
    "subscriberCallback": 1059.5500000054017,
    "firstFrameOfVideo": 1917.670000009821
  },
  ...
]

 A web page that shows an example of these measurements, including Time To First Frame (TTFF), can be found here.

Related articles

The content by label feature displays related articles automatically, based on labels you choose. To edit options for this feature, select the placeholder below and tap the pencil icon.

Related issues