various embed tweaks
This commit is contained in:
parent
dc6d0643bb
commit
899ee1088a
6 changed files with 256 additions and 370 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -57,4 +57,5 @@ rules.ninja
|
||||||
.ninja_log
|
.ninja_log
|
||||||
.ninja_deps
|
.ninja_deps
|
||||||
aes_ctr128
|
aes_ctr128
|
||||||
|
/embed/testing
|
||||||
|
|
||||||
|
|
168
embed/core.js
168
embed/core.js
|
@ -27,10 +27,10 @@ MistPlayer.prototype.sendEvent = function(type,message,target) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
MistPlayer.prototype.addlog = function(msg) {
|
MistPlayer.prototype.addlog = function(msg) {
|
||||||
this.sendEvent('log',msg,this.target);
|
this.sendEvent('log',msg,this.element);
|
||||||
}
|
}
|
||||||
MistPlayer.prototype.adderror = function(msg) {
|
MistPlayer.prototype.adderror = function(msg) {
|
||||||
this.sendEvent('error',msg,this.target);
|
this.sendEvent('error',msg,this.element);
|
||||||
}
|
}
|
||||||
MistPlayer.prototype.build = function () {
|
MistPlayer.prototype.build = function () {
|
||||||
this.addlog('Error in player implementation');
|
this.addlog('Error in player implementation');
|
||||||
|
@ -40,6 +40,32 @@ MistPlayer.prototype.build = function () {
|
||||||
err.className = 'error';
|
err.className = 'error';
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
MistPlayer.prototype.timer = {
|
||||||
|
timers: {},
|
||||||
|
add: function(callback,delay){
|
||||||
|
var me = this;
|
||||||
|
var i = setTimeout(function(){
|
||||||
|
delete me.timers[i];
|
||||||
|
callback();
|
||||||
|
},delay);
|
||||||
|
this.timers[i] = {
|
||||||
|
delay: delay,
|
||||||
|
callback: callback
|
||||||
|
};
|
||||||
|
return i;
|
||||||
|
},
|
||||||
|
remove: function(i){
|
||||||
|
clearTimeout(i);
|
||||||
|
delete this.timers[i];
|
||||||
|
},
|
||||||
|
clear: function(){
|
||||||
|
for (var i in this.timers) {
|
||||||
|
clearTimeout(i);
|
||||||
|
}
|
||||||
|
this.timers = {};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//creates the player element, including custom functions
|
//creates the player element, including custom functions
|
||||||
MistPlayer.prototype.getElement = function(tag){
|
MistPlayer.prototype.getElement = function(tag){
|
||||||
var ele = document.createElement(tag);
|
var ele = document.createElement(tag);
|
||||||
|
@ -164,14 +190,15 @@ MistPlayer.prototype.buildMistControls = function(){
|
||||||
str.push(('0'+secs).slice(-2));
|
str.push(('0'+secs).slice(-2));
|
||||||
return str.join(':');
|
return str.join(':');
|
||||||
}
|
}
|
||||||
|
var timestampValue, bar;
|
||||||
function whilePlaying() {
|
function whilePlaying() {
|
||||||
timestampValue.nodeValue = formatTime(ele.currentTime);
|
timestampValue.nodeValue = formatTime(ele.currentTime);
|
||||||
bar.style.width = ((ele.currentTime-ele.startTime)/ele.duration*100)+'%';
|
bar.style.width = ((ele.currentTime-ele.startTime)/ele.duration*100)+'%';
|
||||||
setTimeout(function(){
|
me.timer.add(function(){
|
||||||
if (!ele.paused) {
|
if (!ele.paused) {
|
||||||
whilePlaying();
|
whilePlaying();
|
||||||
}
|
}
|
||||||
},0.1e3);
|
},0.5e3);
|
||||||
};
|
};
|
||||||
function whileLivePlaying(track) {
|
function whileLivePlaying(track) {
|
||||||
|
|
||||||
|
@ -180,11 +207,11 @@ MistPlayer.prototype.buildMistControls = function(){
|
||||||
timestampValue.nodeValue = formatTime((playtime + track.lastms)/1e3);
|
timestampValue.nodeValue = formatTime((playtime + track.lastms)/1e3);
|
||||||
|
|
||||||
|
|
||||||
setTimeout(function(){
|
me.timer.add(function(){
|
||||||
if (!ele.paused) {
|
if (!ele.paused) {
|
||||||
whileLivePlaying(track);
|
whileLivePlaying(track);
|
||||||
}
|
}
|
||||||
},0.1e3);
|
},0.5e3);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,8 +243,10 @@ MistPlayer.prototype.buildMistControls = function(){
|
||||||
if (options.live) {
|
if (options.live) {
|
||||||
me.load();
|
me.load();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
me.play();
|
me.play();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
me.pause();
|
me.pause();
|
||||||
}
|
}
|
||||||
|
@ -258,7 +287,7 @@ MistPlayer.prototype.buildMistControls = function(){
|
||||||
bar.style.left = (ele.startTime/ele.duration*100)+'%';
|
bar.style.left = (ele.startTime/ele.duration*100)+'%';
|
||||||
};
|
};
|
||||||
progress.ondragstart = function() { return false; };
|
progress.ondragstart = function() { return false; };
|
||||||
var bar = document.createElement('div');
|
bar = document.createElement('div');
|
||||||
progress.appendChild(bar);
|
progress.appendChild(bar);
|
||||||
bar.className = 'bar';
|
bar.className = 'bar';
|
||||||
var buffers = [];
|
var buffers = [];
|
||||||
|
@ -271,6 +300,11 @@ MistPlayer.prototype.buildMistControls = function(){
|
||||||
ele.addEventListener('seeking',function(){
|
ele.addEventListener('seeking',function(){
|
||||||
me.target.setAttribute('data-loading','');
|
me.target.setAttribute('data-loading','');
|
||||||
});
|
});
|
||||||
|
ele.addEventListener('seeked',function(){
|
||||||
|
me.target.removeAttribute('data-loading');
|
||||||
|
bar.style.left = (ele.currentTime/ele.duration*100)+'%';
|
||||||
|
//TODO reset lasttime
|
||||||
|
});
|
||||||
ele.addEventListener('canplay',function(){
|
ele.addEventListener('canplay',function(){
|
||||||
me.target.removeAttribute('data-loading');
|
me.target.removeAttribute('data-loading');
|
||||||
});
|
});
|
||||||
|
@ -285,7 +319,7 @@ MistPlayer.prototype.buildMistControls = function(){
|
||||||
var timestamp = document.createElement('div');
|
var timestamp = document.createElement('div');
|
||||||
controls.appendChild(timestamp);
|
controls.appendChild(timestamp);
|
||||||
timestamp.className = 'button timestamp';
|
timestamp.className = 'button timestamp';
|
||||||
var timestampValue = document.createTextNode('-:--');
|
timestampValue = document.createTextNode('-:--');
|
||||||
timestamp.title = 'Time';
|
timestamp.title = 'Time';
|
||||||
timestamp.appendChild(timestampValue);
|
timestamp.appendChild(timestampValue);
|
||||||
|
|
||||||
|
@ -417,6 +451,9 @@ MistPlayer.prototype.buildMistControls = function(){
|
||||||
name = tracks[i][j].lang;
|
name = tracks[i][j].lang;
|
||||||
o.setAttribute('data-lang',tracks[i][j].lang);
|
o.setAttribute('data-lang',tracks[i][j].lang);
|
||||||
}
|
}
|
||||||
|
else if ('desc' in tracks[i][j]) {
|
||||||
|
name = tracks[i][j].desc;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
name = 'Track '+(Number(j)+1);
|
name = 'Track '+(Number(j)+1);
|
||||||
}
|
}
|
||||||
|
@ -516,6 +553,9 @@ MistPlayer.prototype.buildMistControls = function(){
|
||||||
});
|
});
|
||||||
ele.addEventListener('ended',function(){
|
ele.addEventListener('ended',function(){
|
||||||
play.setAttribute('data-state','paused');
|
play.setAttribute('data-state','paused');
|
||||||
|
if (options.live) {
|
||||||
|
me.load();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
ele.addEventListener('volumechange',function(){
|
ele.addEventListener('volumechange',function(){
|
||||||
var vol = 1 - Math.pow(1-ele.volume,2); //transform back from quadratic
|
var vol = 1 - Math.pow(1-ele.volume,2); //transform back from quadratic
|
||||||
|
@ -610,7 +650,11 @@ MistPlayer.prototype.askNextCombo = function(msg){
|
||||||
var me = this;
|
var me = this;
|
||||||
if (me.errorstate) { return; }
|
if (me.errorstate) { return; }
|
||||||
me.errorstate = true;
|
me.errorstate = true;
|
||||||
me.addlog('Showing error window');
|
me.report({
|
||||||
|
type: 'playback',
|
||||||
|
warn: 'Showing error window',
|
||||||
|
msg: msg
|
||||||
|
});
|
||||||
|
|
||||||
//show the error
|
//show the error
|
||||||
var err = document.createElement('div');
|
var err = document.createElement('div');
|
||||||
|
@ -618,7 +662,6 @@ MistPlayer.prototype.askNextCombo = function(msg){
|
||||||
err.appendChild(msgnode);
|
err.appendChild(msgnode);
|
||||||
err.className = 'error';
|
err.className = 'error';
|
||||||
err.style.position = 'absolute';
|
err.style.position = 'absolute';
|
||||||
err.style.top = 0;
|
|
||||||
err.style.width = '100%';
|
err.style.width = '100%';
|
||||||
err.style['margin-left'] = 0;
|
err.style['margin-left'] = 0;
|
||||||
this.target.appendChild(err);
|
this.target.appendChild(err);
|
||||||
|
@ -626,7 +669,6 @@ MistPlayer.prototype.askNextCombo = function(msg){
|
||||||
|
|
||||||
//if there is a next source/player, show a button to activate it
|
//if there is a next source/player, show a button to activate it
|
||||||
var opts = this.mistplaySettings.options;
|
var opts = this.mistplaySettings.options;
|
||||||
opts.startCombo = this.mistplaySettings.startCombo;
|
|
||||||
if (mistCheck(mistvideo[this.mistplaySettings.streamname],opts)) {
|
if (mistCheck(mistvideo[this.mistplaySettings.streamname],opts)) {
|
||||||
var button = document.createElement('button');
|
var button = document.createElement('button');
|
||||||
var t = document.createTextNode('Try next source/player');
|
var t = document.createTextNode('Try next source/player');
|
||||||
|
@ -640,7 +682,7 @@ MistPlayer.prototype.askNextCombo = function(msg){
|
||||||
//show a button to reload with the current settings
|
//show a button to reload with the current settings
|
||||||
var button = document.createElement('button');
|
var button = document.createElement('button');
|
||||||
var i = document.createElement('div'); //a css countdown clock for 10sec
|
var i = document.createElement('div'); //a css countdown clock for 10sec
|
||||||
i.className = 'countdown10';
|
i.className = 'countdown';
|
||||||
button.appendChild(i);
|
button.appendChild(i);
|
||||||
var t = document.createTextNode('Reload this player');
|
var t = document.createTextNode('Reload this player');
|
||||||
button.appendChild(t);
|
button.appendChild(t);
|
||||||
|
@ -649,10 +691,14 @@ MistPlayer.prototype.askNextCombo = function(msg){
|
||||||
me.reload();
|
me.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
//after 10 seconds, reload the player
|
//after 20 seconds, reload the player
|
||||||
err.timeOut = setTimeout(function(){
|
err.timeOut = me.timer.add(function(){
|
||||||
|
me.report({
|
||||||
|
type: 'playback',
|
||||||
|
warn: 'Automatically reloaded the current player after playback error'
|
||||||
|
});
|
||||||
button.click();
|
button.click();
|
||||||
},10e3);
|
},20e3);
|
||||||
|
|
||||||
};
|
};
|
||||||
MistPlayer.prototype.cancelAskNextCombo = function(){
|
MistPlayer.prototype.cancelAskNextCombo = function(){
|
||||||
|
@ -663,13 +709,17 @@ MistPlayer.prototype.cancelAskNextCombo = function(){
|
||||||
var err = this.target.querySelector('.error');
|
var err = this.target.querySelector('.error');
|
||||||
if (err) {
|
if (err) {
|
||||||
this.target.removeChild(err);
|
this.target.removeChild(err);
|
||||||
if (err.timeOut) { clearTimeout(err.timeOut); }
|
if (err.timeOut) { this.timer.remove(err.timeOut); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
MistPlayer.prototype.reload = function(){
|
MistPlayer.prototype.reload = function(){
|
||||||
this.unload();
|
this.unload();
|
||||||
mistPlay(this.mistplaySettings.streamname,this.mistplaySettings.options);
|
mistPlay(this.mistplaySettings.streamname,this.mistplaySettings.options);
|
||||||
|
this.report({
|
||||||
|
type: 'init',
|
||||||
|
info: 'Reloading player'
|
||||||
|
});
|
||||||
};
|
};
|
||||||
MistPlayer.prototype.nextCombo = function(){
|
MistPlayer.prototype.nextCombo = function(){
|
||||||
this.unload();
|
this.unload();
|
||||||
|
@ -680,8 +730,6 @@ MistPlayer.prototype.nextCombo = function(){
|
||||||
///send information back to mistserver
|
///send information back to mistserver
|
||||||
///\param msg object containing the information to report
|
///\param msg object containing the information to report
|
||||||
MistPlayer.prototype.report = function(msg) {
|
MistPlayer.prototype.report = function(msg) {
|
||||||
return false; ///\todo Remove this when the backend reporting function has been coded
|
|
||||||
|
|
||||||
|
|
||||||
///send a http post request
|
///send a http post request
|
||||||
///\param url (string) url to send to
|
///\param url (string) url to send to
|
||||||
|
@ -717,6 +765,10 @@ MistPlayer.prototype.report = function(msg) {
|
||||||
msg.userinfo.time = Math.round(((new Date) - this.options.initTime)/1e3); //seconds since the info js was loaded
|
msg.userinfo.time = Math.round(((new Date) - this.options.initTime)/1e3); //seconds since the info js was loaded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.sendEvent('report',JSON.stringify(msg),this.element);
|
||||||
|
|
||||||
|
return false; ///\todo Remove this when the backend reporting function has been coded
|
||||||
|
|
||||||
try {
|
try {
|
||||||
httpPost(this.options.host+'/report',{
|
httpPost(this.options.host+'/report',{
|
||||||
report: JSON.stringify(msg)
|
report: JSON.stringify(msg)
|
||||||
|
@ -725,9 +777,10 @@ MistPlayer.prototype.report = function(msg) {
|
||||||
catch (e) { }
|
catch (e) { }
|
||||||
}
|
}
|
||||||
MistPlayer.prototype.unload = function(){
|
MistPlayer.prototype.unload = function(){
|
||||||
|
this.addlog('Unloading..');
|
||||||
if (('pause' in this) && (this.pause)) { this.pause(); }
|
if (('pause' in this) && (this.pause)) { this.pause(); }
|
||||||
if ('updateSrc' in this) { this.updateSrc(''); }
|
if ('updateSrc' in this) { this.updateSrc(''); this.load(); }
|
||||||
//delete this.element;
|
this.timer.clear();
|
||||||
this.target.innerHTML = '';
|
this.target.innerHTML = '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -786,7 +839,7 @@ function mistCheck(streaminfo,options,embedLog) {
|
||||||
return p_shortname;
|
return p_shortname;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
embedLog('This browser does not support '+loop[s].type);
|
embedLog('This browser does not support '+loop[s].type+' via '+loop[s].url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -863,10 +916,10 @@ function mistPlay(streamName,options) {
|
||||||
poster: null, //don't show an image before the stream has started
|
poster: null, //don't show an image before the stream has started
|
||||||
callback: false, //don't call a function when the player has finished building
|
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
|
streaminfo: false, //don't use this streaminfo but collect it from the mistserverhost
|
||||||
startCombo: false,
|
startCombo: false, //start looking for a player/source match at the start
|
||||||
forceType: false,
|
forceType: false, //don't force a mimetype
|
||||||
forcePlayer: false,
|
forcePlayer: false, //don't force a player
|
||||||
forceSource: false
|
forceSource: false //don't force a source
|
||||||
};
|
};
|
||||||
for (var i in global) {
|
for (var i in global) {
|
||||||
options[i] = global[i];
|
options[i] = global[i];
|
||||||
|
@ -879,9 +932,19 @@ function mistPlay(streamName,options) {
|
||||||
mistError('MistServer host undefined.');
|
mistError('MistServer host undefined.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!options.target) {
|
||||||
|
mistError('Target container undefined');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
options.target.setAttribute('data-loading','');
|
options.target.setAttribute('data-loading','');
|
||||||
|
|
||||||
|
var classes = options.target.className.split(' ');
|
||||||
|
if (classes.indexOf('mistvideo') == -1) {
|
||||||
|
classes.push('mistvideo');
|
||||||
|
options.target.className = classes.join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
//check if the css is loaded
|
//check if the css is loaded
|
||||||
if (!document.getElementById('mist_player_css')) {
|
if (!document.getElementById('mist_player_css')) {
|
||||||
var css = document.createElement('link');
|
var css = document.createElement('link');
|
||||||
|
@ -1033,20 +1096,26 @@ function mistPlay(streamName,options) {
|
||||||
var skip = false;
|
var skip = false;
|
||||||
switch (t.type) {
|
switch (t.type) {
|
||||||
case 'video':
|
case 'video':
|
||||||
t.desc = ['['+t.codec+']',t.width+'x'+t.height,Math.round(t.bps/1024)+'kbps',t.fpks/1e3+'fps',t.lang];
|
t.desc = [t.width+'x'+t.height,/*Math.round(t.bps/1024)+'kbps',*/t.fpks/1e3+'fps',t.codec];
|
||||||
|
if (t.lang) {
|
||||||
|
t.desc.unshift(t.lang);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'audio':
|
case 'audio':
|
||||||
t.desc = ['['+t.codec+']',t.channels+' channels',Math.round(t.bps/1024)+'kbps',t.rate+'Hz',t.lang];
|
t.desc = [(t.channels == 2 ? 'Stereo' : (t.channels == 1 ? 'Mono' : t.channels+' channels')),/*Math.round(t.bps/1024)+'kbps',*/Math.round(t.rate/1000)+'kHz',t.codec];
|
||||||
|
if (t.lang) {
|
||||||
|
t.desc.unshift(t.lang);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'subtitle':
|
case 'subtitle':
|
||||||
t.desc = ['['+t.codec+']',t.lang];
|
t.desc = [t.lang,t.codec];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
skip = true;
|
skip = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (skip) { continue; }
|
if (skip) { continue; }
|
||||||
t.desc = t.desc.join(', ');
|
t.desc = t.desc.join(' ');
|
||||||
tracks[t.type].push(t);
|
tracks[t.type].push(t);
|
||||||
}
|
}
|
||||||
player.tracks = tracks;
|
player.tracks = tracks;
|
||||||
|
@ -1115,8 +1184,6 @@ function mistPlay(streamName,options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//monitor for errors
|
//monitor for errors
|
||||||
element.checkStalledTimeout = false;
|
|
||||||
element.checkProgressTimeout = false;
|
|
||||||
element.sendPingTimeout = setInterval(function(){
|
element.sendPingTimeout = setInterval(function(){
|
||||||
if (player.paused) { return; }
|
if (player.paused) { return; }
|
||||||
player.report({
|
player.report({
|
||||||
|
@ -1128,8 +1195,7 @@ function mistPlay(streamName,options) {
|
||||||
player.askNextCombo('The player has thrown an error');
|
player.askNextCombo('The player has thrown an error');
|
||||||
var r = {
|
var r = {
|
||||||
type: 'playback',
|
type: 'playback',
|
||||||
error: 'The player has thrown an error',
|
error: 'The player has thrown an error'
|
||||||
origin: e.target.outerHTML.slice(0,e.target.outerHTML.indexOf('>')+1),
|
|
||||||
};
|
};
|
||||||
if ('readyState' in player.element) {
|
if ('readyState' in player.element) {
|
||||||
r.readyState = player.element.readyState;
|
r.readyState = player.element.readyState;
|
||||||
|
@ -1137,37 +1203,38 @@ function mistPlay(streamName,options) {
|
||||||
if ('networkState' in player.element) {
|
if ('networkState' in player.element) {
|
||||||
r.networkState = player.element.networkState;
|
r.networkState = player.element.networkState;
|
||||||
}
|
}
|
||||||
if (('error' in player.element) && ('code' in player.element.error)) {
|
if (('error' in player.element) && (player.element.error) && ('code' in player.element.error)) {
|
||||||
r.code = player.element.error.code;
|
r.code = player.element.error.code;
|
||||||
}
|
}
|
||||||
player.report(r);
|
player.report(r);
|
||||||
});
|
});
|
||||||
|
element.checkStalledTimeout = false;
|
||||||
var stalled = function(e){
|
var stalled = function(e){
|
||||||
if (element.checkStalledTimeout) { return; }
|
if (element.checkStalledTimeout) { return; }
|
||||||
element.checkStalledTimeout = setTimeout(function(){
|
var curpos = player.element.currentTime;
|
||||||
if (player.paused) { return; }
|
if (curpos == 0) { return; }
|
||||||
|
element.checkStalledTimeout = player.timer.add(function(){
|
||||||
|
if ((player.paused) || (curpos != player.element.currentTime)) { return; }
|
||||||
player.askNextCombo('Playback has stalled');
|
player.askNextCombo('Playback has stalled');
|
||||||
player.report({
|
player.report({
|
||||||
'type': 'playback',
|
'type': 'playback',
|
||||||
'warn': 'Playback was stalled for > 8 sec'
|
'warn': 'Playback was stalled for > 30 sec'
|
||||||
});
|
});
|
||||||
},10e3);
|
},30e3);
|
||||||
};
|
};
|
||||||
element.addEventListener('stalled',stalled,true);
|
element.addEventListener('stalled',stalled,true);
|
||||||
element.addEventListener('waiting',stalled,true);
|
element.addEventListener('waiting',stalled,true);
|
||||||
|
|
||||||
|
if (playerOpts.live) {
|
||||||
|
element.checkProgressTimeout = false;
|
||||||
var progress = function(e){
|
var progress = function(e){
|
||||||
if (element.checkStalledTimeout) {
|
if (element.checkStalledTimeout) {
|
||||||
clearTimeout(element.checkStalledTimeout);
|
player.timer.remove(element.checkStalledTimeout);
|
||||||
element.checkStalledTimeout = false;
|
|
||||||
player.cancelAskNextCombo();
|
|
||||||
}
|
|
||||||
if (element.checkStalledTimeout) {
|
|
||||||
clearTimeout(element.checkStalledTimeout);
|
|
||||||
element.checkStalledTimeout = false;
|
element.checkStalledTimeout = false;
|
||||||
player.cancelAskNextCombo();
|
player.cancelAskNextCombo();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
element.addEventListener('progress',progress,true);
|
//element.addEventListener('progress',progress,true); //sometimes, there is progress but no playback
|
||||||
element.addEventListener('playing',progress,true);
|
element.addEventListener('playing',progress,true);
|
||||||
element.addEventListener('play',function(){
|
element.addEventListener('play',function(){
|
||||||
player.paused = false;
|
player.paused = false;
|
||||||
|
@ -1176,10 +1243,9 @@ function mistPlay(streamName,options) {
|
||||||
var lasttime = player.element.currentTime;
|
var lasttime = player.element.currentTime;
|
||||||
element.checkProgressTimeout = setInterval(function(){
|
element.checkProgressTimeout = setInterval(function(){
|
||||||
var newtime = player.element.currentTime;
|
var newtime = player.element.currentTime;
|
||||||
if (newtime == 0) { return; }
|
|
||||||
var progress = newtime - lasttime;
|
var progress = newtime - lasttime;
|
||||||
lasttime = newtime;
|
lasttime = newtime;
|
||||||
if (progress < 0) { return; }
|
if (progress < 0) { return; } //its probably a looping VOD or we've just seeked
|
||||||
if (progress == 0) {
|
if (progress == 0) {
|
||||||
var msg = 'There should be playback but nothing was played';
|
var msg = 'There should be playback but nothing was played';
|
||||||
var r = {
|
var r = {
|
||||||
|
@ -1198,12 +1264,11 @@ function mistPlay(streamName,options) {
|
||||||
}
|
}
|
||||||
player.report(r);
|
player.report(r);
|
||||||
player.askNextCombo('No playback');
|
player.askNextCombo('No playback');
|
||||||
if ('load' in player.element) { player.element.load(); }
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
player.cancelAskNextCombo();
|
player.cancelAskNextCombo();
|
||||||
if (progress < 4) {
|
if (progress < 20) {
|
||||||
var msg = 'It seems playback is lagging (progressed '+Math.round(progress*100)/100+'/8s)'
|
var msg = 'It seems playback is lagging (progressed '+Math.round(progress*100)/100+'/30s)'
|
||||||
player.addlog(msg);
|
player.addlog(msg);
|
||||||
player.report({
|
player.report({
|
||||||
type: 'playback',
|
type: 'playback',
|
||||||
|
@ -1211,7 +1276,7 @@ function mistPlay(streamName,options) {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},8e3);
|
},30e3);
|
||||||
}
|
}
|
||||||
},true);
|
},true);
|
||||||
element.addEventListener('pause',function(){
|
element.addEventListener('pause',function(){
|
||||||
|
@ -1221,6 +1286,7 @@ function mistPlay(streamName,options) {
|
||||||
element.checkProgressTimeout = false;
|
element.checkProgressTimeout = false;
|
||||||
}
|
}
|
||||||
},true);
|
},true);
|
||||||
|
}
|
||||||
|
|
||||||
if (player.resize) {
|
if (player.resize) {
|
||||||
//monitor for resizes and fire if needed
|
//monitor for resizes and fire if needed
|
||||||
|
|
File diff suppressed because one or more lines are too long
235
embed/test.html
235
embed/test.html
|
@ -1,235 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Embed test</title>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
include script for paid players
|
|
||||||
- jwplayer
|
|
||||||
- theoplayer
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--<script type='text/javascript' src='//cdn.theoplayer.com/latest/41718edc-cc2d-40d0-83d4-67c50c60f68f/theoplayer.loader.js'></script>-->
|
|
||||||
<!--<script src=players/jwplayer.js></script>
|
|
||||||
<script>jwplayer.key="2z0zTRsxD2HkL6m/LgDqvtUy2EThVn+gk1gN1Q==";</script>-->
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// global options can be set here
|
|
||||||
var mistoptions = {
|
|
||||||
//host: 'http://cat.mistserver.org:8080'
|
|
||||||
//host: 'http://thulmk3:8080'
|
|
||||||
//host: 'https://cat.mistserver.org:4433'
|
|
||||||
//host: 'http://localhost:8080'
|
|
||||||
//host: 'http://live.us.picarto.tv:8080'
|
|
||||||
host: 'http://cattop:8080'
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src=core.js></script>
|
|
||||||
<!--<script src=wrappers/theoplayer.js></script>-->
|
|
||||||
<!--<script src=wrappers/jwplayer.js></script>-->
|
|
||||||
<script src=wrappers/html5.js></script>
|
|
||||||
<script src=wrappers/videojs.js></script>
|
|
||||||
<script src=wrappers/dashjs.js></script>
|
|
||||||
<script src=wrappers/flash_strobe.js></script>
|
|
||||||
<script src=wrappers/img.js></script>
|
|
||||||
<script src=wrappers/silverlight.js></script>
|
|
||||||
<script src=wrappers/polytrope.js></script>
|
|
||||||
|
|
||||||
<script src=players/dash.js></script>
|
|
||||||
<script src=players/videojs.js></script>
|
|
||||||
|
|
||||||
<link rel=stylesheet href=mist.css id=mist_player_css>
|
|
||||||
<style>
|
|
||||||
/* the website can override the css at will */
|
|
||||||
|
|
||||||
body {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
max-width: 100vw;
|
|
||||||
max-height: 100vh;
|
|
||||||
background-color: #0f0f0f;
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
.mistvideo {
|
|
||||||
margin: 1px;
|
|
||||||
}
|
|
||||||
.log {
|
|
||||||
max-height: 15em;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
|
|
||||||
function mistinit(){
|
|
||||||
var logele = document.querySelector('.log');
|
|
||||||
var contele = document.querySelector('.cont');
|
|
||||||
document.addEventListener('error',function(e){
|
|
||||||
console.log('[Error] '+e.message,e.target);
|
|
||||||
var msg = document.createTextNode('['+(new Date()).toTimeString().split(' ')[0]+'] '+e.message+' from '+e.target.outerHTML.slice(0,e.target.outerHTML.indexOf('>')+1));
|
|
||||||
var div = document.createElement('div');
|
|
||||||
div.appendChild(msg);
|
|
||||||
div.style.color = 'red';
|
|
||||||
logele.appendChild(div);
|
|
||||||
logele.scrollTop = logele.scrollHeight;
|
|
||||||
});
|
|
||||||
document.addEventListener('log',function(e){
|
|
||||||
if (e.message.indexOf('Player event fired') > -1) { return; }
|
|
||||||
|
|
||||||
console.log('[log] '+e.message);
|
|
||||||
return;
|
|
||||||
var msg = document.createTextNode('['+(new Date()).toTimeString().split(' ')[0]+'] '+e.message);
|
|
||||||
var div = document.createElement('div');
|
|
||||||
div.appendChild(msg);
|
|
||||||
logele.appendChild(div);
|
|
||||||
logele.scrollTop = logele.scrollHeight;
|
|
||||||
});
|
|
||||||
|
|
||||||
//tryplayers = Object.keys(mistplayers);
|
|
||||||
tryplayers = [];
|
|
||||||
tryplayers.push('automatic');
|
|
||||||
//tryplayers.push('html5');
|
|
||||||
//tryplayers.push('videojs');
|
|
||||||
//tryplayers.push('img');
|
|
||||||
//tryplayers.push('dashjs');
|
|
||||||
//tryplayers.push('flash_strobe');
|
|
||||||
//tryplayers.push('silverlight');
|
|
||||||
streams = [];
|
|
||||||
//streams.push('live');
|
|
||||||
//streams.push('golive+emitan');
|
|
||||||
//streams.push('subtel');
|
|
||||||
//streams.push('ogg');
|
|
||||||
//streams.push('vids+mist.mp4');
|
|
||||||
//streams.push('vids+hahalol.mp3');
|
|
||||||
//streams.push('lama');
|
|
||||||
streams.push('bunny');
|
|
||||||
|
|
||||||
for (var j in streams) {
|
|
||||||
for (var i in tryplayers) {
|
|
||||||
var d = document.createElement('div');
|
|
||||||
var c = document.createElement('div');
|
|
||||||
c.className = 'mistvideo';
|
|
||||||
c.title = tryplayers[i];
|
|
||||||
d.appendChild(c);
|
|
||||||
contele.appendChild(d);
|
|
||||||
var p = mistPlay(streams[j],{
|
|
||||||
target: c,
|
|
||||||
maxwidth: 800,
|
|
||||||
forcePlayer: tryplayers[i],
|
|
||||||
//forceType: 'html5/video/mp4',
|
|
||||||
//forceType: 'html5/audio/mp3',
|
|
||||||
//forceType: 'html5/application/vnd.apple.mpegurl',
|
|
||||||
//forceType: 'dash/video/mp4',
|
|
||||||
//forceType: 'rtsp',
|
|
||||||
//forceSource: 6,
|
|
||||||
loop: true,
|
|
||||||
//controls: 'stock'
|
|
||||||
/*streaminfo: {
|
|
||||||
source: [{
|
|
||||||
type: 'html5/video/mp4',
|
|
||||||
url: 'http://localhost:8080/bunny.mp4'
|
|
||||||
},{
|
|
||||||
type: 'html5/application/vnd.apple.mpegurl',
|
|
||||||
url: 'http://localhost:8080/hls/bunny/index.m3u8'
|
|
||||||
},{
|
|
||||||
type: 'dash/video/mp4',
|
|
||||||
url: 'http://localhost:8080/dash/bunny/index.mpd'
|
|
||||||
},{
|
|
||||||
player_url: '/flashplayer.swf',
|
|
||||||
type: 'flash/10',
|
|
||||||
url: 'rtmp://localhost:1935/play/bunny'
|
|
||||||
}],
|
|
||||||
meta: {
|
|
||||||
tracks: []
|
|
||||||
},
|
|
||||||
height: 404,
|
|
||||||
width: 720,
|
|
||||||
type: 'vod'
|
|
||||||
},*/
|
|
||||||
callback: function(player) {
|
|
||||||
var button = document.createElement('button');
|
|
||||||
button.innerHTML = 'askNextCombo();';
|
|
||||||
button.onclick = function(){
|
|
||||||
player.askNextCombo('Button was clicked');
|
|
||||||
//d.removeChild(this);
|
|
||||||
};
|
|
||||||
d.append(button);
|
|
||||||
var i = document.createElement('div');
|
|
||||||
i.className = 'countdown10';
|
|
||||||
button.appendChild(i);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
thumbnailing :')
|
|
||||||
document.addEventListener('initialized',function(e){
|
|
||||||
var canvas = document.createElement('canvas');
|
|
||||||
canvas.width = 180;
|
|
||||||
document.body.appendChild(canvas);
|
|
||||||
var context = canvas.getContext('2d');
|
|
||||||
var embedded;
|
|
||||||
for (var i in mistvideo) {
|
|
||||||
embedded = mistvideo[i].embedded[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
var video = embedded.player.element;
|
|
||||||
var f = video.width / canvas.width;
|
|
||||||
canvas.height = video.height / f;
|
|
||||||
video.addEventListener('canplay',function(){
|
|
||||||
context.drawImage(video,0,0,canvas.width,canvas.height);
|
|
||||||
var img = canvas.toDataURL('image/jpeg');
|
|
||||||
document.write('<img src="'+img+'">');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body onload=mistinit()>
|
|
||||||
<h1>Sup</h1>
|
|
||||||
<!--
|
|
||||||
<div class='mistvideo' id='bunny_84yt98eh9g8ht'>
|
|
||||||
<noscript>
|
|
||||||
<video controls autoplay>
|
|
||||||
<source src='http://localhost:8080/bunny.mp4' type='video/mp4'>
|
|
||||||
<a href='http://localhost:8080/bunny.html' target='_blank'>
|
|
||||||
Click here to play video
|
|
||||||
</a>
|
|
||||||
</video>
|
|
||||||
</noscript>
|
|
||||||
<script>
|
|
||||||
(function(){
|
|
||||||
var play = function(){
|
|
||||||
mistPlay('vids+subtel.mp4',{
|
|
||||||
//mistPlay('bunny',{
|
|
||||||
target: document.getElementById('bunny_84yt98eh9g8ht'),
|
|
||||||
//forcePlayer: 'dashjs'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!window.mistplayers) { //import shit
|
|
||||||
var p = document.createElement('script');
|
|
||||||
p.src = 'http://localhost:8080/player.js';
|
|
||||||
document.head.appendChild(p);
|
|
||||||
p.onload = function(){
|
|
||||||
play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
play();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
</div>-->
|
|
||||||
<div class=cont></div>
|
|
||||||
<div class=log></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -95,11 +95,15 @@ p.prototype.build = function (options) {
|
||||||
else { ele.pause(); }
|
else { ele.pause(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options.live) {
|
this.addlog('Built html');
|
||||||
|
|
||||||
|
//forward events
|
||||||
ele.addEventListener('error',function(e){
|
ele.addEventListener('error',function(e){
|
||||||
|
|
||||||
|
if (options.live) {
|
||||||
if ((ele.error) && (ele.error.code == 3)) {
|
if ((ele.error) && (ele.error.code == 3)) {
|
||||||
e.stopPropagation();
|
e.stopPropagation(); //dont let this error continue to prevent the core from trying to handle the error
|
||||||
ele.load();
|
me.load();
|
||||||
me.cancelAskNextCombo();
|
me.cancelAskNextCombo();
|
||||||
e.message = 'Handled decoding error';
|
e.message = 'Handled decoding error';
|
||||||
me.addlog('Decoding error: reloading..');
|
me.addlog('Decoding error: reloading..');
|
||||||
|
@ -107,18 +111,19 @@ p.prototype.build = function (options) {
|
||||||
type: 'playback',
|
type: 'playback',
|
||||||
warn: 'A decoding error was encountered, but handled'
|
warn: 'A decoding error was encountered, but handled'
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
},true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addlog('Built html');
|
|
||||||
|
|
||||||
//forward events
|
|
||||||
ele.addEventListener('error',function(e){
|
|
||||||
var msg;
|
var msg;
|
||||||
if ('message' in e) {
|
if ('message' in e) {
|
||||||
msg = e.message;
|
msg = e.message;
|
||||||
}
|
}
|
||||||
|
else if ((e.target.tagName == 'SOURCE') && (e.target.getAttribute('src') == '')) {
|
||||||
|
e.stopPropagation();
|
||||||
|
//this error is triggered because the unload function was fired
|
||||||
|
return;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
msg = 'readyState: ';
|
msg = 'readyState: ';
|
||||||
switch (me.element.readyState) {
|
switch (me.element.readyState) {
|
||||||
|
@ -155,12 +160,12 @@ p.prototype.build = function (options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
me.adderror(msg);
|
me.adderror(msg);
|
||||||
},true);
|
});
|
||||||
var events = ['abort','canplay','canplaythrough','durationchange','emptied','ended','interruptbegin','interruptend','loadeddata','loadedmetadata','loadstart','pause','play','playing','ratechange','seeked','seeking','stalled','volumechange','waiting','progress'];
|
var events = ['abort','canplay','canplaythrough','durationchange','emptied','ended','interruptbegin','interruptend','loadeddata','loadedmetadata','loadstart','pause','play','playing','ratechange','seeked','seeking','stalled','volumechange','waiting','progress'];
|
||||||
for (var i in events) {
|
for (var i in events) {
|
||||||
ele.addEventListener(events[i],function(e){
|
ele.addEventListener(events[i],function(e){
|
||||||
me.addlog('Player event fired: '+e.type);
|
me.addlog('Player event fired: '+e.type);
|
||||||
},true);
|
});
|
||||||
}
|
}
|
||||||
return cont;
|
return cont;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +181,32 @@ p.prototype.loop = function(bool){
|
||||||
}
|
}
|
||||||
return this.element.loop = bool;
|
return this.element.loop = bool;
|
||||||
};
|
};
|
||||||
p.prototype.load = function(){ return this.element.load(); };
|
p.prototype.load = function(){
|
||||||
|
var load;
|
||||||
|
if (this.element.paused) {
|
||||||
|
load = this.element.load();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//sometimes there is a play / pause interrupt: try again
|
||||||
|
//TODO figure out if this happens on paused or on playing
|
||||||
|
this.load();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this helps to prevent the player from just showing a black screen after a reload
|
||||||
|
if (this.element.paused) {
|
||||||
|
var me = this;
|
||||||
|
var unpause = function(){
|
||||||
|
if (me.element.paused) {
|
||||||
|
me.element.play();
|
||||||
|
}
|
||||||
|
me.element.removeEventListener('progress',unpause);
|
||||||
|
}
|
||||||
|
this.element.addEventListener('progress',unpause);
|
||||||
|
}
|
||||||
|
|
||||||
|
return load;
|
||||||
|
};
|
||||||
if (document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled) {
|
if (document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled) {
|
||||||
p.prototype.fullscreen = function(){
|
p.prototype.fullscreen = function(){
|
||||||
if(this.element.requestFullscreen) {
|
if(this.element.requestFullscreen) {
|
||||||
|
|
|
@ -6,15 +6,30 @@ mistplayers.videojs = {
|
||||||
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
return (this.mimes.indexOf(mimetype) == -1 ? false : true);
|
||||||
},
|
},
|
||||||
isBrowserSupported: function (mimetype,source,options,streaminfo,logfunc) {
|
isBrowserSupported: function (mimetype,source,options,streaminfo,logfunc) {
|
||||||
|
|
||||||
|
//dont use https if the player is loaded over http
|
||||||
if ((options.host.substr(0,7) == 'http://') && (source.url.substr(0,8) == 'https://')) {
|
if ((options.host.substr(0,7) == 'http://') && (source.url.substr(0,8) == 'https://')) {
|
||||||
if (logfunc) { logfunc('HTTP/HTTPS mismatch for this source'); }
|
if (logfunc) { logfunc('HTTP/HTTPS mismatch for this source'); }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var support = true;
|
|
||||||
|
//dont use videojs if this location is loaded over file://
|
||||||
if ((location.protocol == 'file:') && (mimetype == 'html5/application/vnd.apple.mpegurl')) {
|
if ((location.protocol == 'file:') && (mimetype == 'html5/application/vnd.apple.mpegurl')) {
|
||||||
if (logfunc) { logfunc('This source ('+mimetype+') won\'t work if the page is run via file://'); }
|
if (logfunc) { logfunc('This source ('+mimetype+') won\'t work if the page is run via file://'); }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//dont use HLS if there is an MP3 audio track, unless we're on apple or edge
|
||||||
|
if ((mimetype == 'html5/application/vnd.apple.mpegurl') && (['iPad','iPhone','iPod','MacIntel'].indexOf(navigator.platform) == -1) && (navigator.userAgent.indexOf('Edge') == -1)) {
|
||||||
|
for (var i in streaminfo.meta.tracks) {
|
||||||
|
var t = streaminfo.meta.tracks[i];
|
||||||
|
if (t.codec == 'MP3') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return ('MediaSource' in window);
|
return ('MediaSource' in window);
|
||||||
},
|
},
|
||||||
player: function(){},
|
player: function(){},
|
||||||
|
|
Loading…
Add table
Reference in a new issue