398 lines
15 KiB
JavaScript
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ächstes Video ▶ ▶';
|
|
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 = '◀ ◀ 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);
|
|
}
|
|
};
|