Embed: player reporting
This commit is contained in:
parent
d9d72aab99
commit
35a98178f1
7 changed files with 240 additions and 24 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
214
embed/player.js
214
embed/player.js
|
@ -62,6 +62,7 @@ function MistVideo(streamName,options) {
|
||||||
return event;
|
return event;
|
||||||
};
|
};
|
||||||
this.log("Initializing..");
|
this.log("Initializing..");
|
||||||
|
this.bootMs = new Date().getTime();
|
||||||
|
|
||||||
this.timers = {
|
this.timers = {
|
||||||
list: {}, //will contain the timeouts, format timeOutIndex: endTime
|
list: {}, //will contain the timeouts, format timeOutIndex: endTime
|
||||||
|
@ -402,6 +403,15 @@ function MistVideo(streamName,options) {
|
||||||
|
|
||||||
if (MistVideo.choosePlayer()) {
|
if (MistVideo.choosePlayer()) {
|
||||||
|
|
||||||
|
if (MistVideo.reporting) {
|
||||||
|
MistVideo.reporting.report({
|
||||||
|
player: MistVideo.playerName,
|
||||||
|
sourceType: MistVideo.source.type,
|
||||||
|
sourceUrl: MistVideo.source.url,
|
||||||
|
pageUrl: location.href
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//build player
|
//build player
|
||||||
MistVideo.player = new mistplayers[MistVideo.playerName].player();
|
MistVideo.player = new mistplayers[MistVideo.playerName].player();
|
||||||
|
|
||||||
|
@ -417,6 +427,10 @@ function MistVideo(streamName,options) {
|
||||||
MistVideo.container.removeAttribute("data-loading");
|
MistVideo.container.removeAttribute("data-loading");
|
||||||
MistVideo.video = video;
|
MistVideo.video = video;
|
||||||
|
|
||||||
|
if (MistVideo.reporting) {
|
||||||
|
MistVideo.reporting.init();
|
||||||
|
}
|
||||||
|
|
||||||
if ("api" in MistVideo.player) {
|
if ("api" in MistVideo.player) {
|
||||||
|
|
||||||
//add monitoring
|
//add monitoring
|
||||||
|
@ -495,6 +509,11 @@ function MistVideo(streamName,options) {
|
||||||
score = Math.max(score,list[list.length-1].score);
|
score = Math.max(score,list[list.length-1].score);
|
||||||
|
|
||||||
this.vars.score = score;
|
this.vars.score = score;
|
||||||
|
|
||||||
|
if (MistVideo.reporting) {
|
||||||
|
MistVideo.reporting.stats.set("playbackScore",Math.round(score*10)/10);
|
||||||
|
}
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
},
|
},
|
||||||
valueToScore: function(a,b){ //calculate the moving average
|
valueToScore: function(a,b){ //calculate the moving average
|
||||||
|
@ -568,7 +587,6 @@ function MistVideo(streamName,options) {
|
||||||
if (MistVideo.monitor) { MistVideo.monitor.reset(); }
|
if (MistVideo.monitor) { MistVideo.monitor.reset(); }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove placeholder and add UI structure
|
//remove placeholder and add UI structure
|
||||||
|
@ -874,6 +892,7 @@ function MistVideo(streamName,options) {
|
||||||
|
|
||||||
MistUtil.event.send("initialized",null,options.target);
|
MistUtil.event.send("initialized",null,options.target);
|
||||||
MistVideo.log("Initialized");
|
MistVideo.log("Initialized");
|
||||||
|
|
||||||
if (MistVideo.options.callback) { options.callback(MistVideo); }
|
if (MistVideo.options.callback) { options.callback(MistVideo); }
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -881,7 +900,7 @@ function MistVideo(streamName,options) {
|
||||||
else if (MistVideo.options.startCombo) {
|
else if (MistVideo.options.startCombo) {
|
||||||
//try again without a startCombo
|
//try again without a startCombo
|
||||||
delete MistVideo.options.startCombo;
|
delete MistVideo.options.startCombo;
|
||||||
MistVideo.unload();
|
MistVideo.unload("No compatible players found - retrying without startCombo.");
|
||||||
MistVideo = mistPlay(MistVideo.stream,MistVideo.options);
|
MistVideo = mistPlay(MistVideo.stream,MistVideo.options);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -937,6 +956,182 @@ function MistVideo(streamName,options) {
|
||||||
};
|
};
|
||||||
socket.onopen = function(e){
|
socket.onopen = function(e){
|
||||||
this.wasConnected = true;
|
this.wasConnected = true;
|
||||||
|
|
||||||
|
//report player status to MistServer
|
||||||
|
MistVideo.reporting = {
|
||||||
|
stats: {
|
||||||
|
set: function(key,value){
|
||||||
|
this.d[key] = value;
|
||||||
|
},
|
||||||
|
add: function(key,add){
|
||||||
|
if (typeof add == "undefined") { add = 1; }
|
||||||
|
this.d[key] += add;
|
||||||
|
},
|
||||||
|
d: {
|
||||||
|
nWaiting: 0,
|
||||||
|
timeWaiting: 0,
|
||||||
|
nStalled: 0,
|
||||||
|
timeStalled: 0,
|
||||||
|
timeUnpaused: 0,
|
||||||
|
nError: 0,
|
||||||
|
nLog: 0,
|
||||||
|
videoHeight: null,
|
||||||
|
videoWidth: null,
|
||||||
|
playerHeight: null,
|
||||||
|
playerWidth: null
|
||||||
|
},
|
||||||
|
last: {
|
||||||
|
firstPlayback: null,
|
||||||
|
nWaiting: 0,
|
||||||
|
timeWaiting: 0,
|
||||||
|
nStalled: 0,
|
||||||
|
timeStalled: 0,
|
||||||
|
timeUnpaused: 0,
|
||||||
|
nError: 0,
|
||||||
|
lastError: null,
|
||||||
|
playbackScore: 1,
|
||||||
|
nLog: 0,
|
||||||
|
autoplay: null,
|
||||||
|
videoHeight: null,
|
||||||
|
videoWidth: 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) {
|
||||||
|
if (newlogs.length) {
|
||||||
|
d.logs = [];
|
||||||
|
for (var i in newlogs) {
|
||||||
|
d.logs.push(newlogs[i].message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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(){
|
||||||
|
MistVideo.reporting.stats.set("firstPlayback",new Date().getTime() - MistVideo.bootMs);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//periodically send the gathered stats
|
||||||
|
this.reportStats();
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
socket.onclose = function(e){
|
socket.onclose = function(e){
|
||||||
if (this.die) {
|
if (this.die) {
|
||||||
|
@ -1063,7 +1258,7 @@ function MistVideo(streamName,options) {
|
||||||
|
|
||||||
if ("source" in diff) {
|
if ("source" in diff) {
|
||||||
if ("error" in MistVideo.info) {
|
if ("error" in MistVideo.info) {
|
||||||
MistVideo.reload();
|
MistVideo.reload("Reloading, stream info has error");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1111,6 +1306,8 @@ function MistVideo(streamName,options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
openSocket();
|
openSocket();
|
||||||
}
|
}
|
||||||
|
@ -1118,7 +1315,7 @@ function MistVideo(streamName,options) {
|
||||||
openWithGet();
|
openWithGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.unload = function(){
|
this.unload = function(reason){
|
||||||
if (this.destroyed) { return; }
|
if (this.destroyed) { return; }
|
||||||
|
|
||||||
this.log("Unloading..");
|
this.log("Unloading..");
|
||||||
|
@ -1138,6 +1335,9 @@ function MistVideo(streamName,options) {
|
||||||
MistVideo.monitor.destroy();
|
MistVideo.monitor.destroy();
|
||||||
}
|
}
|
||||||
if (this.socket) {
|
if (this.socket) {
|
||||||
|
if (this.reporting) {
|
||||||
|
this.reporting.report({unload:reason ? reason : null});
|
||||||
|
}
|
||||||
this.socket.destroy();
|
this.socket.destroy();
|
||||||
}
|
}
|
||||||
if ((this.player) && (this.player.api)) {
|
if ((this.player) && (this.player.api)) {
|
||||||
|
@ -1173,10 +1373,10 @@ function MistVideo(streamName,options) {
|
||||||
delete this.video;
|
delete this.video;
|
||||||
|
|
||||||
};
|
};
|
||||||
this.reload = function(){
|
this.reload = function(reason){
|
||||||
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();
|
this.unload(reason);
|
||||||
MistVideo = mistPlay(this.stream,this.options);
|
MistVideo = mistPlay(this.stream,this.options);
|
||||||
|
|
||||||
if ((time) && (this.info.type != "live")) {
|
if ((time) && (this.info.type != "live")) {
|
||||||
|
@ -1212,7 +1412,7 @@ function MistVideo(streamName,options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.unload();
|
this.unload("nextCombo");
|
||||||
var opts = this.options;
|
var opts = this.options;
|
||||||
opts.startCombo = startCombo;
|
opts.startCombo = startCombo;
|
||||||
MistVideo = mistPlay(this.stream,opts);
|
MistVideo = mistPlay(this.stream,opts);
|
||||||
|
|
|
@ -357,9 +357,12 @@ MistSkins["default"] = {
|
||||||
|
|
||||||
var promise = MistVideo.player.api.play();
|
var promise = MistVideo.player.api.play();
|
||||||
if (promise) {
|
if (promise) {
|
||||||
promise.catch(function(){
|
promise.then(function(){
|
||||||
|
if (MistVideo.reporting) { MistVideo.reporting.stats.d.autoplay = "success"; }
|
||||||
|
}).catch(function(){
|
||||||
if (MistVideo.destroyed) { return; }
|
if (MistVideo.destroyed) { return; }
|
||||||
MistVideo.log("Autoplay failed even with muted video. Unmuting and showing play button.");
|
MistVideo.log("Autoplay failed even with muted video. Unmuting and showing play button.");
|
||||||
|
if (MistVideo.reporting) { MistVideo.reporting.stats.d.autoplay = "failed"; }
|
||||||
MistVideo.player.api.muted = false;
|
MistVideo.player.api.muted = false;
|
||||||
|
|
||||||
//play has failed
|
//play has failed
|
||||||
|
@ -388,6 +391,8 @@ MistSkins["default"] = {
|
||||||
|
|
||||||
MistVideo.log("Autoplay worked! Video will be unmuted on mouseover if the page has been interacted with.");
|
MistVideo.log("Autoplay worked! Video will be unmuted on mouseover if the page has been interacted with.");
|
||||||
|
|
||||||
|
if (MistVideo.reporting) { MistVideo.reporting.stats.d.autoplay = "muted"; }
|
||||||
|
|
||||||
//show large "muted" icon
|
//show large "muted" icon
|
||||||
var largeMutedButton = MistVideo.skin.icons.build("muted",100);
|
var largeMutedButton = MistVideo.skin.icons.build("muted",100);
|
||||||
MistUtil.class.add(largeMutedButton,"mistvideo-pointer");
|
MistUtil.class.add(largeMutedButton,"mistvideo-pointer");
|
||||||
|
@ -432,9 +437,11 @@ MistSkins["default"] = {
|
||||||
},function(){});
|
},function(){});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (MistVideo.reporting) { MistVideo.reporting.stats.d.autoplay = "failed"; }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (MistVideo.reporting) { MistVideo.reporting.stats.d.autoplay = "success"; }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1953,7 +1960,7 @@ MistSkins["default"] = {
|
||||||
type: "button",
|
type: "button",
|
||||||
label: "Reload player",
|
label: "Reload player",
|
||||||
onclick: function(){
|
onclick: function(){
|
||||||
MistVideo.reload();
|
MistVideo.reload("Reloading because reload button was clicked.");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (!isNaN(options.reload+"")) { obj.delay = options.reload; }
|
if (!isNaN(options.reload+"")) { obj.delay = options.reload; }
|
||||||
|
@ -2470,7 +2477,7 @@ MistSkins.dev = {
|
||||||
MistUtil.event.addListener(select,"change",function(){
|
MistUtil.event.addListener(select,"change",function(){
|
||||||
MistVideo.options.forcePlayer = (this.value == "" ? false : this.value);
|
MistVideo.options.forcePlayer = (this.value == "" ? false : this.value);
|
||||||
if (MistVideo.options.forcePlayer != MistVideo.playerName) { //only reload if there is a change
|
if (MistVideo.options.forcePlayer != MistVideo.playerName) { //only reload if there is a change
|
||||||
MistVideo.reload();
|
MistVideo.reload("Reloading to force player.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2512,7 +2519,7 @@ MistSkins.dev = {
|
||||||
MistUtil.event.addListener(select,"change",function(){
|
MistUtil.event.addListener(select,"change",function(){
|
||||||
MistVideo.options.forceType = (this.value == "" ? false : this.value);
|
MistVideo.options.forceType = (this.value == "" ? false : this.value);
|
||||||
if ((!MistVideo.source) || (MistVideo.options.forceType != MistVideo.source.type)) { //only reload if there is a change
|
if ((!MistVideo.source) || (MistVideo.options.forceType != MistVideo.source.type)) { //only reload if there is a change
|
||||||
MistVideo.reload();
|
MistVideo.reload("Reloading to force new type.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2546,7 +2553,7 @@ MistSkins.dev = {
|
||||||
MistUtil.event.addListener(select,"change",function(){
|
MistUtil.event.addListener(select,"change",function(){
|
||||||
MistVideo.options.forceSource = (this.value == "" ? false : this.value);
|
MistVideo.options.forceSource = (this.value == "" ? false : this.value);
|
||||||
if (MistVideo.options.forceSource != MistVideo.source.index) { //only reload if there is a change
|
if (MistVideo.options.forceSource != MistVideo.source.index) { //only reload if there is a change
|
||||||
MistVideo.reload();
|
MistVideo.reload("Reloading to force new source.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2601,7 +2608,7 @@ MistSkins.dev.structure.submenu.children.unshift({
|
||||||
title: "Build MistVideo again",
|
title: "Build MistVideo again",
|
||||||
label: "MistVideo.reload();",
|
label: "MistVideo.reload();",
|
||||||
onclick: function(){
|
onclick: function(){
|
||||||
this.reload();
|
this.reload("Dev-reload button clicked.");
|
||||||
}
|
}
|
||||||
},{
|
},{
|
||||||
type: "button",
|
type: "button",
|
||||||
|
|
|
@ -467,6 +467,11 @@ p.prototype.build = function (MistVideo,callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MistVideo.reporting && msg.data.tracks) {
|
||||||
|
MistVideo.reporting.stats.d.tracks = msg.data.tracks.join(",");
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "tracks": {
|
case "tracks": {
|
||||||
|
|
|
@ -157,6 +157,10 @@ p.prototype.build = function (MistVideo,callback) {
|
||||||
|
|
||||||
currenttracks = ev.tracks;
|
currenttracks = ev.tracks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MistVideo.reporting && ev.tracks) {
|
||||||
|
MistVideo.reporting.stats.d.tracks = ev.tracks.join(",");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
on_seek: function(e){
|
on_seek: function(e){
|
||||||
var thisPlayer = this;
|
var thisPlayer = this;
|
||||||
|
|
Loading…
Add table
Reference in a new issue