various embed tweaks

This commit is contained in:
Cat 2017-02-27 14:27:33 +01:00 committed by Thulinma
parent dc6d0643bb
commit 899ee1088a
6 changed files with 256 additions and 370 deletions

1
.gitignore vendored
View file

@ -57,4 +57,5 @@ rules.ninja
.ninja_log .ninja_log
.ninja_deps .ninja_deps
aes_ctr128 aes_ctr128
/embed/testing

View file

@ -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

View file

@ -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>

View file

@ -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) {

View file

@ -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(){},