Embed: mews: disable ABR when the viewer has selected a specific video track

This commit is contained in:
Cat 2021-08-05 15:33:09 +02:00 committed by Thulinma
parent e17420534d
commit 2f12c9fca7
7 changed files with 135 additions and 26 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -33,6 +33,8 @@ function MistVideo(streamName,options) {
height: false, //no set height height: false, //no set height
maxwidth: false, //no max width (apart from targets dimensions) maxwidth: false, //no max width (apart from targets dimensions)
maxheight: false, //no max height (apart from targets dimensions) maxheight: false, //no max height (apart from targets dimensions)
ABR_resize: true, //for supporting wrappers: when the player resizes, request a video track that matches the resolution best
ABR_bitrate: true, //for supporting wrappers: when there are playback issues, request a lower bitrate video track
MistVideoObject: false//no reference object is passed MistVideoObject: false//no reference object is passed
},options); },options);
if (options.host) { options.host = MistUtil.http.url.sanitizeHost(options.host); } if (options.host) { options.host = MistUtil.http.url.sanitizeHost(options.host); }
@ -417,6 +419,11 @@ function MistVideo(streamName,options) {
} }
} }
//check MistServer version if combined track selection is supported
if (MistVideo.options.ABR_bitrate && MistVideo.options.ABR_resize && (MistVideo.info && !MistVideo.info.selver)) {
//having both won't work, disable bitrate based ABR
MistVideo.options.ABR_bitrate = false;
}
if (MistVideo.choosePlayer()) { if (MistVideo.choosePlayer()) {
@ -720,8 +727,14 @@ function MistVideo(streamName,options) {
}; };
} }
MistVideo.player.resize = function(options){ MistVideo.player.resize = function(options,oldsize){
var container = MistVideo.video.currentTarget.querySelector(".mistvideo"); var container = MistVideo.video.currentTarget.querySelector(".mistvideo");
if (!oldsize) {
oldsize = {
width: MistVideo.video.clientWidth,
height: MistVideo.video.clientHeight
};
}
if (!container.hasAttribute("data-fullscreen")) { if (!container.hasAttribute("data-fullscreen")) {
//if ((!document.fullscreenElement) || (document.fullscreenElement.parentElement != MistVideo.video.currentTarget)) { //if ((!document.fullscreenElement) || (document.fullscreenElement.parentElement != MistVideo.video.currentTarget)) {
//first, base the size on the video dimensions //first, base the size on the video dimensions
@ -737,7 +750,7 @@ function MistVideo(streamName,options) {
width:window.innerWidth, width:window.innerWidth,
height: false, height: false,
reiterating: true reiterating: true
}); },oldsize);
} }
//check if the container is smaller than the video, if so, set the max size to the current container dimensions and reiterate //check if the container is smaller than the video, if so, set the max size to the current container dimensions and reiterate
@ -747,7 +760,7 @@ function MistVideo(streamName,options) {
width: false, width: false,
height: MistVideo.video.currentTarget.clientHeight, height: MistVideo.video.currentTarget.clientHeight,
reiterating: true reiterating: true
}); },oldsize);
} }
if ((MistVideo.video.currentTarget.clientWidth) && (MistVideo.video.currentTarget.clientWidth < size.width)) { if ((MistVideo.video.currentTarget.clientWidth) && (MistVideo.video.currentTarget.clientWidth < size.width)) {
//console.log("current w:",size.width,"target w:",MistVideo.video.currentTarget.clientWidth); //console.log("current w:",size.width,"target w:",MistVideo.video.currentTarget.clientWidth);
@ -755,20 +768,23 @@ function MistVideo(streamName,options) {
width: MistVideo.video.currentTarget.clientWidth, width: MistVideo.video.currentTarget.clientWidth,
height: false, height: false,
reiterating: true reiterating: true
}); },oldsize);
} }
MistVideo.log("Player size calculated: "+size.width+" x "+size.height+" px");
return true;
} }
else { else {
//this is the video that is in the main container, and resize this one to the screen dimensions //this is the video that is in the main container, and resize this one to the screen dimensions
this.setSize({ size = {
height: window.innerHeight, width: window.innerWidth,
width: window.innerWidth height: window.innerHeight
}); }
return true; this.setSize(size);
} }
if ((size.width != oldsize.width) || (size.height != oldsize.height)) {
MistVideo.log("Player size calculated: "+size.width+" x "+size.height+" px");
MistUtil.event.send("player_resize",size,MistVideo.video);
}
return true;
}; };
//if this is the main video //if this is the main video
@ -901,6 +917,43 @@ function MistVideo(streamName,options) {
} }
} }
if (MistVideo.player.api.ABR_resize && MistVideo.options.ABR_resize) {
var resizeratelimiter = false;
var newsize = false;
MistUtil.event.addListener(MistVideo.video,"player_resize",function(e){
if (MistVideo.options.setTracks && MistVideo.options.setTracks.video) {
//trackselection is not set to 'automatic'
return;
}
//Whenever the player resizes, start a timer. When the timer ends, request the correct video track. When the player resizes before the timer ends, stop it: track request is sent 1s after the player has the new size
if (resizeratelimiter) {
MistVideo.timers.stop(resizeratelimiter);
}
resizeratelimiter = MistVideo.timers.start(function(){
MistVideo.player.api.ABR_resize(e.message);
resizeratelimiter = false;
},1e3);
});
MistUtil.event.addListener(MistVideo.video,"trackSetToAuto",function(e){
//the user selected automatic track selection, update the track resolution
if (e.message == "video") {
MistVideo.player.api.ABR_resize({
width: MistVideo.video.clientWidth,
height: MistVideo.video.clientHeight
});
}
});
//initialize
MistVideo.player.api.ABR_resize({
width: MistVideo.video.clientWidth,
height: MistVideo.video.clientHeight
});
}
} }
for (var i in MistVideo.player.onreadylist) { for (var i in MistVideo.player.onreadylist) {

View file

@ -1383,7 +1383,11 @@ MistSkins["default"] = {
var checkboxes = {}; var checkboxes = {};
function changeToTracks(type,value){ function changeToTracks(type,value){
MistVideo.log("User selected "+type+" track with id "+value); if (value) { MistVideo.log("User selected "+type+" track with id "+value); }
else {
MistVideo.log("User selected automatic track selection for "+type);
MistUtil.event.send("trackSetToAuto",type,MistVideo.video);
}
if (!MistVideo.options.setTracks) { MistVideo.options.setTracks = {}; } if (!MistVideo.options.setTracks) { MistVideo.options.setTracks = {}; }
MistVideo.options.setTracks[type] = value; MistVideo.options.setTracks[type] = value;
@ -2430,6 +2434,12 @@ MistSkins.dev = {
} }
return new Promise(function(resolve,reject){resolve();},function(){}); return new Promise(function(resolve,reject){resolve();},function(){});
} }
},
"Current bitrate": function(){
if (MistVideo.player.monitor && ("currentBps" in MistVideo.player.monitor)) {
var out = MistUtil.format.bits(MistVideo.player.monitor.currentBps);
return out ? out+"ps" : out;
}
} }
}; };
var updates = []; var updates = [];

