Merge branch 'development' into LTS_development

This commit is contained in:
Thulinma 2020-11-30 15:37:35 +01:00
commit 01b65ed301
5 changed files with 107 additions and 10 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -91,6 +91,7 @@ function MistVideo(streamName,options) {
}
}
this.errorListeners = [];
this.resumeTime = false;
this.urlappend = function(url){
if (this.options.urlappend) {
@ -280,6 +281,11 @@ function MistVideo(streamName,options) {
function onStreamInfo(d) {
if ((MistVideo.player) && (MistVideo.player.api) && (MistVideo.player.api.unload)) {
MistVideo.log("Received new stream info while a player was already loaded: unloading player");
MistVideo.player.api.unload();
}
MistVideo.info = d;
MistVideo.info.updated = new Date();
MistUtil.event.send("haveStreamInfo",d,MistVideo.options.target);
@ -373,7 +379,21 @@ function MistVideo(streamName,options) {
}
d.lastms = maxms;
}
else {
//If this is VoD and was already playing, return to the previous time
//this is triggered when the MistInput is killed/crashes during playback
var time = MistVideo.resumeTime;
if (time) {
var f = function(){
if (MistVideo.player && MistVideo.player.api) {
MistVideo.player.api.currentTime = time;
}
this.removeEventListener("initialized",f);
};
MistUtil.event.addListener(MistVideo.options.target,"initialized",f);
}
}
if (MistVideo.choosePlayer()) {
@ -946,6 +966,9 @@ function MistVideo(streamName,options) {
switch (data.error) {
case "Stream is offline":
MistVideo.info = false;
if (MistVideo.player && MistVideo.player.api && MistVideo.player.api.currentTime) {
MistVideo.resumeTime = MistVideo.player.api.currentTime;
}
case "Stream is initializing":
case "Stream is booting":
case "Stream is waiting for data":

View file

@ -429,7 +429,7 @@ MistSkins["default"] = {
}
MistUtil.event.addListener(MistVideo.video,"volumechange",fu);
});
},function(){});
}
}
});
@ -2198,6 +2198,13 @@ MistSkins.dev = {
label.set = function(val){
if (val !== 0) { this.style.display = ""; }
if (typeof val == "object") {
if (val instanceof Promise) {
val.then(function(val){
label.set(val)
},function(){});
return;
}
if ("val" in val) {
value.nodeValue = val.val;
valuec.className = "value";
@ -2329,6 +2336,26 @@ MistSkins.dev = {
if (MistVideo.player.api) {
return MistUtil.format.bytes(MistVideo.player.api.bytesReceived);
}
},
"Local latency [ms]": function(){
if ((MistVideo.player.api) && ("getLatency" in MistVideo.player.api)) {
var p = MistVideo.player.api.getLatency();
if (p) {
return new Promise(function(resolve,reject) {
p.then(function(result){
var r = [];
for (var i in result) {
if (result[i]) {
r.push(i[0]+Math.round(result[i]*1e3));
}
}
if (r.length) { resolve(r.join(" ")); }
else { resolve(); }
},reject)
});
}
return new Promise(function(resolve,reject){resolve();},function(){});
}
}
};
var updates = [];

View file

@ -100,10 +100,11 @@ p.prototype.build = function (MistVideo,callback) {
If MistOutWebRTC crashes, we receive an on_stop and then an on_disconnect
*/
if (!hasended) {
MistVideo.showError("Connection to media server ended unexpectedly.");
//MistVideo.showError("Connection to media server ended unexpectedly.");
video.pause();
}
//this.webrtc.signaling.ws.close();
},
on_answer_sdp: function (ev) {
if (!ev.result) {
@ -201,7 +202,6 @@ p.prototype.build = function (MistVideo,callback) {
var thisWebRTCPlayer = this;
this.on_event = function(ev) {
//if (ev.type != "on_time") { console.log(ev); }
switch (ev.type) {
case "on_connected": {
thisWebRTCPlayer.isConnected = true;
@ -229,6 +229,7 @@ p.prototype.build = function (MistVideo,callback) {
};
this.connect = function(callback){
thisWebRTCPlayer.isConnecting = true;
//chrome on android has a bug where H264 is not available immediately after the tab is opened: https://bugs.chromium.org/p/webrtc/issues/detail?id=11620
//this workaround tries 5x with 100ms intervals before continuing
@ -257,7 +258,6 @@ p.prototype.build = function (MistVideo,callback) {
checkH264(5).catch(function(){
MistVideo.log("Beware: this device does not seem to be able to play H264.");
}).finally(function(){
thisWebRTCPlayer.isConnecting = true;
thisWebRTCPlayer.signaling = new WebRTCSignaling(thisWebRTCPlayer.on_event);
thisWebRTCPlayer.peerConn = new RTCPeerConnection();
thisWebRTCPlayer.peerConn.ontrack = function(ev) {
@ -373,6 +373,8 @@ p.prototype.build = function (MistVideo,callback) {
this.ws = new WebSocket(MistVideo.source.url.replace(/^http/,"ws"));
var ignoreopen = false;
this.ws.onopen = function() {
onEvent({type: "on_connected"});
};
@ -390,8 +392,11 @@ p.prototype.build = function (MistVideo,callback) {
/* See http://tools.ietf.org/html/rfc6455#section-7.4.1 */
this.ws.onclose = function(ev) {
switch (ev.code) {
case 1006: {
//MistVideo.showError("WebRTC websocket closed unexpectedly");
}
default: {
onEvent({type: "on_disconnected"});
onEvent({type: "on_disconnected", code: ev.code});
break;
}
}
@ -407,7 +412,6 @@ p.prototype.build = function (MistVideo,callback) {
this.ws.send(JSON.stringify(cmd));
}
};
this.webrtc = new WebRTCPlayer();
this.api = {};
@ -528,6 +532,46 @@ p.prototype.build = function (MistVideo,callback) {
}
};
me.api.getStats = function(){
if (me.webrtc && me.webrtc.isConnected) {
return new Promise(function(resolve,reject) {
me.webrtc.peerConn.getStats().then((a) => {
var r = {
audio: null,
video: null
};
for (let dictionary of a.values()) {
if (dictionary.type == "track") {
//average jitter buffer in seconds
r[dictionary.kind] = dictionary;
}
}
resolve(r);
})
});
}
};
me.api.getLatency = function() {
var p = MistVideo.player.api.getStats();
if (p) {
return new Promise(function(resolve,reject){
p.then(function(first){
setTimeout(function(){
var p = me.api.getStats();
if (!p) { reject(); return; }
p.then(function(last){
var r = {};
for (var i in first) {
r[i] = first[i] && last[i] ? (last[i].jitterBufferDelay - first[i].jitterBufferDelay) / (last[i].jitterBufferEmittedCount - first[i].jitterBufferEmittedCount) : null;
}
resolve(r);
},reject);
},1e3);
},reject);
});
}
}
//redirect pause
me.api.pause = function(){
video.pause();
@ -594,8 +638,10 @@ p.prototype.build = function (MistVideo,callback) {
//loop
MistUtil.event.addListener(video,"ended",function(){
if (me.api.loop) {
if (MistVideo.state == "Stream is online") {
me.webrtc.connect();
}
}
});
if ("decodingIssues" in MistVideo.skin.blueprints) {
@ -625,6 +671,7 @@ p.prototype.build = function (MistVideo,callback) {
me.api.unload = function(){
try {
me.webrtc.stop();
me.webrtc.signaling.ws.close();
} catch (e) {}
};