Merge branch 'development' into LTS_development

This commit is contained in:
Thulinma 2020-08-11 19:27:15 +02:00
commit 8bb72a30ea
12 changed files with 889 additions and 414 deletions

File diff suppressed because one or more lines are too long

View file

@ -8,7 +8,7 @@ svg.icon.loading{z-index:-1;position:absolute;top:0;left:0;right:0;bottom:0;marg
[data-loading] svg.icon.loading{z-index:2;opacity:1}
[data-loading-css] .mistvideo-controls{display:none}
[data-hidecursor],[data-hidecursor] *,[data-hidecursor] .mistvideo-pointer{cursor:none}
.mistvideo-error{display:none;position:absolute;top:0;left:0;right:0;bottom:0;background-color:$background;align-items:center;justify-content:center;text-align:center;z-index:2;cursor:default;min-height:fit-content;min-width:fit-content}
.mistvideo-error{display:none;position:absolute;top:0;left:0;right:0;bottom:0;background-color:$background;align-items:center;justify-content:center;text-align:center;z-index:2;cursor:default;min-height:fit-content;min-width:fit-content;height:100%}
.mistvideo-error.show{display:flex}
.mistvideo-error .message{max-width:80%}
.mistvideo-error .message .details table{text-align:left}
@ -62,8 +62,11 @@ svg.icon .stroke,svg.icon.stroke{stroke:$stroke;vector-effect:non-scaling-stroke
svg.icon.off .toggle .fill,svg.icon.off .toggle .semiFill,svg.icon.off .toggle.fill,svg.icon.off .toggle.semiFill{fill:none}
svg.icon .spin,svg.icon.spin{animation:mistvideo-spin 1.5s infinite linear;transform-origin:50% 50%}
.vjs-text-track-display{pointer-events:none}
.vjs-controls-disabled .vjs-control-bar,.vjs-error .vjs-control-bar,.vjs-hidden,.vjs-using-native-controls .vjs-control-bar{display:none!important}
.vjs-controls-disabled .vjs-big-play-button,.vjs-controls-disabled .vjs-loading-spinner,.vjs-error .vjs-big-play-button,.vjs-has-started .vjs-big-play-button,.vjs-using-native-controls .vjs-big-play-button{display:none}
.mistvideo{line-height:1.2;font-size:14.5px}
.mistvideo svg{margin:2.5px}
.mistvideo-video{display:flex;align-items:center;justify-content:center}
.mistvideo-background{background-color:$background}
.mistvideo-totalTime:before{content:'/';margin:.2em}
.mistvideo-progress{padding:10px 0;margin:-10px 0;z-index:2}
@ -83,9 +86,11 @@ svg.icon.timeout{display:inline-block;height:1em;width:1em;margin:0;margin-right
.mistvideo-secondaryVideo{z-index:1;position:absolute;right:0;top:0;width:50%;height:50%;max-width:fit-content;max-height:fit-content}
.mistvideo-polling{display:inline-block;position:relative;width:25px;height:25px}
.mistvideo-polling svg.icon.loading{z-index:0;opacity:1}
.mistvideo:not([data-hide-submenu]) .mistvideo-hoverWindow:hover>svg.icon.settings .fill,.mistvideo[data-fullscreen] svg.icon.fullscreen .fill,.mistvideo[data-show-submenu] svg.icon.settings .fill{fill:$accent}
.mistvideo[data-show-submenu] .mistvideo-submenu{right:5px}
.mistvideo[data-hide-submenu] .mistvideo-submenu{right:-1000px!important}
.mistvideo[data-show-submenu] .mistvideo-controls{bottom:0}
.mistvideo-error[data-passive]{bottom:auto;left:auto;margin:.5em;padding:.5em}
.mistvideo-error[data-passive]{bottom:auto;left:auto;height:auto;margin:.5em;padding:.5em}
.mistvideo-error[data-passive] .message{max-width:none}
.mistvideo-error .mistvideo-buttoncontainer{display:flex;flex-flow:row nowrap;justify-content:center}
.mistvideo-error .mistvideo-buttoncontainer .mistvideo-button{white-space:nowrap}

View file

@ -8,7 +8,7 @@ svg.icon.loading{z-index:-1;position:absolute;top:0;left:0;right:0;bottom:0;marg
[data-loading] svg.icon.loading{z-index:2;opacity:1}
[data-loading-css] .mistvideo-controls{display:none}
[data-hidecursor],[data-hidecursor] *,[data-hidecursor] .mistvideo-pointer{cursor:none}
.mistvideo-error{display:none;position:absolute;top:0;left:0;right:0;bottom:0;background-color:$background;align-items:center;justify-content:center;text-align:center;z-index:2;cursor:default;min-height:fit-content;min-width:fit-content}
.mistvideo-error{display:none;position:absolute;top:0;left:0;right:0;bottom:0;background-color:$background;align-items:center;justify-content:center;text-align:center;z-index:2;cursor:default;min-height:fit-content;min-width:fit-content;height:100%}
.mistvideo-error.show{display:flex}
.mistvideo-error .message{max-width:80%}
.mistvideo-error .message .details table{text-align:left}
@ -62,8 +62,11 @@ svg.icon .stroke,svg.icon.stroke{stroke:$stroke;vector-effect:non-scaling-stroke
svg.icon.off .toggle .fill,svg.icon.off .toggle .semiFill,svg.icon.off .toggle.fill,svg.icon.off .toggle.semiFill{fill:none}
svg.icon .spin,svg.icon.spin{animation:mistvideo-spin 1.5s infinite linear;transform-origin:50% 50%}
.vjs-text-track-display{pointer-events:none}
.vjs-controls-disabled .vjs-control-bar,.vjs-error .vjs-control-bar,.vjs-hidden,.vjs-using-native-controls .vjs-control-bar{display:none!important}
.vjs-controls-disabled .vjs-big-play-button,.vjs-controls-disabled .vjs-loading-spinner,.vjs-error .vjs-big-play-button,.vjs-has-started .vjs-big-play-button,.vjs-using-native-controls .vjs-big-play-button{display:none}
.mistvideo{line-height:1.2;font-size:14.5px}
.mistvideo svg{margin:2.5px}
.mistvideo-video{display:flex;align-items:center;justify-content:center}
.mistvideo-background{background-color:$background}
.mistvideo-totalTime:before{content:'/';margin:.2em}
.mistvideo-progress{padding:10px 0;margin:-10px 0;z-index:2}
@ -83,9 +86,11 @@ svg.icon.timeout{display:inline-block;height:1em;width:1em;margin:0;margin-right
.mistvideo-secondaryVideo{z-index:1;position:absolute;right:0;top:0;width:50%;height:50%;max-width:fit-content;max-height:fit-content}
.mistvideo-polling{display:inline-block;position:relative;width:25px;height:25px}
.mistvideo-polling svg.icon.loading{z-index:0;opacity:1}
.mistvideo:not([data-hide-submenu]) .mistvideo-hoverWindow:hover>svg.icon.settings .fill,.mistvideo[data-fullscreen] svg.icon.fullscreen .fill,.mistvideo[data-show-submenu] svg.icon.settings .fill{fill:$accent}
.mistvideo[data-show-submenu] .mistvideo-submenu{right:5px}
.mistvideo[data-hide-submenu] .mistvideo-submenu{right:-1000px!important}
.mistvideo[data-show-submenu] .mistvideo-controls{bottom:0}
.mistvideo-error[data-passive]{bottom:auto;left:auto;margin:.5em;padding:.5em}
.mistvideo-error[data-passive]{bottom:auto;left:auto;height:auto;margin:.5em;padding:.5em}
.mistvideo-error[data-passive] .message{max-width:none}
.mistvideo-error .mistvideo-buttoncontainer{display:flex;flex-flow:row nowrap;justify-content:center}
.mistvideo-error .mistvideo-buttoncontainer .mistvideo-button{white-space:nowrap}

View file

@ -1 +1 @@
mistplayers.html5={name:"HTML5 video player",mimes:["html5/application/vnd.apple.mpegurl","html5/video/mp4","html5/video/ogg","html5/video/webm","html5/audio/mp3","html5/audio/webm","html5/audio/ogg","html5/audio/wav"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return MistUtil.array.indexOf(this.mimes,t)==-1?false:true},isBrowserSupported:function(t,e,i){if(location.protocol!=MistUtil.http.url.split(e.url).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(e.url).protocol=="http:"){i.log("This page was loaded over file://, the player might not behave as intended.")}else{i.log("HTTP/HTTPS mismatch for this source");return false}}if(t=="html5/application/vnd.apple.mpegurl"){var r=MistUtil.getAndroid();if(r&&parseFloat(r)<7){i.log("Skipping native HLS as videojs will do better");return false}}var a=false;var n=t.split("/");n.shift();try{n=n.join("/");function o(t){var e=document.createElement("video");if(e&&e.canPlayType(t)!=""){a=e.canPlayType(t)}return a}if(n=="video/mp4"){function s(t){function e(e){return("0"+t.init.charCodeAt(e).toString(16)).slice(-2)}switch(t.codec){case"AAC":return"mp4a.40.2";case"MP3":return"mp3";case"AC3":return"ec-3";case"H264":return"avc1."+e(1)+e(2)+e(3);case"HEVC":return"hev1."+e(1)+e(6)+e(7)+e(8)+e(9)+e(10)+e(11)+e(12);default:return t.codec.toLowerCase()}}var l={};for(var p in i.info.meta.tracks){if(i.info.meta.tracks[p].type!="meta"){l[s(i.info.meta.tracks[p])]=1}}l=MistUtil.object.keys(l);if(l.length){if(l.length>e.simul_tracks){var u=0;for(var p in l){var c=o(n+';codecs="'+l[p]+'"');if(c){u++}}return u>=e.simul_tracks}n+=';codecs="'+l.join(",")+'"'}}a=o(n)}catch(t){}return a},player:function(){this.onreadylist=[]},mistControls:true};var p=mistplayers.html5.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=t.source.type.split("/");i.shift();var r=document.createElement("video");r.setAttribute("crossorigin","anonymous");var a=document.createElement("source");a.setAttribute("src",t.source.url);r.source=a;r.appendChild(a);a.type=i.join("/");var n=["autoplay","loop","poster"];for(var o in n){var s=n[o];if(t.options[s]){r.setAttribute(s,t.options[s]===true?"":t.options[s])}}if(t.options.muted){r.muted=true}if(t.options.controls=="stock"){r.setAttribute("controls","")}if(t.info.type=="live"){r.loop=false}if("Proxy"in window&&"Reflect"in window){var l={get:{},set:{}};t.player.api=new Proxy(r,{get:function(t,e,i){if(e in l.get){return l.get[e].apply(t,arguments)}var r=t[e];if(typeof r==="function"){return function(){return r.apply(t,arguments)}}return r},set:function(t,e,i){if(e in l.set){return l.set[e].call(t,i)}return t[e]=i}});if(t.source.type=="html5/audio/mp3"){l.set.currentTime=function(){t.log("Seek attempted, but MistServer does not currently support seeking in MP3.");return false}}if(t.info.type=="live"){l.get.duration=function(){var e=0;if(this.buffered.length){e=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-t.player.api.lastProgress.getTime())*.001;return e+i-t.player.api.liveOffset};l.set.currentTime=function(e){var i=e-t.player.api.duration;if(i>0){i=0}t.player.api.liveOffset=i;t.log("Seeking to "+MistUtil.format.time(e)+" ("+Math.round(i*-10)/10+"s from live)");var r={startunix:i};if(i==0){r={}}t.player.api.setSource(MistUtil.http.url.addParam(t.source.url,r))};MistUtil.event.addListener(r,"progress",function(){t.player.api.lastProgress=new Date});t.player.api.lastProgress=new Date;t.player.api.liveOffset=0;MistUtil.event.addListener(r,"pause",function(){t.player.api.pausedAt=new Date});l.get.play=function(){return function(){if(t.player.api.paused&&t.player.api.pausedAt&&new Date-t.player.api.pausedAt>5e3){r.load();t.log("Reloading source..")}return r.play.apply(r,arguments)}};if(t.source.type=="html5/video/mp4"){l.get.currentTime=function(){return this.currentTime-t.player.api.liveOffset+t.info.lastms*.001}}}else{if(!isFinite(r.duration)){var p=0;for(var o in t.info.meta.tracks){p=Math.max(p,t.info.meta.tracks[o].lastms)}l.get.duration=function(){if(isFinite(this.duration)){return this.duration}return p*.001}}}}else{t.player.api=r}t.player.api.setSource=function(t){if(t!=this.source.src){this.source.src=t;this.load()}};t.player.api.setSubtitle=function(t){var e=r.getElementsByTagName("track");for(var i=e.length-1;i>=0;i--){r.removeChild(e[i])}if(t){var a=document.createElement("track");r.appendChild(a);a.kind="subtitles";a.label=t.label;a.srclang=t.lang;a.src=t.src;a.setAttribute("default","")}};t.player.setSize=function(t){this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e(r)};
mistplayers.html5={name:"HTML5 video player",mimes:["html5/application/vnd.apple.mpegurl","html5/video/mp4","html5/video/ogg","html5/video/webm","html5/audio/mp3","html5/audio/webm","html5/audio/ogg","html5/audio/wav"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return MistUtil.array.indexOf(this.mimes,t)==-1?false:true},isBrowserSupported:function(t,e,i){if(location.protocol!=MistUtil.http.url.split(e.url).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(e.url).protocol=="http:"){i.log("This page was loaded over file://, the player might not behave as intended.")}else{i.log("HTTP/HTTPS mismatch for this source");return false}}if(t=="html5/application/vnd.apple.mpegurl"){var r=MistUtil.getAndroid();if(r&&parseFloat(r)<7){i.log("Skipping native HLS as videojs will do better");return false}}var a=false;var n=t.split("/");n.shift();try{n=n.join("/");function o(t){var e=document.createElement("video");if(e&&e.canPlayType(t)!=""){a=e.canPlayType(t)}return a}if(n=="video/mp4"){function s(t){function e(e){return("0"+t.init.charCodeAt(e).toString(16)).slice(-2)}switch(t.codec){case"AAC":return"mp4a.40.2";case"MP3":return"mp3";case"AC3":return"ec-3";case"H264":return"avc1."+e(1)+e(2)+e(3);case"HEVC":return"hev1."+e(1)+e(6)+e(7)+e(8)+e(9)+e(10)+e(11)+e(12);default:return t.codec.toLowerCase()}}var l={};for(var p in i.info.meta.tracks){if(i.info.meta.tracks[p].type!="meta"){l[s(i.info.meta.tracks[p])]=1}}l=MistUtil.object.keys(l);if(l.length){if(l.length>e.simul_tracks){var u=0;for(var p in l){var c=o(n+';codecs="'+l[p]+'"');if(c){u++}}return u>=e.simul_tracks}n+=';codecs="'+l.join(",")+'"'}}a=o(n)}catch(t){}return a},player:function(){this.onreadylist=[]},mistControls:true};var p=mistplayers.html5.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=t.source.type.split("/");i.shift();var r=document.createElement("video");r.setAttribute("crossorigin","anonymous");r.setAttribute("playsinline","");var a=document.createElement("source");a.setAttribute("src",t.source.url);r.source=a;r.appendChild(a);a.type=i.join("/");var n=["autoplay","loop","poster"];for(var o in n){var s=n[o];if(t.options[s]){r.setAttribute(s,t.options[s]===true?"":t.options[s])}}if(t.options.muted){r.muted=true}if(t.options.controls=="stock"){r.setAttribute("controls","")}if(t.info.type=="live"){r.loop=false}if("Proxy"in window&&"Reflect"in window){var l={get:{},set:{}};t.player.api=new Proxy(r,{get:function(t,e,i){if(e in l.get){return l.get[e].apply(t,arguments)}var r=t[e];if(typeof r==="function"){return function(){return r.apply(t,arguments)}}return r},set:function(t,e,i){if(e in l.set){return l.set[e].call(t,i)}return t[e]=i}});if(t.source.type=="html5/audio/mp3"){l.set.currentTime=function(){t.log("Seek attempted, but MistServer does not currently support seeking in MP3.");return false}}if(t.info.type=="live"){l.get.duration=function(){var e=0;if(this.buffered.length){e=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-t.player.api.lastProgress.getTime())*.001;return e+i-t.player.api.liveOffset};l.set.currentTime=function(e){var i=e-t.player.api.duration;if(i>0){i=0}t.player.api.liveOffset=i;t.log("Seeking to "+MistUtil.format.time(e)+" ("+Math.round(i*-10)/10+"s from live)");var r={startunix:i};if(i==0){r={}}t.player.api.setSource(MistUtil.http.url.addParam(t.source.url,r))};MistUtil.event.addListener(r,"progress",function(){t.player.api.lastProgress=new Date});t.player.api.lastProgress=new Date;t.player.api.liveOffset=0;MistUtil.event.addListener(r,"pause",function(){t.player.api.pausedAt=new Date});l.get.play=function(){return function(){if(t.player.api.paused&&t.player.api.pausedAt&&new Date-t.player.api.pausedAt>5e3){r.load();t.log("Reloading source..")}return r.play.apply(r,arguments)}};if(t.source.type=="html5/video/mp4"){l.get.currentTime=function(){return this.currentTime-t.player.api.liveOffset+t.info.lastms*.001}}}else{if(!isFinite(r.duration)){var p=0;for(var o in t.info.meta.tracks){p=Math.max(p,t.info.meta.tracks[o].lastms)}l.get.duration=function(){if(isFinite(this.duration)){return this.duration}return p*.001}}}}else{t.player.api=r}t.player.api.setSource=function(t){if(t!=this.source.src){this.source.src=t;this.load()}};t.player.api.setSubtitle=function(t){var e=r.getElementsByTagName("track");for(var i=e.length-1;i>=0;i--){r.removeChild(e[i])}if(t){var a=document.createElement("track");r.appendChild(a);a.kind="subtitles";a.label=t.label;a.srclang=t.lang;a.src=t.src;a.setAttribute("default","")}};t.player.setSize=function(t){this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e(r)};

File diff suppressed because one or more lines are too long

View file

@ -402,7 +402,7 @@ function MistVideo(streamName,options) {
averagingSteps: 20, //the amount of measurements that are saved.
threshold: function(){ //returns the score threshold below which the "action" should be taken
if (this.MistVideo.source.type == "webrtc") {
return 0.97;
return 0.95;
}
return 0.75;
},

View file

@ -306,6 +306,7 @@ MistSkins["default"] = {
//also do something useful
//show submenu
MistVideo.container.setAttribute("data-show-submenu","");
MistVideo.container.removeAttribute("data-hide-submenu");
MistVideo.container.removeAttribute("data-hidecursor");
//onmouseout, hide submenu
var f = function(){
@ -676,6 +677,8 @@ MistSkins["default"] = {
var MistVideo = this;
var button = this.skin.icons.build("fullscreen",16);
MistUtil.class.remove(button,"fullscreen");
MistUtil.class.add(button,"draggable-icon");
container.appendChild(button);
button.style.alignSelf = "flex-end";
button.style.position = "absolute";
@ -1200,8 +1203,24 @@ MistSkins["default"] = {
}
},
settings: function(){
var MistVideo = this;
var button = this.skin.icons.build("settings");
button.setAttribute("onclick","");
var touchmode = (typeof document.ontouchstart != "undefined");
MistUtil.event.addListener(button,"click",function(){
if (MistVideo.container.hasAttribute("data-show-submenu")) {
if (touchmode) {
MistVideo.container.setAttribute("data-hide-submenu",""); //don't show even when hovering
}
MistVideo.container.removeAttribute("data-show-submenu");
}
else {
MistVideo.container.setAttribute("data-show-submenu","");
MistVideo.container.removeAttribute("data-hide-submenu");
}
});
return button;
},
loop: function(){
@ -1840,6 +1859,7 @@ MistSkins["default"] = {
else {
container.removeAttribute("data-passive");
}
if (showingError) { container.clear(); } //stop any countdowns still running
showingError = (options.passive ? "passive" : true);
since = (new Date()).getTime();

View file

@ -5,6 +5,11 @@
.mistvideo svg {
margin: 2.5px;
}
.mistvideo-video { /* keep video centered if container is larger (when fillSpace:true) */
display: flex;
align-items: center;
justify-content: center;
}
.mistvideo-background { background-color: $background; }
.mistvideo-totalTime:before {
content: '/';
@ -106,15 +111,25 @@ svg.icon.timeout {
z-index: 0;
opacity: 1;
}
.mistvideo:not([data-hide-submenu]) .mistvideo-hoverWindow:hover >svg.icon.settings .fill,
.mistvideo[data-show-submenu] svg.icon.settings .fill,
.mistvideo[data-fullscreen] svg.icon.fullscreen .fill {
fill: $accent;
}
.mistvideo[data-show-submenu] .mistvideo-submenu {
right: 5px;
}
.mistvideo[data-hide-submenu] .mistvideo-submenu {
right: -1000px !important;
}
.mistvideo[data-show-submenu] .mistvideo-controls {
bottom: 0;
}
.mistvideo-error[data-passive] {
bottom: auto;
left: auto;
height: auto;
margin: 0.5em;
padding: 0.5em;
}

View file

@ -64,6 +64,7 @@ svg.icon.loading {
cursor: default; /*cursor won't show up if it was hidden because the mousemove event can no longer reach the video element*/
min-height: fit-content; /*overflow if needed*/
min-width: fit-content;
height: 100%;
}
.mistvideo-error.show { display: flex; }
.mistvideo-error .message { max-width: 80%; }
@ -226,3 +227,16 @@ svg.icon.spin, svg.icon .spin {
.vjs-text-track-display {
pointer-events: none;
}
.vjs-controls-disabled .vjs-control-bar,
.vjs-using-native-controls .vjs-control-bar,
.vjs-error .vjs-control-bar,
.vjs-hidden {
display: none !important;
}
.vjs-controls-disabled .vjs-loading-spinner,
.vjs-controls-disabled .vjs-big-play-button,
.vjs-has-started .vjs-big-play-button,
.vjs-using-native-controls .vjs-big-play-button,
.vjs-error .vjs-big-play-button {
display: none;
}

File diff suppressed because one or more lines are too long

View file

@ -108,6 +108,8 @@ p.prototype.build = function (MistVideo,callback) {
//TODO verify: not required if player is loaded from same domain as it should always be when not in dev mode?
video.setAttribute("crossorigin","anonymous");//required for subs, breaks ogg?
video.setAttribute("playsinline",""); //iphones. effin' iphones.
var source = document.createElement("source");
source.setAttribute("src",MistVideo.source.url);
video.source = source;

View file

@ -40,6 +40,7 @@ p.prototype.build = function (MistVideo,callback) {
}
var video = document.createElement("video");
video.setAttribute("playsinline",""); //iphones. effin' iphones.
//apply options
var attrs = ["autoplay","loop","poster"];
@ -228,6 +229,34 @@ p.prototype.build = function (MistVideo,callback) {
};
this.connect = function(callback){
//chrome on android has a bug where H264 is not available immediately after the tab is opened: https://bugs.chromium.org/p/webrtc/issues/detail?id=11620
//this workaround tries 5x with 100ms intervals before continuing
function checkH264(n){
var p = new Promise(function(resolve,reject){
function promise_body(n){
var r = RTCRtpReceiver.getCapabilities("video");
for (var i = 0; i < r.codecs.length; i++) {
if (r.codecs[i].mimeType == "video/H264") {
resolve("H264 found :)");
return;
}
}
if (n > 0) { setTimeout(function(){
promise_body(n-1);
},100) }
else {
reject("H264 not found :(");
}
}
promise_body(n);
});
return p;
};
checkH264(5).catch(function(){
MistVideo.log("Beware: this device does not seem to be able to play H264.");
}).finally(function(){
thisWebRTCPlayer.isConnecting = true;
thisWebRTCPlayer.signaling = new WebRTCSignaling(thisWebRTCPlayer.on_event);
thisWebRTCPlayer.peerConn = new RTCPeerConnection();
@ -235,6 +264,7 @@ p.prototype.build = function (MistVideo,callback) {
video.srcObject = ev.streams[0];
if (callback) { callback(); }
};
});
};
this.play = function(){