Embed:
- fixes as a result of documentation, fixed secondaryVideo - added muted option, changing tracks sets options.setTracks - no positive values for startunix when live seeking - dashjs tracks updated, videojs display tweaked - fixes for track selection and live seeking
This commit is contained in:
parent
0a1b00cb5e
commit
998d7c6d03
22 changed files with 283 additions and 119 deletions
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,7 @@
|
|||
.mistvideo{display:inline-block;position:relative;color:$stroke;font-family:sans-serif;background-color:#000;justify-content:center;align-items:center}
|
||||
.mistvideo-controls{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
||||
.mistvideo.novideo{overflow:visible}
|
||||
.mistvideo-video{overflow:hidden}
|
||||
.mistvideo-video{overflow:hidden;outline:0}
|
||||
svg.icon.loading{z-index:-1;position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;opacity:0}
|
||||
[data-loading]{position:relative}
|
||||
[data-loading=stalled] svg.icon.loading{transition:opacity 0s 3s}
|
||||
|
@ -61,6 +61,7 @@ svg.icon .semiFill,svg.icon.semiFill{fill:$semiFill}
|
|||
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:spin 1.5s infinite linear;transform-origin:50% 50%}
|
||||
.vjs-text-track-display{pointer-events:none}
|
||||
.mistvideo{line-height:1.2;font-size:14.5px}
|
||||
.mistvideo svg{margin:2.5px}
|
||||
.mistvideo-background{background-color:$background}
|
||||
|
@ -79,7 +80,7 @@ svg.icon.timeout{display:inline-block;height:1em;width:1em;margin:0;margin-right
|
|||
.mist.largeplay,.mist.muted{position:absolute;opacity:.5}
|
||||
.mist.largeplay{top:50%;left:0;right:0;margin:auto;transform:translateY(-50%)}
|
||||
.mist.muted{top:0;right:0;margin:1em}
|
||||
.mistvideo-secondaryVideo{z-index:1;width:50%;height:50%}
|
||||
.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[data-show-submenu] .mistvideo-submenu{right:5px}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.mistvideo{display:inline-block;position:relative;color:$stroke;font-family:sans-serif;background-color:#000;justify-content:center;align-items:center}
|
||||
.mistvideo-controls{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
|
||||
.mistvideo.novideo{overflow:visible}
|
||||
.mistvideo-video{overflow:hidden}
|
||||
.mistvideo-video{overflow:hidden;outline:0}
|
||||
svg.icon.loading{z-index:-1;position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;opacity:0}
|
||||
[data-loading]{position:relative}
|
||||
[data-loading=stalled] svg.icon.loading{transition:opacity 0s 3s}
|
||||
|
@ -61,6 +61,7 @@ svg.icon .semiFill,svg.icon.semiFill{fill:$semiFill}
|
|||
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:spin 1.5s infinite linear;transform-origin:50% 50%}
|
||||
.vjs-text-track-display{pointer-events:none}
|
||||
.mistvideo{line-height:1.2;font-size:14.5px}
|
||||
.mistvideo svg{margin:2.5px}
|
||||
.mistvideo-background{background-color:$background}
|
||||
|
@ -79,7 +80,7 @@ svg.icon.timeout{display:inline-block;height:1em;width:1em;margin:0;margin-right
|
|||
.mist.largeplay,.mist.muted{position:absolute;opacity:.5}
|
||||
.mist.largeplay{top:50%;left:0;right:0;margin:auto;transform:translateY(-50%)}
|
||||
.mist.muted{top:0;right:0;margin:1em}
|
||||
.mistvideo-secondaryVideo{z-index:1;width:50%;height:50%}
|
||||
.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[data-show-submenu] .mistvideo-submenu{right:5px}
|
||||
|
|
|
@ -1 +1 @@
|
|||
mistplayers.dashjs={name:"Dash.js player",mimes:["dash/video/mp4"],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){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"){i.log("This source ("+t+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){this.onreadylist=[]},scriptsrc:function(t){return t+"/dashjs.js"}};var p=mistplayers.dashjs.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=this;this.onDashLoad=function(){if(t.destroyed){return}t.log("Building DashJS player..");var r=document.createElement("video");if("Proxy"in window){var a={get:{},set:{}};t.player.api=new Proxy(r,{get:function(t,e,i){if(e in a.get){return a.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 a.set){return a.set[e].call(t,i)}return t[e]=i}});if(t.info.type=="live"){a.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+-1*t.player.api.liveOffset+45};a.set.currentTime=function(e){var i=e-t.player.api.duration;t.log("Seeking to "+MistUtil.format.time(e)+" ("+Math.round(i*-10)/10+"s from live)");t.video.currentTime=e};MistUtil.event.addListener(r,"progress",function(){t.player.api.lastProgress=new Date});t.player.api.lastProgress=new Date;t.player.api.liveOffset=0}}else{i.api=r}if(t.options.autoplay){r.setAttribute("autoplay","")}if(t.options.loop&&t.info.type!="live"){r.setAttribute("loop","")}if(t.options.poster){r.setAttribute("poster",t.options.poster)}if(t.options.controls=="stock"){r.setAttribute("controls","")}var s=dashjs.MediaPlayer().create();s.initialize(r,t.source.url,t.options.autoplay);i.dash=s;var o=["METRIC_ADDED","METRIC_CHANGED","METRICS_CHANGED","FRAGMENT_LOADING_STARTED","FRAGMENT_LOADING_COMPLETED","LOG","PLAYBACK_TIME_UPDATED","PLAYBACK_PROGRESS"];for(var n in dashjs.MediaPlayer.events){if(o.indexOf(n)<0){i.dash.on(dashjs.MediaPlayer.events[n],function(e){t.log("Player event fired: "+e.type)})}}t.player.setSize=function(t){this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};t.player.api.setSource=function(e){t.player.dash.attachSource(e)};t.player.api.setTrack=function(e,r){var a=MistUtil.tracks.parse(t.info.meta.tracks);if(!(e in a)||!(r in a[e])&&r!=0){t.log("Skipping trackselection of "+e+" track "+r+" because it does not exist");return}var s=i.dash.getBitrateInfoListFor("video").length-1;for(var o in t.info.meta.tracks){var n=t.info.meta.tracks[o];if(n.type==e){if(n.trackid==r){break}s--}}i.dash.setAutoSwitchQualityFor(e,false);i.dash.setFastSwitchEnabled(true);i.dash.setQualityFor(e,s)};i.dash.on("qualityChangeRendered",function(e){var r=i.dash.getBitrateInfoListFor("video").length-1;var a;for(var s in t.info.meta.tracks){var o=t.info.meta.tracks[s];if(o.type==e.mediaType){if(e.newQuality==r){a=o.trackid;break}r--}}MistUtil.event.send("playerUpdate_trackChanged",{type:e.mediaType,trackid:a},t.video)});MistUtil.event.addListener(r,"progress",function(e){if(t.container.getAttribute("data-loading")=="stalled"){t.container.removeAttribute("data-loading")}});i.api.unload=function(){i.dash.reset()};t.log("Built html");e(r)};if("dashjs"in window){this.onDashLoad()}else{var r=MistUtil.scripts.insert(t.urlappend(mistplayers.dashjs.scriptsrc(t.options.host)),{onerror:function(e){var i="Failed to load dashjs.js";if(e.message){i+=": "+e.message}t.showError(i)},onload:i.onDashLoad},t)}};
|
||||
mistplayers.dashjs={name:"Dash.js player",mimes:["dash/video/mp4"],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){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"){i.log("This source ("+t+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){this.onreadylist=[]},scriptsrc:function(t){return t+"/dashjs.js"}};var p=mistplayers.dashjs.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=this;this.onDashLoad=function(){if(t.destroyed){return}t.log("Building DashJS player..");var r=document.createElement("video");if("Proxy"in window){var a={get:{},set:{}};t.player.api=new Proxy(r,{get:function(t,e,i){if(e in a.get){return a.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 a.set){return a.set[e].call(t,i)}return t[e]=i}});if(t.info.type=="live"){a.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+-1*t.player.api.liveOffset+45};a.set.currentTime=function(e){var i=e-t.player.api.duration;t.log("Seeking to "+MistUtil.format.time(e)+" ("+Math.round(i*-10)/10+"s from live)");t.video.currentTime=e};MistUtil.event.addListener(r,"progress",function(){t.player.api.lastProgress=new Date});t.player.api.lastProgress=new Date;t.player.api.liveOffset=0}}else{i.api=r}if(t.options.autoplay){r.setAttribute("autoplay","")}if(t.options.loop&&t.info.type!="live"){r.setAttribute("loop","")}if(t.options.poster){r.setAttribute("poster",t.options.poster)}if(t.options.muted){r.muted=true}if(t.options.controls=="stock"){r.setAttribute("controls","")}var s=dashjs.MediaPlayer().create();s.initialize(r,t.source.url,t.options.autoplay);i.dash=s;var n=["METRIC_ADDED","METRIC_CHANGED","METRICS_CHANGED","FRAGMENT_LOADING_STARTED","FRAGMENT_LOADING_COMPLETED","LOG","PLAYBACK_TIME_UPDATED","PLAYBACK_PROGRESS"];for(var o in dashjs.MediaPlayer.events){if(n.indexOf(o)<0){i.dash.on(dashjs.MediaPlayer.events[o],function(e){t.log("Player event fired: "+e.type)})}}t.player.setSize=function(t){this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};t.player.api.setSource=function(e){t.player.dash.attachSource(e)};t.player.api.setTrack=function(e,r){var a=MistUtil.tracks.parse(t.info.meta.tracks);if(!(e in a)||!(r in a[e])&&r!=0){t.log("Skipping trackselection of "+e+" track "+r+" because it does not exist");return}var s=[];for(var n in t.info.meta.tracks){var o=t.info.meta.tracks[n];if(o.type==e){s.push(o)}}MistUtil.array.multiSort(s,["bps"]);var l=false;for(var n in s){if(s[n].trackid==r){l=n;break}}if(l===false){return false}i.dash.setAutoSwitchQualityFor(e,false);i.dash.setFastSwitchEnabled(true);i.dash.setQualityFor(e,l);return true};i.dash.on("qualityChangeRendered",function(e){var i=[];for(var r in t.info.meta.tracks){var a=t.info.meta.tracks[r];if(a.type==e.mediaType){i.push(a)}}MistUtil.array.multiSort(i,["bps"]);var s=i[e.newQuality].trackid;MistUtil.event.send("playerUpdate_trackChanged",{type:e.mediaType,trackid:s},t.video)});var l=false;i.dash.on("allTextTracksAdded",function(){l=true});t.player.api.setSubtitle=function(e){if(!l){var r=function(){t.player.api.setSubtitle(e);i.dash.off("allTextTracksAdded",r)};i.dash.on("allTextTracksAdded",r);return}if(!e){i.dash.enableText(false);return}var a=i.dash.getTracksFor("text");for(var s in a){if(a[s].id==e.trackid){i.dash.setTextTrack(s);if(!i.dash.isTextEnabled()){i.dash.enableText()}return true}}return false};MistUtil.event.addListener(r,"progress",function(e){if(t.container.getAttribute("data-loading")=="stalled"){t.container.removeAttribute("data-loading")}});i.api.unload=function(){i.dash.reset()};t.log("Built html");e(r)};if("dashjs"in window){this.onDashLoad()}else{var r=MistUtil.scripts.insert(t.urlappend(mistplayers.dashjs.scriptsrc(t.options.host)),{onerror:function(e){var i="Failed to load dashjs.js";if(e.message){i+=": "+e.message}t.showError(i)},onload:i.onDashLoad},t)}};
|
|
@ -1 +1 @@
|
|||
mistplayers.flash_strobe={name:"Strobe Flash media playback",mimes:["flash/10","flash/11","flash/7"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return this.mimes.indexOf(t)==-1?false:true},isBrowserSupported:function(t,e,i){if(MistUtil.http.url.split(e.url).protocol.slice(0,4)=="http"&&location.protocol!=MistUtil.http.url.split(e.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}var r=0;try{var a=navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin;if(a.version){r=a.version.split(".")[0]}else{r=a.description.replace(/([^0-9\.])/g,"").split(".")[0]}}catch(t){}try{r=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version").replace(/([^0-9\,])/g,"").split(",")[0]}catch(t){}if(!r){return false}var l=t.split("/");return Number(r)>=Number(l[l.length-1])},player:function(){this.onreadylist=[]}};var p=mistplayers.flash_strobe.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=document.createElement("object");var r=document.createElement("embed");i.appendChild(r);function a(e){var a=t.options;function l(t,e){var i=document.createElement("param");i.setAttribute("name",t);i.setAttribute("value",e);return i}MistUtil.empty(i);i.appendChild(l("movie",t.urlappend(a.host+t.source.player_url)));var s="src="+encodeURIComponent(e)+"&controlBarMode="+(a.controls?"floating":"none")+"&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3"+(a.live?"&streamType=live":"")+(a.autoplay?"&autoPlay=true":"");i.appendChild(l("flashvars",s));i.appendChild(l("allowFullScreen","true"));i.appendChild(l("wmode","direct"));if(a.autoplay){i.appendChild(l("autoPlay","true"))}r.setAttribute("src",t.urlappend(t.source.player_url));r.setAttribute("type","application/x-shockwave-flash");r.setAttribute("allowfullscreen","true");r.setAttribute("flashvars",s)}a(t.source.url);this.api={};this.setSize=function(t){i.setAttribute("width",t.width);i.setAttribute("height",t.height);r.setAttribute("width",t.width);r.setAttribute("height",t.height)};this.setSize(t.calcSize());this.onready(function(){if(t.container){t.container.removeAttribute("data-loading")}});this.api.setSource=function(t){a(t)};t.log("Built html");e(i)};
|
||||
mistplayers.flash_strobe={name:"Strobe Flash media playback",mimes:["flash/10","flash/11","flash/7"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return this.mimes.indexOf(t)==-1?false:true},isBrowserSupported:function(t,e,i){if(MistUtil.http.url.split(e.url).protocol.slice(0,4)=="http"&&location.protocol!=MistUtil.http.url.split(e.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}var r=0;try{var a=navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin;if(a.version){r=a.version.split(".")[0]}else{r=a.description.replace(/([^0-9\.])/g,"").split(".")[0]}}catch(t){}try{r=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version").replace(/([^0-9\,])/g,"").split(",")[0]}catch(t){}if(!r){return false}var l=t.split("/");return Number(r)>=Number(l[l.length-1])},player:function(){this.onreadylist=[]}};var p=mistplayers.flash_strobe.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=document.createElement("object");var r=document.createElement("embed");i.appendChild(r);function a(e){var a=t.options;function l(t,e){var i=document.createElement("param");i.setAttribute("name",t);i.setAttribute("value",e);return i}MistUtil.empty(i);i.appendChild(l("movie",t.urlappend(a.host+t.source.player_url)));var o="src="+encodeURIComponent(e)+"&controlBarMode="+(a.controls?"floating":"none")+"&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3"+(a.live?"&streamType=live":"")+(a.autoplay?"&autoPlay=true":"")+(a.loop?"&loop=true":"")+(a.poster?"&poster="+a.poster:"")+(a.muted?"&muted=true":"");i.appendChild(l("flashvars",o));i.appendChild(l("allowFullScreen","true"));i.appendChild(l("wmode","direct"));if(a.autoplay){i.appendChild(l("autoPlay","true"))}if(a.loop){i.appendChild(l("loop","true"))}if(a.poster){i.appendChild(l("poster",a.poster))}if(a.muted){i.appendChild(l("muted","true"))}r.setAttribute("src",t.urlappend(t.source.player_url));r.setAttribute("type","application/x-shockwave-flash");r.setAttribute("allowfullscreen","true");r.setAttribute("flashvars",o)}a(t.source.url);this.api={};this.setSize=function(t){i.setAttribute("width",t.width);i.setAttribute("height",t.height);r.setAttribute("width",t.width);r.setAttribute("height",t.height)};this.setSize(t.calcSize());this.onready(function(){if(t.container){t.container.removeAttribute("data-loading")}});this.api.setSource=function(t){a(t)};t.log("Built html");e(i)};
|
|
@ -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(e){return MistUtil.array.indexOf(this.mimes,e)==-1?false:true},isBrowserSupported:function(e,t,i){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(t.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}}var r=false;var a=e.split("/");a.shift();try{a=a.join("/");function n(e){var t=document.createElement("video");if(t&&t.canPlayType(e)!=""){r=t.canPlayType(e)}return r}if(a=="video/mp4"){function o(e){function t(t){return("0"+e.init.charCodeAt(t).toString(16)).slice(-2)}switch(e.codec){case"AAC":return"mp4a.40.2";case"MP3":return"mp3";case"AC3":return"ec-3";case"H264":return"avc1."+t(1)+t(2)+t(3);case"HEVC":return"hev1."+t(1)+t(6)+t(7)+t(8)+t(9)+t(10)+t(11)+t(12);default:return e.codec.toLowerCase()}}var s={};for(var l in i.info.meta.tracks){if(i.info.meta.tracks[l].type!="meta"){s[o(i.info.meta.tracks[l])]=1}}s=MistUtil.object.keys(s);if(s.length){if(s.length>t.simul_tracks){var p=0;for(var l in s){var u=n(a+';codecs="'+s[l]+'"');if(u){p++}}return p>=t.simul_tracks}a+=';codecs="'+s.join(",")+'"'}}r=n(a)}catch(e){}return r},player:function(){this.onreadylist=[]},mistControls:true};var p=mistplayers.html5.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=e.source.type.split("/");i.shift();var r=document.createElement("video");r.setAttribute("crossorigin","anonymous");var a=document.createElement("source");a.setAttribute("src",e.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(e.options[s]){r.setAttribute(s,e.options[s]===true?"":e.options[s])}}if(e.options.controls=="stock"){r.setAttribute("controls","")}if(e.info.type=="live"){r.loop=false}if("Proxy"in window&&"Reflect"in window){var l={get:{},set:{}};e.player.api=new Proxy(r,{get:function(e,t,i){if(t in l.get){return l.get[t].apply(e,arguments)}var r=e[t];if(typeof r==="function"){return function(){return r.apply(e,arguments)}}return r},set:function(e,t,i){if(t in l.set){return l.set[t].call(e,i)}return e[t]=i}});if(e.source.type=="html5/audio/mp3"){l.set.currentTime=function(){e.log("Seek attempted, but MistServer does not currently support seeking in MP3.");return false}}if(e.info.type=="live"){l.get.duration=function(){var t=0;if(this.buffered.length){t=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-e.player.api.lastProgress.getTime())*.001;return t+i-e.player.api.liveOffset};l.set.currentTime=function(t){var i=t-e.player.api.duration;e.player.api.liveOffset=i;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(i*-10)/10+"s from live)");e.player.api.setSource(MistUtil.http.url.addParam(e.source.url,{startunix:i}))};MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"pause",function(){e.player.api.pausedAt=new Date});l.get.play=function(){return function(){if(e.player.api.paused&&e.player.api.pausedAt&&new Date-e.player.api.pausedAt>5e3){r.load();e.log("Reloading source..")}return r.play.apply(r,arguments)}};if(e.source.type=="html5/video/mp4"){l.get.currentTime=function(){return this.currentTime-e.player.api.liveOffset+e.info.lastms*.001}}}else{if(!isFinite(r.duration)){var p=0;for(var o in e.info.meta.tracks){p=Math.max(p,e.info.meta.tracks[o].lastms)}l.get.duration=function(){if(isFinite(this.duration)){return this.duration}return p*.001}}}}else{e.player.api=r}e.player.api.setSource=function(e){if(e!=this.source.src){this.source.src=e;this.load()}};e.player.api.setSubtitle=function(e){var t=r.getElementsByTagName("track");for(var i=t.length-1;i>=0;i--){r.removeChild(t[i])}if(e){var a=document.createElement("track");r.appendChild(a);a.kind="subtitles";a.label=e.label;a.srclang=e.lang;a.src=e.src;a.setAttribute("default","")}};e.player.setSize=function(e){this.api.style.width=e.width+"px";this.api.style.height=e.height+"px"};t(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}}var r=false;var a=t.split("/");a.shift();try{a=a.join("/");function n(t){var e=document.createElement("video");if(e&&e.canPlayType(t)!=""){r=e.canPlayType(t)}return r}if(a=="video/mp4"){function o(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 s={};for(var l in i.info.meta.tracks){if(i.info.meta.tracks[l].type!="meta"){s[o(i.info.meta.tracks[l])]=1}}s=MistUtil.object.keys(s);if(s.length){if(s.length>e.simul_tracks){var p=0;for(var l in s){var u=n(a+';codecs="'+s[l]+'"');if(u){p++}}return p>=e.simul_tracks}a+=';codecs="'+s.join(",")+'"'}}r=n(a)}catch(t){}return r},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)};
|
|
@ -1 +1 @@
|
|||
mistplayers.videojs={name:"VideoJS player",mimes:["html5/application/vnd.apple.mpegurl"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return this.mimes.indexOf(e)==-1?false:true},isBrowserSupported:function(e,t,i){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"&&e=="html5/application/vnd.apple"){i.log("This source ("+e+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){},scriptsrc:function(e){return e+"/videojs.js"}};var p=mistplayers.videojs.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=this;function r(){if(e.destroyed){return}e.log("Building VideoJS player..");var r=document.createElement("video");if(e.source.type!="html5/video/ogg"){r.crossOrigin="anonymous"}var o=e.source.type.split("/");o.shift();var n=document.createElement("source");n.setAttribute("src",e.source.url);i.source=n;r.appendChild(n);n.type=o.join("/");e.log("Adding "+n.type+" source @ "+e.source.url);if(n.type=="application/vnd.apple.mpegurl"){n.type="application/x-mpegURL"}MistUtil.class.add(r,"video-js");var s={};if(e.options.autoplay){s.autoplay=true}if(e.options.loop&&e.info.type!="live"){s.loop=true;r.loop=true}if(e.options.poster){s.poster=e.options.poster}if(e.options.controls=="stock"){r.setAttribute("controls","");if(!document.getElementById("videojs-css")){var l=document.createElement("link");l.rel="stylesheet";l.href=e.options.host+"/skins/videojs.css";l.id="videojs-css";document.head.appendChild(l)}}i.onready(function(){i.videojs=videojs(r,s,function(){e.log("Videojs initialized")});i.api.unload=function(){videojs(r).dispose()}});e.log("Built html");if("Proxy"in window&&"Reflect"in window){var a={get:{},set:{}};e.player.api=new Proxy(r,{get:function(e,t,i){if(t in a.get){return a.get[t].apply(e,arguments)}var r=e[t];if(typeof r==="function"){return function(){return r.apply(e,arguments)}}return r},set:function(e,t,i){if(t in a.set){return a.set[t].call(e,i)}return e[t]=i}});if(e.info.type=="live"){function p(e){var t=0;if(e.buffered.length){t=e.buffered.end(e.buffered.length-1)}return t}var u=90;a.get.duration=function(){return(e.info.lastms+(new Date).getTime()-e.info.updated.getTime())*.001};e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});a.set.currentTime=function(t){var i=e.player.api.currentTime-t;var r=t-e.player.api.duration;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(r*-10)/10+"s from live)");e.video.currentTime-=i};a.get.currentTime=function(){return this.currentTime+e.info.lastms*.001-e.player.api.liveOffset-u}}}else{i.api=r}e.player.setSize=function(t){if("videojs"in e.player){e.player.videojs.dimensions(t.width,t.height);r.parentNode.style.width=t.width+"px";r.parentNode.style.height=t.height+"px"}this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e.player.api.setSource=function(t){if(!e.player.videojs){return}if(e.player.videojs.src()!=t){e.player.videojs.src({type:e.player.videojs.currentSource().type,src:t})}};e.player.api.setSubtitle=function(e){var t=r.getElementsByTagName("track");for(var i=t.length-1;i>=0;i--){r.removeChild(t[i])}if(e){var o=document.createElement("track");r.appendChild(o);o.kind="subtitles";o.label=e.label;o.srclang=e.lang;o.src=e.src;o.setAttribute("default","")}};t(r)}if("videojs"in window){r()}else{var o=MistUtil.scripts.insert(e.urlappend(mistplayers.videojs.scriptsrc(e.options.host)),{onerror:function(t){var i="Failed to load videojs.js";if(t.message){i+=": "+t.message}e.showError(i)},onload:r},e)}};
|
||||
mistplayers.videojs={name:"VideoJS player",mimes:["html5/application/vnd.apple.mpegurl"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return this.mimes.indexOf(e)==-1?false:true},isBrowserSupported:function(e,t,i){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"&&e=="html5/application/vnd.apple"){i.log("This source ("+e+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){},scriptsrc:function(e){return e+"/videojs.js"}};var p=mistplayers.videojs.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=this;function r(){if(e.destroyed){return}e.log("Building VideoJS player..");var r=document.createElement("video");if(e.source.type!="html5/video/ogg"){r.crossOrigin="anonymous"}var o=e.source.type.split("/");o.shift();var n=document.createElement("source");n.setAttribute("src",e.source.url);i.source=n;r.appendChild(n);n.type=o.join("/");e.log("Adding "+n.type+" source @ "+e.source.url);if(n.type=="application/vnd.apple.mpegurl"){n.type="application/x-mpegURL"}MistUtil.class.add(r,"video-js");var s={};if(e.options.autoplay){s.autoplay=true}if(e.options.loop&&e.info.type!="live"){s.loop=true;r.loop=true}if(e.options.muted){s.muted=true;r.muted=true}if(e.options.poster){s.poster=e.options.poster}if(e.options.controls=="stock"){r.setAttribute("controls","");if(!document.getElementById("videojs-css")){var l=document.createElement("link");l.rel="stylesheet";l.href=e.options.host+"/skins/videojs.css";l.id="videojs-css";document.head.appendChild(l)}}i.onready(function(){i.videojs=videojs(r,s,function(){e.log("Videojs initialized")});i.api.unload=function(){videojs(r).dispose()}});e.log("Built html");if("Proxy"in window&&"Reflect"in window){var a={get:{},set:{}};e.player.api=new Proxy(r,{get:function(e,t,i){if(t in a.get){return a.get[t].apply(e,arguments)}var r=e[t];if(typeof r==="function"){return function(){return r.apply(e,arguments)}}return r},set:function(e,t,i){if(t in a.set){return a.set[t].call(e,i)}return e[t]=i}});if(e.info.type=="live"){function p(e){var t=0;if(e.buffered.length){t=e.buffered.end(e.buffered.length-1)}return t}var u=90;a.get.duration=function(){return(e.info.lastms+(new Date).getTime()-e.info.updated.getTime())*.001};e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});a.set.currentTime=function(t){var i=e.player.api.currentTime-t;var r=t-e.player.api.duration;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(r*-10)/10+"s from live)");e.video.currentTime-=i};a.get.currentTime=function(){return this.currentTime+e.info.lastms*.001-e.player.api.liveOffset-u}}}else{i.api=r}e.player.setSize=function(t){if("videojs"in e.player){e.player.videojs.dimensions(t.width,t.height);r.parentNode.style.width=t.width+"px";r.parentNode.style.height=t.height+"px"}this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e.player.api.setSource=function(t){if(!e.player.videojs){return}if(e.player.videojs.src()!=t){e.player.videojs.src({type:e.player.videojs.currentSource().type,src:t})}};e.player.api.setSubtitle=function(e){var t=r.getElementsByTagName("track");for(var i=t.length-1;i>=0;i--){r.removeChild(t[i])}if(e){var o=document.createElement("track");r.appendChild(o);o.kind="subtitles";o.label=e.label;o.srclang=e.lang;o.src=e.src;o.setAttribute("default","")}};t(r)}if("videojs"in window){r()}else{var o=MistUtil.scripts.insert(e.urlappend(mistplayers.videojs.scriptsrc(e.options.host)),{onerror:function(t){var i="Failed to load videojs.js";if(t.message){i+=": "+t.message}e.showError(i)},onload:r},e)}};
|
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
CHANGES="$(git diff --name-only --cached | grep embed/)";
|
||||
readarray -t CHANGES <<<"$CHANGES";
|
||||
|
||||
elementIn () {
|
||||
local e match="$1";
|
||||
shift;
|
||||
for e; do [[ "$e" == "$match" ]] && return 0; done;
|
||||
return 1;
|
||||
}
|
||||
|
||||
echo "Minimizing player code..";
|
||||
|
||||
echo " Minimizing JS..";
|
||||
|
||||
if [ "min/player.js" -ot "util.js" ] || [ "min/player.js" -ot "skins.js" ] || [ "min/player.js" -ot "controls.js" ] || [ "min/player.js" -ot "player.js" ]; then
|
||||
if elementIn "embed/util.js" "${CHANGES[@]}" || elementIn "embed/skins.js" "${CHANGES[@]}" || elementIn "embed/controls.js" "${CHANGES[@]}" || elementIn "embed/player.js" "${CHANGES[@]}" ; then
|
||||
echo " Minimizing 'util.js skins.js controls.js player.js' into 'min/player.js'..";
|
||||
terser -mc -o min/player.js -- util.js skins.js controls.js player.js
|
||||
fi
|
||||
|
@ -12,23 +22,23 @@ echo " Done.";
|
|||
|
||||
echo " Minimizing wrappers.."
|
||||
|
||||
if [ "min/wrappers/dashjs.js" -ot "wrappers/dashjs.js" ]; then
|
||||
if elementIn "embed/wrappers/dashjs.js" "${CHANGES[@]}"; then
|
||||
echo " Minimizing dashjs";
|
||||
terser -mn -o min/wrappers/dashjs.js -- wrappers/dashjs.js
|
||||
fi
|
||||
if [ "min/wrappers/flash_strobe.js" -ot "wrappers/flash_strobe.js" ]; then
|
||||
if elementIn "embed/wrappers/flash_strobe.js" "${CHANGES[@]}"; then
|
||||
echo " Minimizing flash_strobe";
|
||||
terser -mn -o min/wrappers/flash_strobe.js -- wrappers/flash_strobe.js
|
||||
fi
|
||||
if [ "min/wrappers/html5.js" -ot "wrappers/html5.js" ]; then
|
||||
if elementIn "embed/wrappers/html5.js" "${CHANGES[@]}"; then
|
||||
echo " Minimizing html5";
|
||||
terser -mn -o min/wrappers/html5.js -- wrappers/html5.js
|
||||
fi
|
||||
if [ "min/wrappers/videojs.js" -ot "wrappers/videojs.js" ]; then
|
||||
if elementIn "embed/wrappers/videojs.js" "${CHANGES[@]}"; then
|
||||
echo " Minimizing videojs";
|
||||
terser -mn -o min/wrappers/videojs.js -- wrappers/videojs.js
|
||||
fi
|
||||
if [ "min/wrappers/webrtc.js" -ot "wrappers/webrtc.js" ]; then
|
||||
if elementIn "embed/wrappers/webrtc.js" "${CHANGES[@]}"; then
|
||||
echo " Minimizing webrtc";
|
||||
terser -mn -o min/wrappers/webrtc.js -- wrappers/webrtc.js
|
||||
fi
|
||||
|
@ -36,11 +46,11 @@ echo " Done.";
|
|||
|
||||
echo " Minimizing CSS..";
|
||||
|
||||
if [ "min/skins/default.css" -ot "skins/default.css" ] || [ "min/skins/default.css" -ot "skins/general.css" ]; then
|
||||
if elementIn "embed/skins/default.css" "${CHANGES[@]}" || elementIn "embed/skins/general.css" "${CHANGES[@]}"; then
|
||||
echo " Minimizing default";
|
||||
cleancss --format keep-breaks -o min/skins/default.css skins/general.css skins/default.css
|
||||
fi
|
||||
if [ "min/skins/dev.css" -ot "skins/default.css" ] || [ "min/skins/dev.css" -ot "skins/general.css" ] || [ "min/skins/dev.css" -ot "skins/dev.css" ]; then
|
||||
if elementIn "embed/skins/default.css" "${CHANGES[@]}" || elementIn "embed/skins/general.css" "${CHANGES[@]}" || elementIn "embed/skins/dev.css" "${CHANGES[@]}"; then
|
||||
echo " Minimizing dev";
|
||||
cleancss --format keep-breaks -o min/skins/dev.css skins/general.css skins/default.css skins/dev.css
|
||||
fi
|
||||
|
|
|
@ -15,7 +15,8 @@ function MistVideo(streamName,options) {
|
|||
autoplay: true, //start playing when loaded
|
||||
controls: true, //show controls (MistControls when available)
|
||||
loop: false, //don't loop when the stream has finished
|
||||
poster: null, //don't show an image before the stream has started
|
||||
poster: false, //don't show an image before the stream has started
|
||||
muted: false, //don't start muted
|
||||
callback: false, //don't call a function when the player has finished building
|
||||
streaminfo: false, //don't use this streaminfo but collect it from the mistserverhost
|
||||
startCombo: false, //start looking for a player/source match at the start
|
||||
|
@ -99,7 +100,7 @@ function MistVideo(streamName,options) {
|
|||
|
||||
new MistSkin(this);
|
||||
|
||||
this.checkPlayer = function(options,quiet) {
|
||||
this.checkCombo = function(options,quiet) {
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
|
@ -244,7 +245,7 @@ function MistVideo(streamName,options) {
|
|||
this.choosePlayer = function() {
|
||||
MistVideo.log("Checking available players..");
|
||||
|
||||
var result = this.checkPlayer();
|
||||
var result = this.checkCombo();
|
||||
if (!result) { return false; }
|
||||
|
||||
var player = mistplayers[result.player];
|
||||
|
@ -257,7 +258,7 @@ function MistVideo(streamName,options) {
|
|||
source.url = MistVideo.urlappend(source.url);
|
||||
MistVideo.source = source;
|
||||
|
||||
MistUtil.event.send("playerChosen","Player/source combination selected",MistVideo.options.target);
|
||||
MistUtil.event.send("comboChosen","Player/source combination selected",MistVideo.options.target);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -605,7 +606,7 @@ function MistVideo(streamName,options) {
|
|||
if ("setSize" in MistVideo.player) {
|
||||
MistVideo.player.videocontainer = MistVideo.video.parentNode;
|
||||
MistVideo.video.currentTarget = MistVideo.options.target;
|
||||
if (!MistUtil.class.has(MistVideo.options.target,"secondaryVideo")) {
|
||||
if (!MistUtil.class.has(MistVideo.options.target,"mistvideo-secondaryVideo")) {
|
||||
//this is the main MistVideo
|
||||
MistVideo.player.resizeAll = function(){
|
||||
function findVideo(startAt,matchTarget) {
|
||||
|
@ -622,14 +623,18 @@ function MistVideo(streamName,options) {
|
|||
}
|
||||
|
||||
//find the video that is in the main container, and resize that one
|
||||
findVideo(MistVideo,MistVideo.options.target).p.resize();
|
||||
var main = findVideo(MistVideo,MistVideo.options.target);
|
||||
if (!main) { throw "Main video not found"; }
|
||||
main.p.resize();
|
||||
|
||||
//then, resize the secondaries
|
||||
if ("secondary" in MistVideo) {
|
||||
function tryResize(mv){
|
||||
if (mv.MistVideo) {
|
||||
if ("player" in mv.MistVideo) {
|
||||
findVideo(MistVideo,mv.MistVideo.options.target).p.resize();
|
||||
var sec = findVideo(MistVideo,mv.MistVideo.options.target);
|
||||
if (!sec) { throw "Secondary video not found"; }
|
||||
sec.p.resize();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -647,13 +652,14 @@ function MistVideo(streamName,options) {
|
|||
|
||||
}
|
||||
MistVideo.player.resize = function(options){
|
||||
if (!MistVideo.container.hasAttribute("data-fullscreen")) {
|
||||
var container = MistVideo.video.currentTarget.querySelector(".mistvideo");
|
||||
if (!container.hasAttribute("data-fullscreen")) {
|
||||
//if ((!document.fullscreenElement) || (document.fullscreenElement.parentElement != MistVideo.video.currentTarget)) {
|
||||
//first, base the size on the video dimensions
|
||||
size = MistVideo.calcSize(options);
|
||||
this.setSize(size);
|
||||
MistVideo.container.style.width = size.width+"px";
|
||||
MistVideo.container.style.height = size.height+"px";
|
||||
container.style.width = size.width+"px";
|
||||
container.style.height = size.height+"px";
|
||||
|
||||
if ((MistVideo.options.fillSpace) && (!options || !options.reiterating)) {
|
||||
//if this container is set to fill the available space
|
||||
|
@ -686,13 +692,6 @@ function MistVideo(streamName,options) {
|
|||
return true;
|
||||
}
|
||||
else {
|
||||
function findVideo(parent) {
|
||||
for (var i = 0; i < parent.children.length; i++) {
|
||||
if (MistUtil.class.has(parent.children[i],"video")) {
|
||||
return parent.children[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//this is the video that is in the main container, and resize this one to the screen dimensions
|
||||
this.setSize({
|
||||
|
@ -704,7 +703,7 @@ function MistVideo(streamName,options) {
|
|||
};
|
||||
|
||||
//if this is the main video
|
||||
if (!MistUtil.class.has(MistVideo.options.target,"secondaryVideo")) {
|
||||
if (!MistUtil.class.has(MistVideo.options.target,"mistvideo-secondaryVideo")) {
|
||||
MistUtil.event.addListener(window,"resize",function(){
|
||||
if (MistVideo.destroyed) { return; }
|
||||
MistVideo.player.resizeAll();
|
||||
|
@ -738,7 +737,7 @@ function MistVideo(streamName,options) {
|
|||
MistVideo.log("Skipping trackselection of "+i+" track "+usetracks[i]+" because it does not exist");
|
||||
delete usetracks[i];
|
||||
}
|
||||
if (!MistUtil.object.keys(usetracks).length) { return; }
|
||||
//if (!MistUtil.object.keys(usetracks).length) { return; } //don't do this; allow switching back to auto
|
||||
|
||||
//create source url
|
||||
var newurl;
|
||||
|
@ -771,11 +770,13 @@ function MistVideo(streamName,options) {
|
|||
this.setSourceParams(newurl,usetracks);
|
||||
|
||||
//restore video position
|
||||
var f = function(){
|
||||
this.currentTime = time;
|
||||
this.removeEventListener("loadedmetadata",f);
|
||||
};
|
||||
MistUtil.event.addListener(MistVideo.video,"loadedmetadata",f);
|
||||
if (MistVideo.info.type != "live") {
|
||||
var f = function(){
|
||||
this.currentTime = time;
|
||||
this.removeEventListener("loadedmetadata",f);
|
||||
};
|
||||
MistUtil.event.addListener(MistVideo.video,"loadedmetadata",f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1091,9 +1092,9 @@ function MistVideo(streamName,options) {
|
|||
source: this.source.index,
|
||||
player: this.playerName
|
||||
};
|
||||
if (!this.checkPlayer({startCombo:startCombo},true)) {
|
||||
if (!this.checkCombo({startCombo:startCombo},true)) {
|
||||
//the nextCombo won't yield a result
|
||||
if (this.checkPlayer({startCombo: false},true)) {
|
||||
if (this.checkCombo({startCombo: false},true)) {
|
||||
//..but resetting the startcombo would
|
||||
startCombo = false;
|
||||
}
|
||||
|
@ -1107,7 +1108,7 @@ function MistVideo(streamName,options) {
|
|||
opts.startCombo = startCombo;
|
||||
MistVideo = mistPlay(this.stream,opts);
|
||||
|
||||
if ((time) && (isFinite(time))) {
|
||||
if ((time) && (isFinite(time) && (this.info.type != "live"))) {
|
||||
//after load, try to restore the video position
|
||||
var f = function(){
|
||||
if (("player" in MistVideo) && ("api" in MistVideo.player)) { MistVideo.player.api.currentTime = time; }
|
||||
|
|
|
@ -205,15 +205,16 @@ MistSkins["default"] = {
|
|||
mode: "pos",
|
||||
transition: {
|
||||
hide: "left: 10px; bottom: -40px;",
|
||||
show: "bottom: 10px;"
|
||||
show: "bottom: 10px;",
|
||||
viewport: "left: 0; right: 0; top: 0; bottom: 0"
|
||||
},
|
||||
button: {
|
||||
type: "container",
|
||||
children: [{type: "video"}]
|
||||
children: [{type: "videocontainer"}]
|
||||
},
|
||||
window: {
|
||||
type: "switchVideo",
|
||||
classes: ["mistvideo-controls","mistvideo-padding","mistvideo-background"],
|
||||
classes: ["mistvideo-controls","mistvideo-padding","mistvideo-background","mistvideo-pointer"],
|
||||
containers: switchThese
|
||||
}
|
||||
};
|
||||
|
@ -448,7 +449,8 @@ MistSkins["default"] = {
|
|||
MistVideo.secondary = [];
|
||||
}
|
||||
|
||||
var options = MistUtil.object.extend(o.options,MistVideo.options,true);
|
||||
var options = MistUtil.object.extend({},MistVideo.options);
|
||||
options = MistUtil.object.extend(options,o.options);
|
||||
MistVideo.secondary.push(options);
|
||||
|
||||
var pointer = {
|
||||
|
@ -457,7 +459,14 @@ MistSkins["default"] = {
|
|||
};
|
||||
|
||||
options.target = document.createElement("div");
|
||||
options.callback = function(mv){
|
||||
delete options.container;
|
||||
|
||||
var mvo = {};
|
||||
options.MistVideoObject = mvo;
|
||||
|
||||
MistUtil.event.addListener(options.target,"initialized",function(){
|
||||
var mv = mvo.reference;
|
||||
//options.callback = function(mv){
|
||||
options.MistVideo = mv; //tell the main video we exist
|
||||
pointer.secondary = mv;
|
||||
|
||||
|
@ -467,7 +476,7 @@ MistSkins["default"] = {
|
|||
//as all event listeners are tied to the video element (not the container), events don't bubble up and disturb higher players
|
||||
|
||||
//prevent clicks on the control container from bubbling down to underlying elements
|
||||
var controlContainers = options.target.querySelectorAll(".controls");
|
||||
var controlContainers = options.target.querySelectorAll(".mistvideo-controls");
|
||||
for (var i = 0; i < controlContainers.length; i++) {
|
||||
MistUtil.event.addListener(controlContainers[i],"click",function(e){
|
||||
e.stopPropagation();
|
||||
|
@ -516,7 +525,7 @@ MistSkins["default"] = {
|
|||
mv.player.api.pausedesync = false;
|
||||
});
|
||||
|
||||
};
|
||||
});
|
||||
options.skin = MistUtil.object.extend({},MistVideo.skin,true);
|
||||
options.skin.structure.main = MistUtil.object.extend({},MistVideo.skin.structure.secondaryVideo(pointer));
|
||||
|
||||
|
@ -582,6 +591,8 @@ MistSkins["default"] = {
|
|||
},
|
||||
controls: function(){
|
||||
if ((this.options.controls) && (this.options.controls != "stock")) {
|
||||
MistUtil.class.add(this.container,"hasControls");
|
||||
|
||||
var container = this.UI.buildStructure(this.skin.structure.controls);
|
||||
if (MistUtil.isTouchDevice()) {
|
||||
container.style.zoom = 1.5;
|
||||
|
@ -1274,28 +1285,31 @@ MistSkins["default"] = {
|
|||
function changeToTracks(type,value){
|
||||
MistVideo.log("User selected "+type+" track with id "+value);
|
||||
|
||||
if ("setTrack" in MistVideo.player.api) {
|
||||
MistVideo.player.api.setTrack(type,value);
|
||||
return;
|
||||
}
|
||||
if (!MistVideo.options.setTracks) { MistVideo.options.setTracks = {}; }
|
||||
MistVideo.options.setTracks[type] = value;
|
||||
|
||||
if ("setTrack" in MistVideo.player.api) {
|
||||
return MistVideo.player.api.setTrack(type,value);
|
||||
}
|
||||
else {
|
||||
//gather what tracks we should use
|
||||
var usetracks = {};
|
||||
for (var i in selections) {
|
||||
if (i == "subtitle") { continue; } //subtitle tracks are handled seperately
|
||||
if ((i == "subtitle") || (selections[i].value == "")) { continue; } //subtitle tracks are handled seperately
|
||||
usetracks[i] = selections[i].value;
|
||||
}
|
||||
usetracks[type] = value;
|
||||
if (value != ""){ usetracks[type] = value; }
|
||||
//use setTracks
|
||||
if ("setTracks" in MistVideo.player.api) {
|
||||
MistVideo.player.api.setTracks(usetracks);
|
||||
return MistVideo.player.api.setTracks(usetracks);
|
||||
}
|
||||
//use setSource
|
||||
if ("setSource" in MistVideo.player.api) {
|
||||
MistVideo.player.api.setSource(
|
||||
return MistVideo.player.api.setSource(
|
||||
MistUtil.http.url.addParam(MistVideo.source.url,usetracks)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//sort the tracks to ["audio","video",..,"subtitle",..etc]
|
||||
|
@ -1373,6 +1387,7 @@ MistSkins["default"] = {
|
|||
if (i == this.trackType) { continue; }
|
||||
if (!checkboxes[i].checked) {
|
||||
checkboxes[i].checked = true;
|
||||
changeToTracks(i,true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1405,13 +1420,14 @@ MistSkins["default"] = {
|
|||
//var determine the display info for the tracks
|
||||
function orderValues(trackinfoobj) {
|
||||
var order = {
|
||||
width: 1,
|
||||
bps: 2,
|
||||
trackid: 0,
|
||||
language: 1,
|
||||
width: 2,
|
||||
bps: 3,
|
||||
fpks: 4,
|
||||
channels: 5,
|
||||
rate: 7,
|
||||
language: 0,
|
||||
codec: 6
|
||||
codec: 6,
|
||||
rate: 7
|
||||
};
|
||||
return MistUtil.object.values(trackinfoobj,function(keya,keyb,valuea,valueb){
|
||||
if (order[keya] > order[keyb]) { return 1; }
|
||||
|
@ -1429,6 +1445,13 @@ MistSkins["default"] = {
|
|||
select.trackType = type;
|
||||
cell.appendChild(select);
|
||||
|
||||
if (type != "subtitle") {
|
||||
var option = document.createElement("option");
|
||||
select.appendChild(option);
|
||||
option.value = "";
|
||||
option.appendChild(document.createTextNode("Automatic"));
|
||||
}
|
||||
|
||||
//display properties that are the same for all tracks
|
||||
var same = orderValues(t[MistUtil.object.keys(t)[0]].same);
|
||||
if (same.length) {
|
||||
|
@ -1440,7 +1463,9 @@ MistSkins["default"] = {
|
|||
|
||||
|
||||
//add options to the select
|
||||
var options = MistUtil.object.keys(t,true); //sort them
|
||||
var options = MistUtil.object.keys(t,function(a,b){
|
||||
return Number(a) - Number(b);
|
||||
}); //sort them
|
||||
for (var i in options) {
|
||||
var track = t[options[i]];
|
||||
var option = document.createElement("option");
|
||||
|
@ -1495,11 +1520,14 @@ MistSkins["default"] = {
|
|||
checkboxes[this.trackType].checked = true;
|
||||
}
|
||||
|
||||
changeToTracks(this.trackType,this.value);
|
||||
if (!changeToTracks(this.trackType,this.value)) {
|
||||
//trackchange failed, reset select to old value
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//set to the track that plays by default
|
||||
/*
|
||||
if (MistVideo.info.type == "live") {
|
||||
//for live, the default track is the highest index
|
||||
select.value = MistUtil.object.keys(t).pop();
|
||||
|
@ -1508,6 +1536,7 @@ MistSkins["default"] = {
|
|||
//for vod, the default track is the lowest index
|
||||
select.value = MistUtil.object.keys(t).shift();
|
||||
}
|
||||
*/
|
||||
|
||||
MistUtil.event.addListener(MistVideo.video,"playerUpdate_trackChanged",function(e){
|
||||
|
||||
|
@ -1736,8 +1765,8 @@ MistSkins["default"] = {
|
|||
this.showError = function(message,options){
|
||||
if (!options) {
|
||||
options = {
|
||||
softReload: true,
|
||||
reload: true,//(MistVideo.options.reloadDelay ? MistVideo.options.reloadDelay : 10),
|
||||
softReload: !!((MistVideo.video) && (MistVideo.video.load)),
|
||||
reload: true,
|
||||
nextCombo: !!MistVideo.info,
|
||||
polling: false,
|
||||
passive: false
|
||||
|
@ -2456,7 +2485,7 @@ function MistSkin(MistVideo) {
|
|||
if ((typeof skinOptions == "string") && (skinOptions in MistSkins)) { skinOptions = MistUtil.object.extend({},MistSkins[skinOptions],true); }
|
||||
|
||||
var skinParent;
|
||||
if (("inherit" in skinOptions) && (skinOptions.inherit)) {
|
||||
if (("inherit" in skinOptions) && (skinOptions.inherit) && (skinOptions.inherit in MistSkins)) {
|
||||
skinParent = this.applySkinOptions(skinOptions.inherit);
|
||||
}
|
||||
else {
|
||||
|
@ -2545,6 +2574,7 @@ function MistSkin(MistVideo) {
|
|||
}
|
||||
this.applySkinOptions("skin" in MistVideo.options ? MistVideo.options.skin : "default");
|
||||
|
||||
|
||||
//load css
|
||||
var styles = [];
|
||||
var toload = 0;
|
||||
|
|
|
@ -88,8 +88,13 @@ svg.icon.timeout {
|
|||
}
|
||||
.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;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
}
|
||||
.mistvideo-video {
|
||||
overflow: hidden;
|
||||
outline: none;
|
||||
}
|
||||
svg.icon.loading {
|
||||
z-index: -1; /* don't use display: none because of transition for [data-loading=stalled] */
|
||||
|
@ -222,3 +223,6 @@ svg.icon.spin, svg.icon .spin {
|
|||
animation: spin 1.5s infinite linear;
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
.vjs-text-track-display {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
|
|
@ -213,10 +213,8 @@ var MistUtil = {
|
|||
|
||||
if (sorting) {
|
||||
if (typeof sorting != "function") {
|
||||
sorting = function(keya,keyb){
|
||||
if (keya > keyb) { return 1; }
|
||||
if (keya < keyb) { return -1; }
|
||||
return 0;
|
||||
sorting = function(a,b){
|
||||
return a.localeCompare(b);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -764,6 +762,22 @@ var MistUtil = {
|
|||
var d = MistUtil.object.values(different);
|
||||
output[type][i].displayName = (d.length ? d.join(", ") : MistUtil.object.values(output[type][i].describe).join(" "));
|
||||
}
|
||||
|
||||
//check if some tracks have the same display name
|
||||
var names = {};
|
||||
for (var i in output[type]) {
|
||||
if (output[type][i].displayName in names) {
|
||||
//we have double names, add the track id
|
||||
var n = 1;
|
||||
for (var i in output[type]) {
|
||||
output[type][i].different.trackid = n+")";
|
||||
output[type][i].displayName = "Track "+n+" ("+output[type][i].displayName+")";
|
||||
n++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
names[output[type][i].displayName] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
|
|
|
@ -103,6 +103,9 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
if (MistVideo.options.poster) {
|
||||
ele.setAttribute("poster",MistVideo.options.poster);
|
||||
}
|
||||
if (MistVideo.options.muted) {
|
||||
ele.muted = true;
|
||||
}
|
||||
if (MistVideo.options.controls == "stock") {
|
||||
ele.setAttribute("controls","");
|
||||
}
|
||||
|
@ -141,20 +144,34 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
}
|
||||
|
||||
//figure out what the track number is
|
||||
//whyyyy did it have to be reverse order
|
||||
var n = me.dash.getBitrateInfoListFor("video").length - 1;
|
||||
//for dash: 0 lowest bitrate, going up
|
||||
//get the relevant tracks
|
||||
var mistTracks = [];
|
||||
for (var i in MistVideo.info.meta.tracks) {
|
||||
var t = MistVideo.info.meta.tracks[i];
|
||||
if (t.type == type) {
|
||||
if (t.trackid == id) { break; }
|
||||
n--;
|
||||
mistTracks.push(t);
|
||||
}
|
||||
}
|
||||
//sort by bitrate
|
||||
MistUtil.array.multiSort(mistTracks,["bps"]);
|
||||
var n = false;
|
||||
for (var i in mistTracks) {
|
||||
if (mistTracks[i].trackid == id) {
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (n === false) {
|
||||
return false; //track not found
|
||||
}
|
||||
|
||||
me.dash.setAutoSwitchQualityFor(type,false); //turn off ABR rules //TODO do we want this by default?
|
||||
me.dash.setFastSwitchEnabled(true); //show the new track asap
|
||||
me.dash.setQualityFor(type,n);
|
||||
//dash does change the track, but is appended to the buffer, so it seems to take a while..
|
||||
|
||||
return true; //track found and change requested
|
||||
}
|
||||
|
||||
//react to automatic trackswitching
|
||||
|
@ -162,19 +179,19 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
//the newQuality-th track of type mediaType is being selected
|
||||
|
||||
//figure out the track id
|
||||
//whyyyy did it have to be reverse order
|
||||
var n = me.dash.getBitrateInfoListFor("video").length - 1;
|
||||
var id;
|
||||
//for dash: 0 lowest bitrate, going up
|
||||
//get the relevant tracks
|
||||
var mistTracks = [];
|
||||
for (var i in MistVideo.info.meta.tracks) {
|
||||
var t = MistVideo.info.meta.tracks[i];
|
||||
if (t.type == e.mediaType) {
|
||||
if (e.newQuality == n) {
|
||||
id = t.trackid;
|
||||
break;
|
||||
}
|
||||
n--;
|
||||
mistTracks.push(t);
|
||||
}
|
||||
}
|
||||
//sort by bitrate
|
||||
MistUtil.array.multiSort(mistTracks,["bps"]);
|
||||
//get mist's id for the track
|
||||
var id = mistTracks[e.newQuality].trackid;
|
||||
|
||||
//create an event to pass this to the skin
|
||||
MistUtil.event.send("playerUpdate_trackChanged",{
|
||||
|
@ -183,6 +200,37 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
},MistVideo.video);
|
||||
|
||||
});
|
||||
var subsloaded = false;
|
||||
me.dash.on("allTextTracksAdded",function(){
|
||||
subsloaded = true;
|
||||
});
|
||||
|
||||
MistVideo.player.api.setSubtitle = function(trackmeta) {
|
||||
|
||||
if (!subsloaded) {
|
||||
var f = function(){
|
||||
MistVideo.player.api.setSubtitle(trackmeta);
|
||||
me.dash.off("allTextTracksAdded",f);
|
||||
};
|
||||
me.dash.on("allTextTracksAdded",f);
|
||||
return;
|
||||
}
|
||||
if (!trackmeta) {
|
||||
me.dash.enableText(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var dashsubs = me.dash.getTracksFor("text");
|
||||
for (var i in dashsubs) {
|
||||
if (dashsubs[i].id == trackmeta.trackid) {
|
||||
me.dash.setTextTrack(i);
|
||||
if (!me.dash.isTextEnabled()) { me.dash.enableText(); }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false; //failed to find subtitle
|
||||
};
|
||||
|
||||
//dashjs keeps on spamming the stalled icon >_>
|
||||
MistUtil.event.addListener(ele,"progress",function(e){
|
||||
|
|
|
@ -56,13 +56,22 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
|
||||
MistUtil.empty(ele);
|
||||
ele.appendChild(createParam("movie",MistVideo.urlappend(options.host+MistVideo.source.player_url)));
|
||||
var flashvars = "src="+encodeURIComponent(source)+"&controlBarMode="+(options.controls ? "floating" : "none")+"&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3"+(options.live ? "&streamType=live" : "")+(options.autoplay ? "&autoPlay=true" : "" );
|
||||
var flashvars = "src="+encodeURIComponent(source)+"&controlBarMode="+(options.controls ? "floating" : "none")+"&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3"+(options.live ? "&streamType=live" : "")+(options.autoplay ? "&autoPlay=true" : "" )+(options.loop ? "&loop=true" : "" )+(options.poster ? "&poster="+options.poster : "" )+(options.muted ? "&muted=true" : "" );
|
||||
ele.appendChild(createParam("flashvars",flashvars));
|
||||
ele.appendChild(createParam("allowFullScreen","true"));
|
||||
ele.appendChild(createParam("wmode","direct"));
|
||||
if (options.autoplay) {
|
||||
ele.appendChild(createParam("autoPlay","true"));
|
||||
}
|
||||
if (options.loop) {
|
||||
ele.appendChild(createParam("loop","true"));
|
||||
}
|
||||
if (options.poster) {
|
||||
ele.appendChild(createParam("poster",options.poster));
|
||||
}
|
||||
if (options.muted) {
|
||||
ele.appendChild(createParam("muted","true"));
|
||||
}
|
||||
|
||||
e.setAttribute("src",MistVideo.urlappend(MistVideo.source.player_url));
|
||||
e.setAttribute("type","application/x-shockwave-flash");
|
||||
|
|
|
@ -114,6 +114,9 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
video.setAttribute(attr,(MistVideo.options[attr] === true ? "" : MistVideo.options[attr]));
|
||||
}
|
||||
}
|
||||
if (MistVideo.options.muted) {
|
||||
video.muted = true; //don't use attribute because of Chrome bug: https://stackoverflow.com/questions/14111917/html5-video-muted-but-stilly-playing?rq=1
|
||||
}
|
||||
if (MistVideo.options.controls == "stock") {
|
||||
video.setAttribute("controls","");
|
||||
}
|
||||
|
@ -168,11 +171,19 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
};
|
||||
overrides.set.currentTime = function(value){
|
||||
var offset = value - MistVideo.player.api.duration;
|
||||
|
||||
if (offset > 0) {offset = 0;} //don't allow positive numbers, as Mist will interpret them as unix timestamps
|
||||
|
||||
MistVideo.player.api.liveOffset = offset;
|
||||
|
||||
MistVideo.log("Seeking to "+MistUtil.format.time(value)+" ("+Math.round(offset*-10)/10+"s from live)");
|
||||
|
||||
MistVideo.player.api.setSource(MistUtil.http.url.addParam(MistVideo.source.url,{startunix:offset}));
|
||||
var params = {startunix:offset};
|
||||
if (offset == 0) {
|
||||
params = {};
|
||||
}
|
||||
|
||||
MistVideo.player.api.setSource(MistUtil.http.url.addParam(MistVideo.source.url,params));
|
||||
}
|
||||
MistUtil.event.addListener(video,"progress",function(){
|
||||
MistVideo.player.api.lastProgress = new Date();
|
||||
|
|
|
@ -59,6 +59,10 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
vjsopts.loop = true;
|
||||
ele.loop = true;
|
||||
}
|
||||
if (MistVideo.options.muted) {
|
||||
vjsopts.muted = true;
|
||||
ele.muted = true;
|
||||
}
|
||||
if (MistVideo.options.poster) { vjsopts.poster = MistVideo.options.poster; }
|
||||
if (MistVideo.options.controls == "stock") {
|
||||
ele.setAttribute("controls","");
|
||||
|
@ -71,7 +75,6 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
me.onready(function(){
|
||||
me.videojs = videojs(ele,vjsopts,function(){
|
||||
MistVideo.log("Videojs initialized");
|
||||
|
|
|
@ -49,6 +49,9 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
video.setAttribute(attr,(MistVideo.options[attr] === true ? "" : MistVideo.options[attr]));
|
||||
}
|
||||
}
|
||||
if (MistVideo.options.muted) {
|
||||
video.muted = true; //don't use attribute because of Chrome bug
|
||||
}
|
||||
if (MistVideo.info.type == "live") {
|
||||
video.loop = false;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue