Skip to content

Commit

Permalink
Feature/reduce settings url length (#3918)
Browse files Browse the repository at this point in the history
* Initial commit; Added functionality to copyQueryUrl that reduces the exported string to 'externalSettings' + actually changed settings

* Removed hardcoded defaultSettings.js, replaced with dynamic method

* Changed externalSettings to also only reflect changed settings; Switched from using 'debug' as the delimiter between external and internal settigns to '+' as debug is no longer guaranteed in the string

* Fixed settings who are NaN by default not being filtered out of the URL

* Only copy array values in "copy settings url" functionality if an entry has changed

* Removed NaN check

* Added code to prevent cmcd array being part of the url if default was not changed

* Fixed error in function order, shortened array handling line

* Adjust description text for export settings
  • Loading branch information
ShikiSeiren authored Apr 22, 2022
1 parent 2bedb63 commit 25da43a
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 73 deletions.
4 changes: 4 additions & 0 deletions samples/dash-if-reference-player/app/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,10 @@ BS Information
border-left-color: #5cb85c ;
}

.bs-callout-warning {
border-left-color: #f0ad4e ;
}

.bs-callout-danger {
border-left-color: #CA0B00;
}
115 changes: 95 additions & 20 deletions samples/dash-if-reference-player/app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,20 @@ app.controller('DashController', ['$scope', '$window', 'sources', 'contributors'

$scope.conformanceViolations = [];

var defaultExternalSettings = {
mpd: encodeURIComponent('https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd'),
loop: true,
autoPlay: true,
drmToday: false,
forceQualitySwitchSelected: false,
drmPrioritiesEnabled: false,
languageAudio: null,
roleVideo: null,
languageText: null,
roleText: undefined,
forceTextStreaming: false
}

// metrics
$scope.videoBitrate = 0;
$scope.videoIndex = 0;
Expand Down Expand Up @@ -313,6 +327,8 @@ app.controller('DashController', ['$scope', '$window', 'sources', 'contributors'
// store a ref in window.player to provide an easy way to play with dash.js API
window.player = $scope.player = dashjs.MediaPlayer().create(); /* jshint ignore:line */

const defaultSettings = JSON.parse(JSON.stringify($scope.player.getSettings()));

$scope.player.on(dashjs.MediaPlayer.events.ERROR, function (e) { /* jshint ignore:line */
console.log(e);
if (!e.event) {
Expand Down Expand Up @@ -1414,18 +1430,21 @@ app.controller('DashController', ['$scope', '$window', 'sources', 'contributors'

/** Copy a URL containing the current settings as query Parameters to the Clipboard */
$scope.copyQueryUrl = function () {
var externalSettingsString = 'mpd=' + encodeURIComponent(decodeURIComponent($scope.selectedItem.url))
+ '&loop=' + $scope.loopSelected
+ '&autoPlay=' + $scope.autoPlaySelected
+ '&drmToday=' + $scope.drmToday
+ '&forceQualitySwitchSelected=' + $scope.forceQualitySwitchSelected
+ '&drmPrioritiesEnabled=' + $scope.prioritiesEnabled
+ '&languageAudio=' + $scope.initialSettings.audio
+ '&roleVideo=' + $scope.initialSettings.video
+ '&languageText=' + $scope.initialSettings.text
+ '&roleText=' + $scope.initialSettings.textRole
+ '&forceTextStreaming=' + $scope.initialSettings.forceTextStreaming
+ '&';
var currentExternalSettings = {
mpd: encodeURIComponent(decodeURIComponent($scope.selectedItem.url)),
loop: $scope.loopSelected,
autoPlay: $scope.autoPlaySelected,
drmToday: $scope.drmToday,
forceQualitySwitchSelected: $scope.forceQualitySwitchSelected,
drmPrioritiesEnabled: $scope.prioritiesEnabled,
languageAudio: $scope.initialSettings.audio,
roleVideo: $scope.initialSettings.video,
languageText: $scope.initialSettings.text,
roleText: $scope.textRole,
forceTextStreaming: $scope.initialSettings.forceTextStreaming
}

var externalSettingsString = $scope.toQueryString($scope.makeSettingDifferencesObject(currentExternalSettings, defaultExternalSettings));

$scope.handleRequestHeaders();
$scope.handleClearkeys();
Expand All @@ -1436,25 +1455,29 @@ app.controller('DashController', ['$scope', '$window', 'sources', 'contributors'
switch (drm.drmKeySystem) {
case 'com.microsoft.playready':
currentDrm = { 'playready': drm };
externalSettingsString += $scope.toQueryString(currentDrm) + '&';
externalSettingsString += '&' + $scope.toQueryString(currentDrm);
break;
case 'com.widevine.alpha':
currentDrm = { 'widevine': drm };
externalSettingsString += $scope.toQueryString(currentDrm) + '&';
externalSettingsString += '&' + $scope.toQueryString(currentDrm);
break;
case 'org.w3.clearkey':
currentDrm = { 'clearkey': drm };
externalSettingsString += $scope.toQueryString(currentDrm) + '&';
externalSettingsString += '&' + $scope.toQueryString(currentDrm);
break;
}
}
}
var currentSetting = $scope.player.getSettings();
currentSetting = $scope.makeSettingDifferencesObject(currentSetting, defaultSettings);

var url = window.location.protocol + '//' + window.location.host + window.location.pathname + '?';
var queryString = externalSettingsString + $scope.toQueryString(currentSetting);
var queryString = externalSettingsString + '+&' + $scope.toQueryString(currentSetting);

var urlString = url + queryString;

if (urlString.slice(-1) === '&') urlString = urlString.slice(0, -1);

$scope.checkQueryLength(urlString);

const element = document.createElement('textarea');
Expand All @@ -1465,6 +1488,57 @@ app.controller('DashController', ['$scope', '$window', 'sources', 'contributors'
document.body.removeChild(element);
}

$scope.makeSettingDifferencesObject = function (settings, defaultSettings) {
var settingDifferencesObject = {};

if (Array.isArray(settings)) {
console.log(settings)
return _arraysEqual(settings, defaultSettings) ? {} : settings;
}

for (var setting in settings) {
if (typeof defaultSettings[setting] === 'object' && defaultSettings[setting] !== null && !(defaultSettings[setting] instanceof Array)) {
settingDifferencesObject[setting] = this.makeSettingDifferencesObject(settings[setting], defaultSettings[setting], false);
}
else if(settings[setting] !== defaultSettings[setting]){
if(Array.isArray(settings[setting])){
settingDifferencesObject[setting] = _arraysEqual(settings[setting], defaultSettings[setting]) ? {} : settings[setting];
}
else {
settingDifferencesObject[setting] = settings[setting];
}

}
}

return settingDifferencesObject;
}

function _arraysEqual(a, b) {
if (a === b) {
return true;
}
if (a == null || b == null) {
return false;
}
if (a.length !== b.length) {
return false;
}

// If you don't care about the order of the elements inside
// the array, you should sort both arrays here.
// Please note that calling sort on an array will modify that array.
// you might want to clone your array first.

for (var i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) {
return false;
}
}

return true;
}

/** Transform the current Settings into a nested query-string format */
$scope.toQueryString = function (settings, prefix) {
var urlString = [];
Expand All @@ -1478,7 +1552,7 @@ app.controller('DashController', ['$scope', '$window', 'sources', 'contributors'
}
}
// Make the string, then remove all cases of && caused by empty settings
return urlString.join('&').split('&&').join('&');
return urlString.join('&').split(/&&*/).join('&');
}

/** Resolve nested query parameters */
Expand Down Expand Up @@ -1620,9 +1694,10 @@ app.controller('DashController', ['$scope', '$window', 'sources', 'contributors'
var [key, value] = handleExternalSettings[index].split('=') || '';
switch (key) {
case 'mpd':
$scope.selectedItem.url = decodeURIComponent(value);
$scope.selectedItem.url = decodeURIComponent(value).slice(0, -1);
break;
case 'loop':
$scope.loopSelected = $scope.parseBoolean(value);
$scope.loopSelected = this.parseBoolean(value);
break;
case 'autoPlay':
$scope.autoPlaySelected = this.parseBoolean(value);
Expand Down Expand Up @@ -1672,7 +1747,7 @@ app.controller('DashController', ['$scope', '$window', 'sources', 'contributors'
if (!currentQuery.includes('&')) {
return;
}
var passedSettings = currentQuery.slice(currentQuery.indexOf('debug'));
var passedSettings = currentQuery.slice(currentQuery.indexOf('+')).substring(1);
passedSettings = $scope.toSettingsObject(passedSettings)[0];
$scope.protectionData = $scope.toSettingsObject(currentQuery)[1];
$scope.player.updateSettings(passedSettings);
Expand Down
Loading

0 comments on commit 25da43a

Please sign in to comment.