diff --git a/analytics/analytics-industry-insights/css/style.css b/analytics/analytics-industry-insights/css/style.css new file mode 100644 index 00000000..075ee488 --- /dev/null +++ b/analytics/analytics-industry-insights/css/style.css @@ -0,0 +1,62 @@ +.map-legend{ + height: 16px; + width: 20px; + margin-left: 2px; +} + +.map-legend-text-size{ + font-size: 13px !important; +} + +.country{ + font-weight: 600; + font-size: 18px; + display: inline-block; + margin-bottom: 0px !important; + vertical-align: bottom; + color: rgb(13, 56, 65); +} + +.metric-text{ + font-size: 13px !important; + margin-bottom: 0px !important; + margin-top: 8px; +} + +.metric-value{ + font-weight: 600; + font-size: 24px !important; + margin-bottom: 16px !important; + color: rgb(13, 56, 65); +} + +.box-border{ + box-shadow: inset 1px 0px 0px rgb(203, 224, 237); +} + +.text-label { + margin-left: 8px; +} + +.chart-legend-extra-dark{ + background-color: rgb(0, 107, 255); +} +.chart-legend-dark{ + background-color: rgba(0, 107, 255, 0.8); +} +.chart-legend-medium{ + background-color: rgba(0, 107, 255, 0.6); +} +.chart-legend-neutral{ + background-color: rgba(0, 107, 255, 0.4); +} +.chart-legend-light{ + background-color: rgba(0, 107, 255, 0.2); +} +.chart-legend-extra-light{ + background-color: rgba(0, 107, 255, 0.05); +} +.chart-legend-no-data{ + background-color: rgb(220, 223, 228); + margin-left: 24px; +} diff --git a/analytics/analytics-industry-insights/icon.svg b/analytics/analytics-industry-insights/icon.svg new file mode 100755 index 00000000..287a940c --- /dev/null +++ b/analytics/analytics-industry-insights/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/analytics/analytics-industry-insights/index.html b/analytics/analytics-industry-insights/index.html new file mode 100644 index 00000000..6f6cc89c --- /dev/null +++ b/analytics/analytics-industry-insights/index.html @@ -0,0 +1,119 @@ +

+ For selected metrics, industry insights display the median of all data points we collect for this metric. + Choose the metric below to get industry insights across the world: +

+ +
+ +
+ +
+
+
+
+
+
+

+
+ +
+
+
+
+ +
+
+

0

+
+ +
Median video startup time (s)
+
+
No data available
+
+
+ +
+

Comparing countries

+
+
+ +

+
+

+

+
+ +
+ +

Shift + Click on map to compare countries

+
+ +
+ +
+ +
+

About Median Startup Time

+
+

+ The total startup time represents the amount of time it takes from starting to load the player until the video + playback can commence. This includes all the initializations the player has to perform as well as downloading + and parsing the manifests, downloading the content segments and initiating playback. +

+ +
Good to know:
+

+ Studies have shown that after 10 seconds of startup delay, more than half of your audience has usually left and + only 8% of users will return to your website within 24 hours after experiencing a video failure. +

+

+ Specifically, if it takes longer than 2 seconds to load the video, viewers will start to leave. After 5 seconds, + more than 20% of your users abandon, and with each additional second of delay, 6% of your users leave and the + majority will never come back. +

+
+ +
+

About Error Percentage

+
+

+ The error percentage shows the number of errors in relation to the number of play attempts on a video platform. +

+ +

+ The error percentage includes errors that disrupted a user's playback as well as errors from which the player was able to recover. +

+
+ +
+

About Rebuffer Percentage

+
+

+ Rebuffering occurs when the player buffer runs out of video data to display to the user. The player pauses and has to wait for ongoing video segment downloads to finish before it can resume playback. +

+ +

+ Rebuffering percentage is the average time a user had to wait for video segment downloads in relation to the total time a user spent watching a video. +

+

+ Example: If a user watches a video with a length of 9 seconds and has to wait 1 second for video segment downloads, it would take him 10 seconds in total to watch the video, so you'd get a 10% rebuffering percentage. +

