[object Object] Icon

Encoding
Learn how to create, start, manage and modify Encodings

[object Object] Icon

Player
Learn how to create, start, manage and modify Players

[object Object] Icon

Analytics
Learn how to create, start, manage and modify Analyticss

Docs Home
User shortcuts for search
Focus by pressing f
Hide results by pressing Esc
Navigate via   keys

Wed Sep 12 2018

Measuring startup times

OverviewLink Icon

As a video platform, you want to deliver video content to your audience as fast as possible: The earlier a video starts playing, the more likely your audience will watch the video.

Therefore it’s crucial to optimize video startup time and to identify potential delays. The Bitmovin Analytics API provides you with all the tools you need. In this article we’ll show you how to use them.

Different startup timesLink Icon

The Analytics API distinguishes between three types of startup times:

  1. Player startup time
  2. Video startup time
  3. Startup time

The player startup time states how long the player needed until it was ready for playback.

When video playback is started, the video startup time measures how long it took until the first frame was displayed.

The startup time is the sum of player startup time and video startup time. Note that this is not necessarily the total duration from loading the player to the first video frame. There could be a substantial pause when the player is already loaded but video playback hasn’t started – for example, when no-one has pressed the “Play” button yet. This pause is not reflected in the startup time.

Retrieving the median startup timeLink Icon

To understand how long your average viewer had to wait for a video, we can query for the median startup time. Make sure you’ve set up the Bitmovin JavaScript client according to the “Getting Started” guide.

If everything works, we can query for the median startup time:

1queryBuilder
2 .median('STARTUPTIME')
3 .between(fromDate, toDate)
4 .filter('STARTUPTIME', 'GT', 0)
5 .query()
6 .then(console.log);

The result will look something like this:

1{
2 rowCount: 1,
3 rows: [[1644.8242063492066]],
4 columnLabels: [{ key: 'STARTUPTIME', label: 'Startuptime' }],
5}

Our median startup time is stored in result.rows[0][0]. The time is given in milliseconds, so in this example, a typical video started up in 1.64 seconds.

Why did we add the .filter clause? Your analytics data contains entries for all sorts of video events. Only few of them will be about startup time, for all others the STARTUPTIME is set to 0. Unless we filter out this irrelevant data, the median startup time will always be 0.

Avoiding background loadsLink Icon

Some browsers like Chrome defer media loading when videos are loaded in background tabs. This influences the tracked startup time. Since startup times for videos loaded in the background are irrelevant for user experience, you typically want to ignore them by adding a PAGE_LOAD_TYPE filter to your query. The following query only considers videos loaded in the foreground:

1queryBuilder
2 .median('STARTUPTIME')
3 .between(fromDate, toDate)
4 .filter('STARTUPTIME', 'GT', 0)
5 .filter('PAGE_LOAD_TYPE', 'EQ', 1)
6 .query()

Average vs. medianLink Icon

Often we are interested in typical scenarios, like “How long did viewers have to wait for a video to start playing?”. To answer this question we can either use the average or the median of a metric.

The median is more meaningful for metrics with strict boundaries, like durations. Since there cannot be negative durations, the lower boundary of the metric is 0. Thus the average will be unproportionally skewed by very high outliers – like the startup time of a hiker watching a video on the cell phone on a mountain top. For metrics where most data is near the boundary but there are extreme outliers, the median will give you results closer to the real-life experience of your viewers.

Also when you expect one of several discrete values (like the viewer’s browser version), the median makes more sense.

In general the choice depends on your question, though. If you ask “What did the average user experience?”, you should query for the median. If your question is “What did my users experience on average?”, then the average is the way to go.

Average startup time for each dayLink Icon

When we look at a metric in a certain period, it’s useful to divide the period into equal time intervals to see how our metric evolved over time. To determine the average player startup time for each day of our period, we can use the following query:

1queryBuilder
2 .avg('PLAYER_STARTUPTIME')
3 .between(fromDate, toDate)
4 .interval('DAY')
5 .filter('PLAYER_STARTUPTIME', 'GT', 0)
6 .filter('PAGE_LOAD_TYPE', 'EQ', 1)
7 .query()
8 .then(console.log);

The result looks like this:

1{
2 rowCount: 5,
3 rows: [
4 [ 1510531200000, 12301.99537037037 ],
5 [ 1509580800000, 910 ],
6 ],
7 columnLabels: [{ key: 'PLAYER_STARTUPTIME', label: 'Player startuptime' }],
8}

Now we’ve got an array of several rows, with 2 elements each. The first element is the unix timestamp of the beginning of the day.

1new Date(1510531200000) // => 2017-11-13T00:00:00.000Z

The second element is the average player startup time of the day. In our example, the average player startup time on November 13 was 12.3 seconds.

You might have noticed that there isn’t a row for every day of our query period. That’s because only days with actual analytics data are included in the result.

Of course you can also choose other intervals. Available values are 'MINUTE', 'HOUR', 'DAY' and 'MONTH'.

Video startup times for different countries, browsers and CDN providersLink Icon

With an international audience, it’s important to analyze how your video platform performs across different countries, browsers and CDN providers.

To check how your video startup time performs in Google Chrome, you can query

1queryBuilder
2 .median('VIDEO_STARTUPTIME')
3 .between(fromDate, toDate)
4 .filter('VIDEO_STARTUPTIME', 'GT', 0)
5 .filter('PAGE_LOAD_TYPE', 'EQ', 1)
6 .filter('BROWSER', 'EQ', 'Chrome')
7 .query()
1queryBuilder
2 .median('VIDEO_STARTUPTIME')
3 .between(fromDate, toDate)
4 .filter('VIDEO_STARTUPTIME', 'GT', 0)
5 .filter('PAGE_LOAD_TYPE', 'EQ', 1)
6 .filter('CDN_PROVIDER', 'EQ', 'akamai')
7 .filter('COUNTRY', 'EQ', 'ES')
8 .query()

Comparing BrowsersLink Icon

Sometimes you don’t know all the values to query for. Like for Browsers, there are some exotic ones that you might not think of – or would you have though of “Vivaldi”? To get an overview of startup times in all browsers, we can group our results:

1queryBuilder
2 .median('STARTUPTIME')
3 .between(fromDate, toDate)
4 .filter('PLAYER_STARTUPTIME', 'GT', 0)
5 .filter('PAGE_LOAD_TYPE', 'EQ', 1)
6 .groupBy('BROWSER')
7 .query()
8 .then(console.log);

This gives us the median startup time for each browser:

1{
2 rowCount: 15,
3 rows: [
4 ['Edge', 1654],
5 ['Other', 9809.5],
6 ['Mobile Safari', 1550],
7 ['Chrome Mobile', 2742.5],
8 ['Samsung Internet', 19398.5],
9 ['Opera', 2752],
10 ['Chrome', 1659.617857142857],
11 ['Safari', 492],
12 ['UC Browser', 1368],
13 ['Mobile Safari UI/WKWebView', 6622],
14 ['IE', 1740],
15 ['Vivaldi', 4169.5],
16 ['Firefox Mobile', 2036],
17 ['Firefox', 1403.6666666666665],
18 ['Chromium', 1822],
19 ],
20 columnLabels: [
21 { key: 'STARTUPTIME', label: 'Startuptime' },
22 { key: 'PAGE_LOAD_TYPE', label: 'Page load type' },
23 ],
24}

You can apply the same technique to countries, CDN providers and other attributes. For an extensive list of available attributes, check out the Bitmovin Analytics API docs.

Give us feedback