assets/js/interactivePlayer.js

398 lines
15 KiB
JavaScript

var interactivePlayerSelfScriptPath = document.getElementsByTagName('script')[document.getElementsByTagName('script').length-1].src;
function loadJsWindows (callback) {
if (window.JSWindow) callback();
else {
var jswScript = document.getElementById('JSWindowScript');
if (jswScript)
jswScript.addEventListener('load', callback);
else {
if (interactivePlayerSelfScriptPath.indexOf('\/interactivePlayer.js') < 0) throw 'interactivePlayer.js cannot determine its script path. You have to load it when page loads.';
var selfScriptPath = interactivePlayerSelfScriptPath.substring(0, interactivePlayerSelfScriptPath.lastIndexOf('\/')+1);
jswScript = document.createElement('script');
jswScript.setAttribute('type', 'text/javascript');
jswScript.addEventListener('load', callback);
jswScript.src = selfScriptPath+'JSWindow.js';
document.getElementsByTagName('head')[0].appendChild(jswScript);
}
}
}
window.previewVideoWin = null;
window.showPreview = function (preview, video, asWindow=true) {
if (player && player.currentVideo >= 0) return;
loadJsWindows(function () {
let img = document.createElement('img');
img.src = preview;
img.style.width = '100%';
img.style.height = '100%';
img.style.cursor = 'pointer';
let previewVideoWin = new JSWindow();
window.previewVideoWin = previewVideoWin;
if (asWindow) previewVideoWin.pos.position = 'fixed';
else previewVideoWin.pos.position = 'absolute';
previewVideoWin.pos.top = Number.NaN;
previewVideoWin.pos.left = 10;
previewVideoWin.pos.width = 300;
previewVideoWin.pos.height = 220;
previewVideoWin.pos.right = Number.NaN;
previewVideoWin.pos.bottom = 10;
previewVideoWin.minimizable = false;
previewVideoWin.maximizable = !asWindow;
previewVideoWin.setTitle('Video');
previewVideoWin.el['InnerBox'].appendChild(img);
previewVideoWin.el['InnerBox'].style.overflow = 'hidden';
previewVideoWin.addEventListener('hide', function () {
window.previewVideoWin = null;
});
previewVideoWin.show((asWindow)?document.body:document.getElementById('SideVideo'));
if (!asWindow) previewVideoWin.maximize();
img.addEventListener('click', function () {
player.play(video, 0, true);
}, false);
});
}
function InteractivePlayer () {
var _this = this;
this.queryActions = new Array();
this.playlist = new Array();
if (interactivePlayerSelfScriptPath.indexOf('\/interactivePlayer.js') < 0) throw 'interactivePlayer.js cannot determine its script path. You have to load it when page loads.';
this.selfScriptPath = interactivePlayerSelfScriptPath.substring(0, interactivePlayerSelfScriptPath.lastIndexOf('\/')+1);
function videoQualityLoad () {
_this.loading = false;
while (_this.queryActions.length > 0) {
var act = _this.queryActions.shift();
var fkt = act.shift();
fkt.apply(_this, act);
}
}
function videojsLoad () {
var qualitySelectScript = document.createElement('script');
qualitySelectScript.setAttribute('type', 'text/javascript');
qualitySelectScript.addEventListener('load', videoQualityLoad);
qualitySelectScript.src = _this.selfScriptPath+'silvermine-videojs-quality-selector.min.js';
document.body.appendChild(qualitySelectScript);
}
loadJsWindows(function () {
if (window.videojs) videojsLoad();
else {
window.HELP_IMPROVE_VIDEOJS = false;
var videojsStyle = document.createElement('link');
videojsStyle.setAttribute('rel', 'stylesheet');
let cssPath = _this.selfScriptPath.split('/');
if (cssPath.pop() == '') cssPath.pop();
videojsStyle.href = cssPath.join('/')+'/css/video-js.min.css';
document.getElementsByTagName('head')[0].appendChild(videojsStyle);
var videoScript = document.createElement('script');
videoScript.setAttribute('type', 'text/javascript');
videoScript.addEventListener('load', videojsLoad);
videoScript.src = _this.selfScriptPath+'video.min.js';
document.body.appendChild(videoScript);
}
});
}
InteractivePlayer.prototype = {
// private
selfScriptPath : '',
win : null,
video : null,
player : null,
playlist : null,
loading : true,
queryActions : null,
currentVideo : -1,
currentAction : 0,
prevBut : null,
nextBut : null,
_asWindow : true,
get asWindow () { return this._asWindow; }, set asWindow (v) {
if (this.win) {
this.win.maximizable = !this._asWindow;
if (v) {
this.win.show(document.body);
this.win.normalize();
if (!this._asWindow) this.win.hide();
} else {
this.win.show(document.getElementById('SideVideo'));
this.win.maximize();
}
}
this._asWindow = v;
},
timeset : -1,
playall : false,
lastWaiting : null, // contains alternating pairs of video time and real time
indexById : /* private */ function (id) {
for (var i = 0; i < this.playlist.length; i++)
if (this.playlist[i].id == id)
return i;
return -1;
},
videoByHashtag : /* public */ function (hashtag) {
for (var i = 0; i < this.playlist.length; i++)
if (this.playlist[i].hashtags && this.playlist[i].hashtags.indexOf(hashtag) >= 0)
return this.playlist[i].id;
return '';
},
timeupdate : /* private */ function () {
if (this.timeset >= 0) {
this.video.currentTime = this.timeset;
this.timeset = -1;
}
if (this.currentVideo < 0 || !this.playlist[this.currentVideo].actions) return;
var t = this.video.currentTime;
var stopInd = this.currentAction;
while (stopInd < this.playlist[this.currentVideo].actions.length)
if (this.playlist[this.currentVideo].actions[stopInd].time > t) break;
else stopInd++;
while (this.currentAction < stopInd) {
try {
if ((this.currentAction == stopInd-1 || this.playlist[this.currentVideo].actions[this.currentAction].required) && this.playlist[this.currentVideo].actions[this.currentAction].fkt)
this.playlist[this.currentVideo].actions[this.currentAction].fkt.call(this, this.currentAction == stopInd-1);
} finally {
this.currentAction++;
}
}
},
videoended : /* private */ function () {
if (!this.playall) return;
if (this.currentVideo >= this.playlist.length-1) {
this.playall = false;
return;
}
this.currentVideo++;
this.currentAction = 0;
this.loadVideo(this.currentVideo);
try {
this.player.play();
} catch (e) { }
},
getCurrentQuality : /* private */ function () {
var q = null;
var quality = '';
for (var i = 0; i < this.video.parentElement.getElementsByTagName('div').length; i++)
if (this.video.parentElement.getElementsByTagName('div')[i].className.indexOf('vjs-quality-selector') >= 0) {
q = this.video.parentElement.getElementsByTagName('div')[i];
break;
}
if (q) {
for (var i = 0; i < q.getElementsByTagName('li').length; i++)
if (q.getElementsByTagName('li')[i].className.indexOf('vjs-menu-item') >= 0) if (q.getElementsByTagName('li')[i].className.indexOf('vjs-selected') >= 0) {
q = q.getElementsByTagName('li')[i];
break;
}
if (q) {
for (var i = 0; i < q.getElementsByTagName('span').length; i++)
if (q.getElementsByTagName('span')[i].className.indexOf('vjs-menu-item-text') >= 0) {
q = q.getElementsByTagName('span')[i];
break;
}
if (q) {
quality = q.textContent;
}
}
}
return quality;
},
videowaiting : /* private */ function (timerRecall=false) {
var _this = this;
this.lastWaiting.push(this.video.currentTime);
this.lastWaiting.push(Math.floor(Date.now() / 1000));
if (!timerRecall)
window.setTimeout(function () { _this.videowaiting(true); }, 2000);
var l = this.lastWaiting.length;
if (!timerRecall && l >= 8 || l >= 4 && (this.lastWaiting[l-2] - this.lastWaiting[l-4]) * 2 + 1 < (this.lastWaiting[l-1] - this.lastWaiting[l-3])) {
var quality = this.getCurrentQuality();
var redQualBegin = '!';
if (quality.indexOf('1080p') >= 0)
redQualBegin = '720p';
if (quality.indexOf('720p') >= 0)
redQualBegin = '400p';
this.lastWaiting = new Array();
if (redQualBegin == '!') return;
console.log('Reducing video quality to '+redQualBegin);
var q = null;
for (var i = 0; i < this.video.parentElement.getElementsByTagName('div').length; i++)
if (this.video.parentElement.getElementsByTagName('div')[i].className.indexOf('vjs-quality-selector') >= 0) {
q = this.video.parentElement.getElementsByTagName('div')[i];
break;
}
if (q) {
for (var i = 0; i < q.getElementsByTagName('li').length; i++)
if (q.getElementsByTagName('li')[i].className.indexOf('vjs-menu-item') >= 0)
if (q.getElementsByTagName('li')[i].textContent.indexOf(redQualBegin) >= 0) {
q.getElementsByTagName('li')[i].click();
break;
}
}
}
},
closeWindow : /* private */ function () {
if (this.currentVideo >= 0 || this.playlist[this.currentVideo].actions)
while (this.currentAction < this.playlist[this.currentVideo].actions.length) {
try {
if (this.playlist[this.currentVideo].actions[this.currentAction].final && this.playlist[this.currentVideo].actions[this.currentAction].fkt)
this.playlist[this.currentVideo].actions[this.currentAction].fkt.call(this, false);
} catch (e) { }
this.currentAction++;
}
this.player.dispose();
this.freePlayer();
},
freePlayer : /* private */ function () {
this.video = null;
this.player = null;
this.win = null;
this.prevBut = null;
this.nextBut = null;
this.currentVideo = -1;
},
createWindow : /* prvate */ function () {
if (this.win) throw 'Window already created!';
this.playall = false;
var _this = this;
this.win = new JSWindow();
this.win.pos.position = 'fixed';
this.win.pos.top = 300;
this.win.pos.left = 150;
this.win.pos.width = Number.NaN;
this.win.pos.height = Number.NaN;
this.win.pos.right = 150;
this.win.pos.bottom = 10;
this.win.excludable = true;
this.win.minimizable = !this.asWindow;
this.win.setTitle('Video');
this.win.addEventListener('hide', function () { _this.closeWindow(); });
this.win.addEventListener('free', function () { _this.freePlayer(); });
this.video = document.createElement('video');
this.video.className = 'video-js';
this.video.setAttribute('controls', '');
this.video.disablePictureInPicture = true;
this.video.addEventListener('timeupdate', function () { _this.timeupdate(); }, false);
this.video.addEventListener('ended', function () { _this.videoended(); }, false);
this.video.addEventListener('waiting', function () { _this.videowaiting(); }, false);
this.win.el['InnerBox'].appendChild(this.video);
this.win.show((this.asWindow)?document.body:document.getElementById('SideVideo'));
if (!this.asWindow) this.win.maximize();
this.player = videojs(this.video);
this.player.controlBar.addChild('QualitySelector');
var divs = this.video.parentElement.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++)
if ((' '+divs[i].className+' ').indexOf(' vjs-control-bar ') >= 0) {
this.nextBut = document.createElement('a');
this.nextBut.href = 'javascript:';
this.nextBut.className = 'video-next-but';
this.nextBut.addEventListener('click', function () {
_this.next();
});
this.nextBut.innerHTML = 'n&auml;chstes Video &#9654; &#9654;';
divs[i].appendChild(this.nextBut);
this.prevBut = document.createElement('a');
this.prevBut.href = 'javascript:';
this.prevBut.className = 'video-prev-but';
this.prevBut.addEventListener('click', function () {
_this.prev();
});
this.prevBut.innerHTML = '&#9664; &#9664; vorheriges Video';
divs[i].appendChild(this.prevBut);
break;
}
},
clearPlaylist : /* public */ function () {
if (this.player) this.player.pause();
this.playlist = new Array();
this.currentVideo = -1;
},
loadVideo : /* private */ function (nr) {
if (this.prevBut)
this.prevBut.style.visibility = (nr > 0)?'visible':'hidden';
if (this.nextBut)
this.nextBut.style.visibility = (nr < this.playlist.length - 1)?'visible':'hidden';
var url = this.playlist[nr].src;
var quality = this.getCurrentQuality();
this.player.src([
{type: "video\/mp4", src: url+((this.playlist[nr].fixedResolution)?'.mp4':'-1080p.mp4'), label: '1080p 50fps', selected: (quality == '1080p 50fps')},
{type: "video\/mp4", src: url+((this.playlist[nr].fixedResolution)?'.mp4':'-720p.mp4'), label: '720p 25fps', selected: (quality == '720p 25fps')},
{type: "video\/mp4", src: url+((this.playlist[nr].fixedResolution)?'.mp4':'-400p.mp4'), label: '400p 25fps', selected: (quality == '400p 25fps')},
]);
this.lastWaiting = [0, Math.floor(Date.now() / 1000)];
},
addVideo : /* public */ function (videoInfo) {
if (videoInfo.actions)
videoInfo.actions.sort(function (a, b) { return a.time - b.time; });
var absPath = document.createElement('a');
absPath.style.display = 'none';
document.body.appendChild(absPath);
absPath.href = videoInfo.src;
videoInfo.src = absPath.href;
document.body.removeChild(absPath);
this.playlist.push(videoInfo);
},
play : /* public */ function (id, time=-1, playall=false) {
if (window.previewVideoWin)
window.previewVideoWin.hide();
var i = this.indexById(id);
if (i < 0) return;
if (this.loading) {
this.queryActions.push([this.play, id, time]);
return;
}
this.currentVideo = i;
this.currentAction = 0;
if (!this.win)
this.createWindow();
else if (!this.win.visible) this.win.show((this.asWindow)?document.body:document.getElementById('SideVideo'));
this.loadVideo(i);
this.timeset = time;
try {
this.player.play();
if (playall) this.playall = true;
} catch (e) { }
},
playAll : /* public */ function () {
if (this.playlist.length == 0) return;
if (this.loading) {
this.queryActions.push([this.playAll]);
return;
}
this.play(this.playlist[0].id);
this.playall = true;
},
next : /* public */ function () {
if (this.loading) {
this.queryActions.push([this.next]);
return;
}
if (this.currentVideo >= this.playlist.length-1) return;
this.play(this.playlist[this.currentVideo+1].id);
this.playall = this.video.paused;
},
prev : /* public */ function () {
if (this.loading) {
this.queryActions.push([this.prev]);
return;
}
if (this.currentVideo <= 0) return;
this.play(this.playlist[this.currentVideo-1].id);
}
};