Embed: improved unloading behaviour (again), removed artificial HLS latency addition because it was causing negative timestamps
This commit is contained in:
parent
09d4bb6318
commit
420fea9b31
7 changed files with 68 additions and 26 deletions
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
mistplayers.videojs={name:"VideoJS player",mimes:["html5/application/vnd.apple.mpegurl","html5/application/vnd.apple.mpegurl;version=7"],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("/");if(o[0]=="html5"){o.shift()}var s=document.createElement("source");s.setAttribute("src",e.source.url);i.source=s;r.appendChild(s);s.type=o.join("/");e.log("Adding "+s.type+" source @ "+e.source.url);MistUtil.class.add(r,"video-js");var n={};if(e.options.autoplay){n.autoplay=true}if(e.options.loop&&e.info.type!="live"){n.loop=true;r.loop=true}if(e.options.muted){n.muted=true;r.muted=true}if(e.options.poster){n.poster=e.options.poster}if(e.options.controls=="stock"){r.setAttribute("controls","");if(!document.getElementById("videojs-css")){var a=document.createElement("link");a.rel="stylesheet";a.href=e.options.host+"/skins/videojs.css";a.id="videojs-css";document.head.appendChild(a)}}i.onready(function(){i.videojs=videojs(r,n,function(){e.log("Videojs initialized")});i.api.unload=function(){if(i.videojs){videojs(r).dispose();i.videojs=false}};MistUtil.event.addListener(e.options.target,"error",function(t){var r=false;switch(t.message){case"Stream is shutting down":{t.preventDefault();break}case"Stream is offline":{e.clearError();t.preventDefault();r=MistUtil.event.addListener(e.video,"waiting",function(){i.api.pause();e.showError("Stream is offline ",{polling:true});if(r){MistUtil.event.removeListener(r)}});break}case"Stream is waiting for data":{if(r){MistUtil.event.removeListener(r)}i.api.pause();e.reload();break}}})});e.log("Built html");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.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;l.get.duration=function(){if(e.info){return(e.info.lastms+(new Date).getTime()-e.info.updated.getTime())*.001}return false};e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});l.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};l.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","html5/application/vnd.apple.mpegurl;version=7"],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;var r;function o(){if(e.destroyed){return}e.log("Building VideoJS player..");r=document.createElement("video");if(e.source.type!="html5/video/ogg"){r.crossOrigin="anonymous"}var o=e.source.type.split("/");if(o[0]=="html5"){o.shift()}var s=document.createElement("source");s.setAttribute("src",e.source.url);i.source=s;r.appendChild(s);s.type=o.join("/");e.log("Adding "+s.type+" source @ "+e.source.url);MistUtil.class.add(r,"video-js");var n={};if(e.options.autoplay){n.autoplay=true}if(e.options.loop&&e.info.type!="live"){n.loop=true;r.loop=true}if(e.options.muted){n.muted=true;r.muted=true}if(e.options.poster){n.poster=e.options.poster}if(e.options.controls=="stock"){r.setAttribute("controls","");if(!document.getElementById("videojs-css")){var a=document.createElement("link");a.rel="stylesheet";a.href=e.options.host+"/skins/videojs.css";a.id="videojs-css";document.head.appendChild(a)}}else{n.controls=false}i.onready(function(){e.log("Building videojs");i.videojs=videojs(r,n,function(){e.log("Videojs initialized")});i.api.unload=function(){if(i.videojs){videojs(r).dispose();i.videojs=false;e.log("Videojs instance disposed")}};MistUtil.event.addListener(e.options.target,"error",function(t){var r=false;switch(t.message){case"Stream is shutting down":{t.preventDefault();break}case"Stream is offline":{e.clearError();t.preventDefault();if(e.video){r=MistUtil.event.addListener(e.video,"waiting",function(){i.api.pause();e.showError("Stream is offline ",{polling:true});if(r){MistUtil.event.removeListener(r)}})}break}case"Stream is waiting for data":{if(r){MistUtil.event.removeListener(r)}i.api.pause();e.reload();break}}},e.video)});e.log("Built html");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.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=0;l.get.duration=function(){if(e.info){var t=(e.info.lastms+(new Date).getTime()-e.info.updated.getTime())*.001;return t}return 0};e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});l.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};var d=0;l.get.currentTime=function(){if(e.info){d=e.info.lastms*.001}var t=this.currentTime+d-e.player.api.liveOffset-u;if(isNaN(t)){return 0}return t}}}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){o()}else{var s=e.urlappend(mistplayers.videojs.scriptsrc(e.options.host));var n;window.onerror=function(t,i,o,s,a){if(i==n.src){r.pause();e.showError("Error in videojs player");e.reload()}return false};n=MistUtil.scripts.insert(s,{onerror:function(t){var i="Failed to load videojs.js";if(t.message){i+=": "+t.message}e.showError(i)},onload:o},e)}};
|
|
@ -388,6 +388,7 @@ function MistVideo(streamName,options) {
|
|||
|
||||
|
||||
MistVideo.player.build(MistVideo,function(video){
|
||||
MistVideo.log("Building new player");
|
||||
|
||||
MistVideo.container.removeAttribute("data-loading");
|
||||
MistVideo.video = video;
|
||||
|
@ -1110,6 +1111,12 @@ function MistVideo(streamName,options) {
|
|||
if ((this.UI) && (this.UI.elements)) {
|
||||
for (var i in this.UI.elements) {
|
||||
var e = this.UI.elements[i];
|
||||
if ("attachedListeners" in e) {
|
||||
//remove attached event listeners
|
||||
for (var i in e.attachedListeners) {
|
||||
MistUtil.event.removeListener(e.attachedListeners[i]);
|
||||
}
|
||||
}
|
||||
if (e.parentNode) {
|
||||
e.parentNode.removeChild(e);
|
||||
}
|
||||
|
|
|
@ -5,4 +5,4 @@ wget https://cdn.dashjs.org/latest/dash.all.min.js -O dash.all.min.js
|
|||
|
||||
echo "Videojs"
|
||||
echo "You'll want to check for the latest version at https://videojs.com/getting-started/#download-cdn"
|
||||
wget https://vjs.zencdn.net/7.4.1/video.min.js -O video.min.js
|
||||
wget https://vjs.zencdn.net/7.5.4/video.min.js -O video.min.js
|
||||
|
|
7
embed/players/video.min.js
vendored
7
embed/players/video.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1006,9 +1006,12 @@ MistSkins["default"] = {
|
|||
},button);
|
||||
|
||||
//apply initial video state
|
||||
if (('localStorage' in window) && (localStorage != null) && ('mistVolume' in localStorage)) {
|
||||
MistVideo.player.api.volume = localStorage['mistVolume'];
|
||||
}
|
||||
var initevent = MistUtil.event.addListener(video,"loadstart",function(){
|
||||
if (('localStorage' in window) && (localStorage != null) && ('mistVolume' in localStorage)) {
|
||||
MistVideo.player.api.volume = localStorage['mistVolume'];
|
||||
}
|
||||
MistUtil.event.removeListener(initevent);
|
||||
});
|
||||
|
||||
button.addPadding = function(actual){
|
||||
return actual * (1 - (this.margin.start + this.margin.end)) + this.margin.start;
|
||||
|
|
|
@ -29,12 +29,13 @@ p.prototype = new MistPlayer();
|
|||
p.prototype.build = function (MistVideo,callback) {
|
||||
var me = this; //to allow nested functions to access the player class itself
|
||||
|
||||
var ele;
|
||||
function onVideoJSLoad () {
|
||||
if (MistVideo.destroyed) { return;}
|
||||
|
||||
MistVideo.log("Building VideoJS player..");
|
||||
|
||||
var ele = document.createElement("video");
|
||||
ele = document.createElement("video");
|
||||
if (MistVideo.source.type != "html5/video/ogg") {
|
||||
ele.crossOrigin = "anonymous"; //required for subtitles, but if ogg, the video won"t load
|
||||
}
|
||||
|
@ -77,8 +78,12 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
document.head.appendChild(style);
|
||||
}
|
||||
}
|
||||
else {
|
||||
vjsopts.controls = false;
|
||||
}
|
||||
|
||||
me.onready(function(){
|
||||
MistVideo.log("Building videojs");
|
||||
me.videojs = videojs(ele,vjsopts,function(){
|
||||
MistVideo.log("Videojs initialized");
|
||||
});
|
||||
|
@ -87,6 +92,7 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
if (me.videojs) {
|
||||
videojs(ele).dispose();
|
||||
me.videojs = false;
|
||||
MistVideo.log("Videojs instance disposed");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -103,16 +109,17 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
MistVideo.clearError(); //we've probably got loads of buffer left to play
|
||||
e.preventDefault();
|
||||
|
||||
eventdata = MistUtil.event.addListener(MistVideo.video,"waiting",function(){
|
||||
//stream has ended
|
||||
|
||||
me.api.pause();
|
||||
|
||||
//show stream offline error
|
||||
MistVideo.showError("Stream is offline ",{polling:true});
|
||||
|
||||
if (eventdata) { MistUtil.event.removeListener(eventdata); }
|
||||
});
|
||||
if (MistVideo.video) {
|
||||
eventdata = MistUtil.event.addListener(MistVideo.video,"waiting",function(){
|
||||
//stream has ended
|
||||
me.api.pause();
|
||||
|
||||
//show stream offline error
|
||||
MistVideo.showError("Stream is offline ",{polling:true});
|
||||
|
||||
if (eventdata) { MistUtil.event.removeListener(eventdata); }
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "Stream is waiting for data": {
|
||||
|
@ -122,7 +129,7 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
},MistVideo.video);
|
||||
});
|
||||
|
||||
MistVideo.log("Built html");
|
||||
|
@ -162,13 +169,15 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
}
|
||||
return buffer_end;
|
||||
}
|
||||
var HLSlatency = 90; //best guess..
|
||||
var HLSlatency = 0; //best guess..
|
||||
|
||||
overrides.get.duration = function(){
|
||||
if (MistVideo.info) {
|
||||
return (MistVideo.info.lastms + (new Date()).getTime() - MistVideo.info.updated.getTime())*1e-3;
|
||||
var duration = (MistVideo.info.lastms + (new Date()).getTime() - MistVideo.info.updated.getTime())*1e-3;
|
||||
//if (isNaN(duration)) { return 1e9; }
|
||||
return duration;
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
};
|
||||
MistVideo.player.api.lastProgress = new Date();
|
||||
MistVideo.player.api.liveOffset = 0;
|
||||
|
@ -184,8 +193,12 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
MistVideo.log("Seeking to "+MistUtil.format.time(value)+" ("+Math.round(offset*-10)/10+"s from live)");
|
||||
MistVideo.video.currentTime -= diff;
|
||||
}
|
||||
var lastms = 0;
|
||||
overrides.get.currentTime = function(){
|
||||
return this.currentTime + MistVideo.info.lastms*1e-3 - MistVideo.player.api.liveOffset - HLSlatency;
|
||||
if (MistVideo.info) { lastms = MistVideo.info.lastms*1e-3; }
|
||||
var time = this.currentTime + lastms - MistVideo.player.api.liveOffset - HLSlatency;
|
||||
if (isNaN(time)) { return 0; }
|
||||
return time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +254,25 @@ p.prototype.build = function (MistVideo,callback) {
|
|||
else {
|
||||
//load the videojs player
|
||||
|
||||
var scripttag = MistUtil.scripts.insert(MistVideo.urlappend(mistplayers.videojs.scriptsrc(MistVideo.options.host)),{
|
||||
var scripturl = MistVideo.urlappend(mistplayers.videojs.scriptsrc(MistVideo.options.host));
|
||||
var scripttag;
|
||||
window.onerror = function (msg, url, lineNo, columnNo, error) {
|
||||
|
||||
if (url == scripttag.src) {
|
||||
//error in internal videojs code
|
||||
//console.error(me.videojs,MistVideo.video,ele,arguments);
|
||||
|
||||
ele.pause();
|
||||
|
||||
MistVideo.showError("Error in videojs player");
|
||||
|
||||
MistVideo.reload();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
scripttag = MistUtil.scripts.insert(scripturl,{
|
||||
onerror: function(e){
|
||||
var msg = "Failed to load videojs.js";
|
||||
if (e.message) { msg += ": "+e.message; }
|
||||
|
|
Loading…
Add table
Reference in a new issue