+
+ +
+ Disclaimer + + The information presented in the Bitmovin Industry Insights Demo is for demonstration purposes only and not for + research or any other purposes. + Bitmovin makes no representations or warranties express or implied in relation to the Industry Insights Demo as + to the currency, accuracy, validity, + reliability, fitness or completeness of the information provided. + +
+ + + \ No newline at end of file diff --git a/analytics/analytics-industry-insights/info.json b/analytics/analytics-industry-insights/info.json new file mode 100644 index 00000000..0159f3d0 --- /dev/null +++ b/analytics/analytics-industry-insights/info.json @@ -0,0 +1,14 @@ +{ + "title": "Industry Insights Demo", + "description": "Gain insights into video performance across the globe provided by Bitmovin Analytics", + "executable": { + "executable": false, + "indexfile": "index.html" + }, + "tags": [ + "analytics", + "industry insights" + ], + "hide_github_link": true + } + \ No newline at end of file diff --git a/analytics/analytics-industry-insights/js/industry-insights.js b/analytics/analytics-industry-insights/js/industry-insights.js new file mode 100644 index 00000000..c02acf76 --- /dev/null +++ b/analytics/analytics-industry-insights/js/industry-insights.js @@ -0,0 +1,377 @@ +var countriesChart = {}; +var mapChart = {}; +const INDUSTRY_INSIGHT_MEDIAN_STARTUP_TIME_URL = 'https://storage.googleapis.com/bitmovin-frontend-cdn-origin/frontend/demos/analytics/median_video_startup_time.json' +const INDUSTRY_INSIGHT_ERROR_PERCENTAGE_URL = 'https://storage.googleapis.com/bitmovin-frontend-cdn-origin/frontend/demos/analytics/error_percentage.json' +const INDUSTRY_INSIGHT_REBUFFER_PERCENTAGE_URL = 'https://storage.googleapis.com/bitmovin-frontend-cdn-origin/frontend/demos/analytics/rebuffer_percentage.json' + +$(function () { + reset(); + + $(document).on('change', '#available-industry-insight-metrics', function () { + reset(); + if (this.value === 'medianStartupTime') { + showMedianStartupTimeChart(); + } + if (this.value === 'errorPercentage') { + showErrorPercentageChart(); + } + if (this.value === 'rebufferPercentage') { + showRebufferPercentageChart(); + } + }); + + showMedianStartupTimeChart(); +}); + +function getIndustryInsightsData(url, callbackFunction) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.onreadystatechange = function () { + if (xhr.readyState === XMLHttpRequest.DONE) { + callbackFunction(JSON.parse(xhr.responseText)); + } + }; + + xhr.send(); +} + +function showMedianStartupTimeChart() { + const dataClasses = [ + { + from: 4.2 + }, + { + from: 3.5, + to: 4.2 + }, + { + from: 2.8, + to: 3.5 + }, + { + from: 2.1, + to: 2.8 + }, + { + from: 1.4, + to: 2.1 + }, + { + from: 0.7, + to: 1.4 + }, + { + to: 0.7 + }]; + $('#metricLegend').html('Median video startup time (s)'); + $('#legend_max_value').html('4'); + $('#startupTimeContent').show(); + $('#errorPercentageContent').hide(); + $('#rebufferPercentageContent').hide(); + + getIndustryInsightsData(INDUSTRY_INSIGHT_MEDIAN_STARTUP_TIME_URL, (response) => { + const data = response.map((res, i) => ({ + code: res.countryCode.toUpperCase(), + value: parseFloat(res.value).toFixed(2), + name: res.countryCode, + })); + drawChart(data, 'Median video startup time', 'Seconds', 's', dataClasses); + }); +} + +function showErrorPercentageChart() { + const dataClasses = [ + { + from: 4.2 + }, + { + from: 3.5, + to: 4.2 + }, + { + from: 2.8, + to: 3.5 + }, + { + from: 2.1, + to: 2.8 + }, + { + from: 1.4, + to: 2.1 + }, + { + from: 0.7, + to: 1.4 + }, + { + to: 0.7 + }]; + $('#startupTimeContent').hide(); + $('#errorPercentageContent').show(); + $('#rebufferPercentageContent').hide(); + $('#metricLegend').html('Error percentage (%)'); + $('#legend_max_value').html('4'); + getIndustryInsightsData(INDUSTRY_INSIGHT_ERROR_PERCENTAGE_URL, (response) => { + const data = response.map((res, i) => ({ + code: res.countryCode.toUpperCase(), + value: parseFloat(res.value).toFixed(2), + name: res.countryCode, + })); + drawChart(data, 'Error Percentage', 'Percentage', '%', dataClasses); + }); +} + +function showRebufferPercentageChart() { + const dataClasses = [ + { + from: 1.2 + }, + { + from: 1.0, + to: 1.2 + }, + { + from: 0.8, + to: 1.0 + }, + { + from: 0.6, + to: 0.8 + }, + { + from: 0.4, + to: 0.6 + }, + { + from: 0.2, + to: 0.4 + }, + { + to: 0.2 + }]; + $('#startupTimeContent').hide(); + $('#errorPercentageContent').hide(); + $('#rebufferPercentageContent').show(); + $('#metricLegend').html('Rebuffer percentage (%)'); + $('#legend_max_value').html('1'); + getIndustryInsightsData(INDUSTRY_INSIGHT_REBUFFER_PERCENTAGE_URL, (response) => { + const data = response.map((res, i) => ({ + code: res.countryCode.toUpperCase(), + value: parseFloat(res.value).toFixed(2), + name: res.countryCode + })); + drawChart(data, 'Rebuffer Percentage', 'Percentage', '%', dataClasses); + }) +} + +function drawChart(data, metric, unit, unitAbb, dataClasses) { + if ($.isEmptyObject(mapChart)) { + mapChart = Highcharts + .mapChart('container', { + title: { + text: '' + }, + chart: { + map: map, + }, + colors: ['rgba(0, 107, 255, 1)', + 'rgba(0, 107, 255, 0.8)', + 'rgba(0, 107, 255, 0.6)', + 'rgba(0, 107, 255, 0.4)', + 'rgba(0, 107, 255, 0.2)', + 'rgba(0, 107, 255, 0.05)' + ], + mapNavigation: { + enabled: true + }, + legend: { + enabled: false + }, + tooltip: { + backgroundColor: 'rgb(255, 255, 255)', + borderWidth: 1, + borderColor: 'rgb(203, 224, 237)', + borderRadius: 16, + useHTML: true, + pointFormat: '
{point.name}: {point.value} ' + unitAbb + '
' + + '(click for details)
' + }, + colorAxis: [{ + maxColor: 'rgba(0, 107, 255, 1)', + minColor: 'rgba(0, 107, 255, 0.2)', + dataClasses: dataClasses + }], + series: [{ + data: data, + allowPointSelect: true, + joinBy: ['iso-a2', 'code'], + animation: true, + name: metric, + states: { + hover: { + color: 'rgb(67, 200, 120)' + }, + select: { + color: 'rgb(105, 211, 147)' + } + }, + colorAxis: 0, + nullColor: 'rgb(220, 223, 228)', + shadow: false + }], + credits: { + enabled: false + }, + }); + } + else { + mapChart.tooltip.update({ + pointFormat: '
{point.name}: {point.value} ' + unitAbb + '
' + + '(click for details)
' + }); + mapChart.colorAxis[0].update({ + dataClasses: dataClasses + }); + mapChart.series[0].update({ + data: data, + name: metric + }); + mapChart.redraw(); + } + + Highcharts.wrap(Highcharts.Point.prototype, 'select', function (proceed) { + proceed.apply(this, Array.prototype.slice.call(arguments, 1)); + var points = mapChart.getSelectedPoints(); + + if (points.length === 0) { + reset(); + } + else if (points.length === 1) { + if (!$.isEmptyObject(countriesChart)) { + countriesChart = countriesChart.destroy(); + } + setValues(points[0], metric, unitAbb); + $('#info').show(); + $('#instructions').show(); + $('#additionalData').show(); + $('#chartTitle').hide(); + } else { + $('#info').hide(); + $('#chartTitle').show(); + var categories = $.map(points, function (n, i) { + return [n.name]; + }); + var seriesData = $.map(points, function (n, i) { + return [{ "name": n.name, "data": [parseFloat(n.value)] }]; + }); + + compareCharts(categories, seriesData, metric, unit, unitAbb); + } + }); +} + +function compareCharts(categories, series, metric, unit, unitAbb) { + if ($.isEmptyObject(countriesChart)) { + countriesChart = Highcharts.chart('country-chart', { + chart: { + type: 'column' + }, + title: { + text: '' + }, + xAxis: { + categories: categories, + labels: { + enabled: false + } + }, + colors: ['rgb(18, 120, 225)', + 'rgb(61, 217, 187)', + 'rgb(243, 210, 54)', + 'rgb(210, 52, 127)', + 'rgb(173, 85, 54)', + 'rgb(47, 102, 242)', + 'rgb(189, 55, 209)', + 'rgb(50, 224, 191)', + 'rgb(103, 12, 232)', + 'rgb(255, 0, 0)', + 'rgb(232, 144, 12)', + 'rgb(154, 13, 255)', + 'rgb(16, 12, 232)', + 'rgb(232, 176, 12)', + 'rgb(13, 255, 26)'], + yAxis: { + min: 0, + title: { + text: unit + } + }, + tooltip: { + headerFormat: '' + metric + '', + pointFormat: '' + + '', + footerFormat: '
{series.name}: {point.y:.1f} ' + unitAbb + '
', + shared: true, + useHTML: true + }, + plotOptions: { + column: { + pointPadding: 0.2, + borderWidth: 0 + } + }, + series: series, + credits: { + enabled: false + }, + }); + } + else { + countriesChart.categories = categories; + countriesChart.yAxis[0].update({ + title: { + text: unit + } + }); + countriesChart.tooltip.update({ + headerFormat: '' + metric + '', + pointFormat: '' + + '', + }); + $.each(series, function (i) { + if (countriesChart.series[i]) { + countriesChart.series[i].update({ + name: this.name, + data: this.data, + }, false); + } else { + countriesChart.addSeries({ + name: this.name, + data: this.data, + }, false); + } + }); + while (countriesChart.series.length > series.length) { + countriesChart.series[countriesChart.series.length - 1].remove(false); + } + countriesChart.redraw(); + } +} + + +function setValues(point, metric, unit) { + $('#info #flag').attr('class', 'flag ' + point.properties["hc-key"]); + $('#country').html(point.name); + $('#metricName').html(metric); + $('#metricValue').html(point.value + ' ' + unit); + $('#intructions').show(); +} + +function reset() { + $('#additionalData').hide(); + if (!$.isEmptyObject(countriesChart)) { + countriesChart = countriesChart.destroy(); + } +} diff --git a/player/vr-360/demo.js b/player/vr-360/demo.js index 6fbb9643..23d71026 100644 --- a/player/vr-360/demo.js +++ b/player/vr-360/demo.js @@ -9,9 +9,9 @@ var source = { dash: 'https://bitmovin-a.akamaihd.net/content/playhouse-vr/mpds/105560.mpd', hls: - 'https://bitmovin.com/player-content/playhouse-vr/m3u8s/105560.m3u8', + 'https://bitmovin-a.akamaihd.net/content/playhouse-vr/m3u8s/105560.m3u8', progressive: - 'https://bitmovin.com/player-content/playhouse-vr/progressive.mp4', + 'https://bitmovin-a.akamaihd.net/content/playhouse-vr/progressive.mp4', poster: 'https://bitmovin-a.akamaihd.net/content/playhouse-vr/poster.jpg', vr: { diff --git a/player/vr-360/js/script.js b/player/vr-360/js/script.js index f7250449..84bd5a52 100644 --- a/player/vr-360/js/script.js +++ b/player/vr-360/js/script.js @@ -14,8 +14,8 @@ var conf = { var source = { dash: 'https://bitmovin-a.akamaihd.net/content/playhouse-vr/mpds/105560.mpd', - hls: 'https://bitmovin.com/player-content/playhouse-vr/m3u8s/105560.m3u8', - progressive: 'https://bitmovin.com/player-content/playhouse-vr/progressive.mp4', + hls: 'https://bitmovin-a.akamaihd.net/content/playhouse-vr/m3u8s/105560.m3u8', + progressive: 'https://bitmovin-a.akamaihd.net/content/playhouse-vr/progressive.mp4', poster: 'https://bitmovin-a.akamaihd.net/content/playhouse-vr/poster.jpg', vr: { startupMode: '2d',
{series.name}: {point.y:.1f} ' + unitAbb + '