View file

@ -727,8 +727,6 @@ p.prototype.build = function (MistVideo,callback) {
} }
var data = new Uint8Array(e.data); var data = new Uint8Array(e.data);
if (data) { if (data) {
//if (new Date().getTime() - MistVideo.bootMs > 15e3) { data.fill(0,0,Math.floor(data.length*0.1)); } //corrupt the data pl0x :D
if (player.monitor && player.monitor.bitCounter) { if (player.monitor && player.monitor.bitCounter) {
for (var i in player.monitor.bitCounter) { for (var i in player.monitor.bitCounter) {
player.monitor.bitCounter[i] += e.data.byteLength*8; player.monitor.bitCounter[i] += e.data.byteLength*8;
@ -902,6 +900,7 @@ p.prototype.build = function (MistVideo,callback) {
if (player.sb) { player.sb.paused = true; } if (player.sb) { player.sb.paused = true; }
}, },
setTracks: function(obj){ setTracks: function(obj){
if (!MistUtil.object.keys(obj).length) { return; }
obj.type = "tracks"; obj.type = "tracks";
obj = MistUtil.object.extend({ obj = MistUtil.object.extend({
type: "tracks", type: "tracks",
@ -1063,22 +1062,62 @@ p.prototype.build = function (MistVideo,callback) {
}); });
} }
this.ABR = {
size: null,
bitrate: null,
generateString: function(type,raw){
switch (type) {
case "size": {
return "~"+[raw.width,raw.height].join("x");
}
case "bitrate": {
return "<"+Math.round(raw)+"bps,minbps";
}
default: {
throw "Unknown ABR type";
}
}
},
request: function(type,value){
this[type] = value;
var request = [];
if (this.bitrate !== null) {
request.push(this.generateString("bitrate",this.bitrate));
}
if (this.size !== null) {
request.push(this.generateString("size",this.size));
}
else {
request.push("maxbps");
}
return player.api.setTracks({
video: request.join(",|")
});
}
}
this.api.ABR_resize = function(size){
MistVideo.log("Requesting the video track with the resolution that best matches the player size");
player.ABR.request("size",size);
};
//ABR: monitor playback issues and switch to lower bitrate track if available //ABR: monitor playback issues and switch to lower bitrate track if available
//NB: this ABR requests a lower bitrate if needed, but it can never go back up
this.monitor = { this.monitor = {
bitCounter: [], bitCounter: [],
bitsSince: [], bitsSince: [],
currentBps: null, currentBps: null,
nWaiting: 0, nWaiting: 0,
nWaitingThreshold: 3, nWaitingThreshold: 3,
listener: MistUtil.event.addListener(video,"waiting",function(){ listener: MistVideo.options.ABR_bitrate ? MistUtil.event.addListener(video,"waiting",function(){
player.monitor.nWaiting++; player.monitor.nWaiting++;
if (player.monitor.nWaiting >= player.monitor.nWaitingThreshold) { if (player.monitor.nWaiting >= player.monitor.nWaitingThreshold) {
player.monitor.nWaiting = 0; player.monitor.nWaiting = 0;
MistVideo.log("ABR threshold triggered, requesting lower quality");
player.monitor.action(); player.monitor.action();
} }
}), }) : null,
getBitRate: function(){ getBitRate: function(){
if (player.sb && !player.sb.paused) { if (player.sb && !player.sb.paused) {
@ -1098,18 +1137,20 @@ p.prototype.build = function (MistVideo,callback) {
var dt = new Date().getTime() - since; var dt = new Date().getTime() - since;
this.currentBps = bits / (dt*1e-3); this.currentBps = bits / (dt*1e-3);
//console.log(MistUtil.format.bytes(this.currentBps)+"its/s"); //console.log(MistUtil.format.bits(this.currentBps)+"its/s");
} }
MistVideo.timers.start(function(){ MistVideo.timers.start(function(){
player.monitor.getBitRate(); player.monitor.getBitRate();
},500); },500);
}, },
action: function(){ action: function(){
player.api.setTracks({video:"max<"+Math.round(this.currentBps)+"bps"}); if (MistVideo.options.setTracks && MistVideo.options.setTracks.video) {
//a video track was selected by the user, do not change it
return;
}
MistVideo.log("ABR threshold triggered, requesting lower quality");
player.ABR.request("bitrate",this.currentBps);
} }
}; };
this.monitor.getBitRate(); this.monitor.getBitRate();
}; };

View file

@ -725,6 +725,11 @@ p.prototype.build = function (MistVideo,callback) {
f(); f();
} }
me.api.ABR_resize = function(size){
MistVideo.log("Requesting the video track with the resolution that best matches the player size");
me.api.setTracks({video:"~"+[size.width,size.height].join("x")});
};
me.api.unload = function(){ me.api.unload = function(){
try { try {
me.webrtc.stop(); me.webrtc.stop();