Embed: improved behavior when websocket disconnects
This commit is contained in:
parent
51147c3df5
commit
8e8017dfd9
4 changed files with 196 additions and 163 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
322
embed/player.js
322
embed/player.js
|
@ -908,7 +908,7 @@ function MistVideo(streamName,options) {
|
||||||
//try again without a startCombo
|
//try again without a startCombo
|
||||||
delete MistVideo.options.startCombo;
|
delete MistVideo.options.startCombo;
|
||||||
MistVideo.unload("No compatible players found - retrying without startCombo.");
|
MistVideo.unload("No compatible players found - retrying without startCombo.");
|
||||||
MistVideo = mistPlay(MistVideo.stream,MistVideo.options);
|
mistPlay(MistVideo.stream,MistVideo.options);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MistVideo.showError("No compatible player/source combo found.",{reload:true});
|
MistVideo.showError("No compatible player/source combo found.",{reload:true});
|
||||||
|
@ -966,178 +966,180 @@ function MistVideo(streamName,options) {
|
||||||
this.wasConnected = true;
|
this.wasConnected = true;
|
||||||
|
|
||||||
//report player status to MistServer
|
//report player status to MistServer
|
||||||
MistVideo.reporting = {
|
if (!MistVideo.reporting) {
|
||||||
stats: {
|
MistVideo.reporting = {
|
||||||
set: function(key,value){
|
stats: {
|
||||||
this.d[key] = value;
|
set: function(key,value){
|
||||||
},
|
this.d[key] = value;
|
||||||
add: function(key,add){
|
},
|
||||||
if (typeof add == "undefined") { add = 1; }
|
add: function(key,add){
|
||||||
this.d[key] += add;
|
if (typeof add == "undefined") { add = 1; }
|
||||||
},
|
this.d[key] += add;
|
||||||
d: {
|
},
|
||||||
nWaiting: 0,
|
d: {
|
||||||
timeWaiting: 0,
|
nWaiting: 0,
|
||||||
nStalled: 0,
|
timeWaiting: 0,
|
||||||
timeStalled: 0,
|
nStalled: 0,
|
||||||
timeUnpaused: 0,
|
timeStalled: 0,
|
||||||
nError: 0,
|
timeUnpaused: 0,
|
||||||
nLog: 0,
|
nError: 0,
|
||||||
videoHeight: null,
|
nLog: 0,
|
||||||
videoWidth: null,
|
videoHeight: null,
|
||||||
playerHeight: null,
|
videoWidth: null,
|
||||||
playerWidth: null
|
playerHeight: null,
|
||||||
},
|
playerWidth: null
|
||||||
last: {
|
},
|
||||||
firstPlayback: null,
|
last: {
|
||||||
nWaiting: 0,
|
firstPlayback: null,
|
||||||
timeWaiting: 0,
|
nWaiting: 0,
|
||||||
nStalled: 0,
|
timeWaiting: 0,
|
||||||
timeStalled: 0,
|
nStalled: 0,
|
||||||
timeUnpaused: 0,
|
timeStalled: 0,
|
||||||
nError: 0,
|
timeUnpaused: 0,
|
||||||
lastError: null,
|
nError: 0,
|
||||||
playbackScore: 1,
|
lastError: null,
|
||||||
nLog: 0,
|
playbackScore: 1,
|
||||||
autoplay: null,
|
nLog: 0,
|
||||||
videoHeight: null,
|
autoplay: null,
|
||||||
videoWidth: null,
|
videoHeight: null,
|
||||||
playerHeight: null,
|
videoWidth: null,
|
||||||
playerWidth: null
|
playerHeight: null,
|
||||||
}
|
playerWidth: null
|
||||||
},
|
|
||||||
report: function(d){
|
|
||||||
socket.send(JSON.stringify(d));
|
|
||||||
},
|
|
||||||
reportStats: function(){
|
|
||||||
var d = {};
|
|
||||||
var report = false;
|
|
||||||
var newlogs = MistVideo.logs.slice(this.stats.last.nLog);
|
|
||||||
for (var i in this.stats.d) {
|
|
||||||
if (this.stats.d[i] != this.stats.last[i]) {
|
|
||||||
d[i] = this.stats.d[i];
|
|
||||||
this.stats.last[i] = d[i];
|
|
||||||
report = true;
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
if (report) {
|
report: function(d){
|
||||||
if (newlogs.length) {
|
MistVideo.socket.send(JSON.stringify(d));
|
||||||
d.logs = [];
|
},
|
||||||
for (var i in newlogs) {
|
reportStats: function(){
|
||||||
d.logs.push(newlogs[i].message);
|
var d = {};
|
||||||
|
var report = false;
|
||||||
|
var newlogs = MistVideo.logs.slice(this.stats.last.nLog);
|
||||||
|
for (var i in this.stats.d) {
|
||||||
|
if (this.stats.d[i] != this.stats.last[i]) {
|
||||||
|
d[i] = this.stats.d[i];
|
||||||
|
this.stats.last[i] = d[i];
|
||||||
|
report = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.report(d);
|
if (report) {
|
||||||
}
|
if (newlogs.length) {
|
||||||
MistVideo.timers.start(function(){
|
d.logs = [];
|
||||||
MistVideo.reporting.reportStats();
|
for (var i in newlogs) {
|
||||||
},5e3);
|
d.logs.push(newlogs[i].message);
|
||||||
},
|
}
|
||||||
init: function(){
|
}
|
||||||
var video = MistVideo.video;
|
this.report(d);
|
||||||
|
}
|
||||||
|
MistVideo.timers.start(function(){
|
||||||
|
MistVideo.reporting.reportStats();
|
||||||
|
},5e3);
|
||||||
|
},
|
||||||
|
init: function(){
|
||||||
|
var video = MistVideo.video;
|
||||||
|
|
||||||
var firstPlay = MistUtil.event.addListener(video,"playing",function(){
|
var firstPlay = MistUtil.event.addListener(video,"playing",function(){
|
||||||
MistVideo.reporting.stats.set("firstPlayback",new Date().getTime() - MistVideo.bootMs);
|
MistVideo.reporting.stats.set("firstPlayback",new Date().getTime() - MistVideo.bootMs);
|
||||||
MistUtil.event.removeListener(firstPlay);
|
MistUtil.event.removeListener(firstPlay);
|
||||||
});
|
|
||||||
|
|
||||||
//set listeners for player reporting
|
|
||||||
MistUtil.event.addListener(video,"waiting",function(){
|
|
||||||
MistVideo.reporting.stats.add("nWaiting");
|
|
||||||
});
|
|
||||||
MistUtil.event.addListener(video,"stalled",function(){
|
|
||||||
MistVideo.reporting.stats.add("nStalled");
|
|
||||||
});
|
|
||||||
MistUtil.event.addListener(MistVideo.options.target,"error",function(e){
|
|
||||||
MistVideo.reporting.stats.add("nError");
|
|
||||||
MistVideo.reporting.stats.set("lastError",e.message);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (Object && Object.defineProperty) {
|
|
||||||
var timeWaiting = 0;
|
|
||||||
var waitingSince = false;
|
|
||||||
var timeStalled = 0;
|
|
||||||
var stalledSince = false;
|
|
||||||
var timeUnpaused = 0;
|
|
||||||
var unpausedSince = false;
|
|
||||||
var d = MistVideo.reporting.stats.d;
|
|
||||||
Object.defineProperty(d,"timeWaiting",{
|
|
||||||
get: function(){
|
|
||||||
return timeWaiting + (waitingSince ? (new Date()).getTime() - waitingSince : 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(d,"timeStalled",{
|
|
||||||
get: function(){
|
|
||||||
return timeStalled + (stalledSince ? (new Date()).getTime() - stalledSince : 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(d,"timeUnpaused",{
|
|
||||||
get: function(){
|
|
||||||
return timeUnpaused + (unpausedSince ? (new Date()).getTime() - unpausedSince : 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(d,"nLog",{
|
|
||||||
get: function(){
|
|
||||||
return MistVideo.logs.length;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(d,"videoHeight",{
|
|
||||||
get: function(){
|
|
||||||
return MistVideo.video.videoHeight;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(d,"videoWidth",{
|
|
||||||
get: function(){
|
|
||||||
return MistVideo.video.videoWidth;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(d,"playerHeight",{
|
|
||||||
get: function(){
|
|
||||||
return MistVideo.video.clientHeight;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(d,"playerWidth",{
|
|
||||||
get: function(){
|
|
||||||
return MistVideo.video.clientWidth;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//set listeners for player reporting
|
||||||
MistUtil.event.addListener(video,"waiting",function(){
|
MistUtil.event.addListener(video,"waiting",function(){
|
||||||
timeWaiting = d.timeWaiting; //in case we get waiting several times in a row
|
MistVideo.reporting.stats.add("nWaiting");
|
||||||
waitingSince = (new Date()).getTime();
|
|
||||||
});
|
});
|
||||||
MistUtil.event.addListener(video,"stalled",function(){
|
MistUtil.event.addListener(video,"stalled",function(){
|
||||||
timeStalled = d.timeStalled; //in case we get stalled several times in a row
|
MistVideo.reporting.stats.add("nStalled");
|
||||||
stalledSince = (new Date()).getTime();
|
|
||||||
});
|
});
|
||||||
var events = ["playing","pause"];
|
MistUtil.event.addListener(MistVideo.options.target,"error",function(e){
|
||||||
for (var i in events) {
|
MistVideo.reporting.stats.add("nError");
|
||||||
MistUtil.event.addListener(video,events[i],function(){
|
MistVideo.reporting.stats.set("lastError",e.message);
|
||||||
timeWaiting = d.timeWaiting;
|
});
|
||||||
timeStalled = d.timeStalled;
|
|
||||||
waitingSince = false;
|
if (Object && Object.defineProperty) {
|
||||||
stalledSince = false;
|
var timeWaiting = 0;
|
||||||
|
var waitingSince = false;
|
||||||
|
var timeStalled = 0;
|
||||||
|
var stalledSince = false;
|
||||||
|
var timeUnpaused = 0;
|
||||||
|
var unpausedSince = false;
|
||||||
|
var d = MistVideo.reporting.stats.d;
|
||||||
|
Object.defineProperty(d,"timeWaiting",{
|
||||||
|
get: function(){
|
||||||
|
return timeWaiting + (waitingSince ? (new Date()).getTime() - waitingSince : 0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
Object.defineProperty(d,"timeStalled",{
|
||||||
|
get: function(){
|
||||||
|
return timeStalled + (stalledSince ? (new Date()).getTime() - stalledSince : 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(d,"timeUnpaused",{
|
||||||
|
get: function(){
|
||||||
|
return timeUnpaused + (unpausedSince ? (new Date()).getTime() - unpausedSince : 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(d,"nLog",{
|
||||||
|
get: function(){
|
||||||
|
return MistVideo.logs.length;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(d,"videoHeight",{
|
||||||
|
get: function(){
|
||||||
|
return MistVideo.video.videoHeight;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(d,"videoWidth",{
|
||||||
|
get: function(){
|
||||||
|
return MistVideo.video.videoWidth;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(d,"playerHeight",{
|
||||||
|
get: function(){
|
||||||
|
return MistVideo.video.clientHeight;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(d,"playerWidth",{
|
||||||
|
get: function(){
|
||||||
|
return MistVideo.video.clientWidth;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MistUtil.event.addListener(video,"waiting",function(){
|
||||||
|
timeWaiting = d.timeWaiting; //in case we get waiting several times in a row
|
||||||
|
waitingSince = (new Date()).getTime();
|
||||||
|
});
|
||||||
|
MistUtil.event.addListener(video,"stalled",function(){
|
||||||
|
timeStalled = d.timeStalled; //in case we get stalled several times in a row
|
||||||
|
stalledSince = (new Date()).getTime();
|
||||||
|
});
|
||||||
|
var events = ["playing","pause"];
|
||||||
|
for (var i in events) {
|
||||||
|
MistUtil.event.addListener(video,events[i],function(){
|
||||||
|
timeWaiting = d.timeWaiting;
|
||||||
|
timeStalled = d.timeStalled;
|
||||||
|
waitingSince = false;
|
||||||
|
stalledSince = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
MistUtil.event.addListener(video,"playing",function(){
|
||||||
|
timeUnpaused = d.timeUnpaused; //in case we get playing several times in a row
|
||||||
|
unpausedSince = (new Date()).getTime();
|
||||||
|
});
|
||||||
|
MistUtil.event.addListener(video,"pause",function(){
|
||||||
|
timeUnpaused = d.timeUnpaused;
|
||||||
|
unpausedSince = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
MistUtil.event.addListener(video,"playing",function(){
|
|
||||||
timeUnpaused = d.timeUnpaused; //in case we get playing several times in a row
|
|
||||||
unpausedSince = (new Date()).getTime();
|
|
||||||
});
|
|
||||||
MistUtil.event.addListener(video,"pause",function(){
|
|
||||||
timeUnpaused = d.timeUnpaused;
|
|
||||||
unpausedSince = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
//periodically send the gathered stats
|
||||||
|
this.reportStats();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
//periodically send the gathered stats
|
|
||||||
this.reportStats();
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
socket.onclose = function(e){
|
socket.onclose = function(e){
|
||||||
|
@ -1384,13 +1386,13 @@ function MistVideo(streamName,options) {
|
||||||
var time = ("player" in this && "api" in this.player ? this.player.api.currentTime : false);
|
var time = ("player" in this && "api" in this.player ? this.player.api.currentTime : false);
|
||||||
|
|
||||||
this.unload(reason);
|
this.unload(reason);
|
||||||
MistVideo = mistPlay(this.stream,this.options);
|
var NewMistVideo = mistPlay(this.stream,this.options);
|
||||||
|
|
||||||
if ((time) && (this.info.type != "live")) {
|
if ((time) && (this.info.type != "live")) {
|
||||||
//after load, try to restore the video position
|
//after load, try to restore the video position
|
||||||
var f = function(){
|
var f = function(){
|
||||||
if (MistVideo.player && MistVideo.player.api) {
|
if (NewMistVideo.player && NewMistVideo.player.api) {
|
||||||
MistVideo.player.api.currentTime = time;
|
NewMistVideo.player.api.currentTime = time;
|
||||||
}
|
}
|
||||||
this.removeEventListener("initialized",f);
|
this.removeEventListener("initialized",f);
|
||||||
};
|
};
|
||||||
|
|
|
@ -333,14 +333,45 @@ p.prototype.build = function (MistVideo,callback) {
|
||||||
this.ws = new WebSocket(MistVideo.source.url);
|
this.ws = new WebSocket(MistVideo.source.url);
|
||||||
this.ws.binaryType = "arraybuffer";
|
this.ws.binaryType = "arraybuffer";
|
||||||
|
|
||||||
|
this.ws.s = this.ws.send;
|
||||||
|
this.ws.send = function(){
|
||||||
|
if (this.readyState == 1) {
|
||||||
|
return this.s.apply(this,arguments);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
this.ws.onopen = function(){
|
this.ws.onopen = function(){
|
||||||
|
this.wasConnected = true;
|
||||||
resolve();
|
resolve();
|
||||||
};
|
};
|
||||||
this.ws.onerror = function(e){
|
this.ws.onerror = function(e){
|
||||||
MistVideo.showError("MP4 over WS: websocket error");
|
MistVideo.showError("MP4 over WS: websocket error");
|
||||||
}
|
};
|
||||||
this.ws.onclose = function(e){
|
this.ws.onclose = function(e){
|
||||||
MistVideo.log("MP4 over WS: websocket closed");
|
MistVideo.log("MP4 over WS: websocket closed");
|
||||||
|
if (this.wasConnected && (!MistVideo.destroyed)) {
|
||||||
|
MistVideo.log("MP4 over WS: reopening websocket");
|
||||||
|
player.wsconnect().then(function(){
|
||||||
|
if (!player.sb) {
|
||||||
|
//retrieve codec info
|
||||||
|
var f = function(msg){
|
||||||
|
//got codec data, set up source buffer
|
||||||
|
|
||||||
|
if (!player.sb) { player.sbinit(msg.data.codecs); }
|
||||||
|
else { player.api.play(); }
|
||||||
|
|
||||||
|
player.ws.removeListener("codec_data",f);
|
||||||
|
};
|
||||||
|
player.ws.addListener("codec_data",f);
|
||||||
|
send({type:"request_codec_data",supported_codecs:MistVideo.source.supportedCodecs});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
player.api.play();
|
||||||
|
}
|
||||||
|
},function(){
|
||||||
|
Mistvideo.error("Lost connection to the Media Server");
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
this.ws.listeners = {}; //kind of event listener list for websocket messages
|
this.ws.listeners = {}; //kind of event listener list for websocket messages
|
||||||
this.ws.addListener = function(type,f){
|
this.ws.addListener = function(type,f){
|
||||||
|
|
Loading…
Add table
Reference in a new issue