Merge branch 'dev-ksplayer' into dev
This commit is contained in:
@@ -1,60 +1,13 @@
|
||||
[#ftl]
|
||||
[#include "/header.inc.ftl"]
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/js-cookie/2.1.0/js.cookie.min.js"></script>
|
||||
<script type="text/javascript" src="/js/player.js"></script>
|
||||
|
||||
<div class="modal fade" tabindex="-1" role="dialog" id="modal">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Продолжить просмотр?</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<b>Время:</b> <span id="mdl-vtime"></span>
|
||||
<div id="mdl-blk-serial">
|
||||
<div id="mdl-season" class="hide"><b>Сезон:</b> <span></span></div>
|
||||
<div id="mdl-serial" class="hide"><b>Серия:</b> <span></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="mdl-btn-yes" type="button" class="btn btn-primary" data-dismiss="modal">Да</button>
|
||||
<button id="mdl-btn-no" type="button" class="btn btn-default" data-dismiss="modal">Нет</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="/js/ksplayer.js"></script>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="pl-season" class="dropdown hide" style="display: inline-block;">
|
||||
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownSeason" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
Seasons
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul id="pl-season-menu" class="dropdown-menu" aria-labelledby="dropdownSeason">
|
||||
<li><a href="#">Season</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="pl-serial" class="dropdown hide" style="display: inline-block;">
|
||||
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownSerial" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
Serials
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul id="pl-serial-menu" class="dropdown-menu" aria-labelledby="dropdownSerial">
|
||||
<li><a href="#">Serial</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<br id="plbr">
|
||||
|
||||
<h2 id="title"></h2>
|
||||
|
||||
<br>
|
||||
|
||||
<video id="player" class="center-block" controls="controls" preload="none"></video>
|
||||
<div id="ksplayer"></div>
|
||||
<br>
|
||||
<script type="text/javascript">
|
||||
const playerCore = initPlayer(${json});
|
||||
const ksplayer = new KSPlayer('ksplayer', ${json});
|
||||
</script>
|
||||
[#include "/fother.inc.ftl"]
|
||||
257
src/main/resources/kinosearch/webapp/static/js/ksplayer.js
Normal file
257
src/main/resources/kinosearch/webapp/static/js/ksplayer.js
Normal file
@@ -0,0 +1,257 @@
|
||||
const KSPlayer = function(containerId, data) {
|
||||
/* --- FIELDS -------------- */
|
||||
|
||||
let isShowTitle = false;
|
||||
|
||||
/* --- PRIVATE FIELDS ------ */
|
||||
|
||||
let titleElement;
|
||||
let seasonSerials = [];
|
||||
const _self = this;
|
||||
let lastActiveSerialItem;
|
||||
let lastActiveSeasonItem;
|
||||
|
||||
/* --- PRIVATE FUNCTIONS --- */
|
||||
|
||||
function createSerialMenuElement(serials) {
|
||||
let div = document.createElement('div');
|
||||
div.id = 'pl-serial';
|
||||
div.className = 'dropdown';
|
||||
div.style = 'display: inline-block';
|
||||
|
||||
let button = document.createElement('button');
|
||||
button.className = 'btn btn-default dropdown-toggle';
|
||||
button.type = 'button';
|
||||
button.id = 'dropdownSerial';
|
||||
button.setAttribute('data-toggle', 'dropdown');
|
||||
button.setAttribute('aria-haspopup', 'true');
|
||||
button.setAttribute('aria-expanded', 'true');
|
||||
|
||||
let text = document.createTextNode('Serials');
|
||||
|
||||
let span = document.createElement('span');
|
||||
span.className = 'caret';
|
||||
span.style = 'margin-left: .5em';
|
||||
|
||||
let ul = document.createElement('ul');
|
||||
ul.id = 'pl-serial-menu';
|
||||
ul.className = 'dropdown-menu';
|
||||
ul.setAttribute('aria-labelledby', 'dropdownSerial');
|
||||
|
||||
serials.forEach(item => {
|
||||
let li = document.createElement('li');
|
||||
let a = document.createElement('a');
|
||||
a.href = '#';
|
||||
a.innerText = item.title;
|
||||
a.onclick = function() {
|
||||
text.nodeValue = item.title;
|
||||
setTitle(item.title);
|
||||
|
||||
if (lastActiveSerialItem) {
|
||||
lastActiveSerialItem.classList.remove('active');
|
||||
}
|
||||
li.classList.add('active');
|
||||
lastActiveSerialItem = li;
|
||||
|
||||
setSource(item.file);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
li.appendChild(a);
|
||||
ul.appendChild(li);
|
||||
});
|
||||
|
||||
button.appendChild(text);
|
||||
button.appendChild(span);
|
||||
div.appendChild(button);
|
||||
div.appendChild(ul);
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
function createSeasonMenuElement(seasons) {
|
||||
let div = document.createElement('div');
|
||||
div.id = 'pl-season';
|
||||
div.className = 'dropdown';
|
||||
div.style = 'display: inline-block';
|
||||
div.kspSerialMenuElement = undefined;
|
||||
|
||||
let button = document.createElement('button');
|
||||
button.className = 'btn btn-default dropdown-toggle';
|
||||
button.type = 'button';
|
||||
button.id = 'dropdownSeason';
|
||||
button.setAttribute('data-toggle', 'dropdown');
|
||||
button.setAttribute('aria-haspopup', 'true');
|
||||
button.setAttribute('aria-expanded', 'true');
|
||||
|
||||
let text = document.createTextNode('Seasons');
|
||||
|
||||
let span = document.createElement('span');
|
||||
span.className = 'caret';
|
||||
span.style = 'margin-left: .5em';
|
||||
|
||||
let ul = document.createElement('ul');
|
||||
ul.id = 'pl-season-menu';
|
||||
ul.className = 'dropdown-menu';
|
||||
ul.setAttribute('aria-labelledby', 'dropdownSeason');
|
||||
|
||||
seasons.forEach((item, idx) => {
|
||||
let li = document.createElement('li');
|
||||
let a = document.createElement('a');
|
||||
a.href = '#';
|
||||
a.innerText = item.title;
|
||||
a.setAttribute('data-number', idx);
|
||||
a.onclick = function() {
|
||||
text.nodeValue = item.title;
|
||||
|
||||
if (lastActiveSeasonItem) {
|
||||
lastActiveSeasonItem.classList.remove('active');
|
||||
}
|
||||
li.classList.add('active');
|
||||
lastActiveSeasonItem = li;
|
||||
|
||||
if (div.kspSerialMenuElement) {
|
||||
containerElement.removeChild(div.kspSerialMenuElement);
|
||||
}
|
||||
containerElement.insertAfter(seasonSerials[idx], div);
|
||||
div.kspSerialMenuElement = seasonSerials[idx];
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
seasonSerials.push(createSerialMenuElement(item.serials));
|
||||
li.appendChild(a);
|
||||
ul.appendChild(li);
|
||||
});
|
||||
|
||||
button.appendChild(text);
|
||||
button.appendChild(span);
|
||||
div.appendChild(button);
|
||||
div.appendChild(ul);
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
function initTitleElement() {
|
||||
titleElement = document.createElement('h2');
|
||||
titleElement.id = 'title';
|
||||
}
|
||||
|
||||
function createVideoElement() {
|
||||
let videoElement = document.createElement('video');
|
||||
videoElement.id = 'player';
|
||||
videoElement.className = 'center-block';
|
||||
videoElement.setAttribute('controls', 'controls');
|
||||
videoElement.setAttribute('preload', 'none');
|
||||
|
||||
if (videoElement.requestFullscreen) {
|
||||
videoElement.kspFullScreen = videoElement.requestFullscreen;
|
||||
} else if (videoElement.mozRequestFullScreen) {
|
||||
videoElement.kspFullScreen = videoElement.mozRequestFullScreen; // Firefox
|
||||
} else if (videoElement.webkitRequestFullscreen) {
|
||||
videoElement.kspFullScreen = videoElement.webkitRequestFullscreen; // Chrome and Safari
|
||||
} else {
|
||||
console.warn('KSPlayer: can\'t use fullscreen mode =(');
|
||||
videoElement.kspFullScreen = function() { return false; };
|
||||
}
|
||||
|
||||
videoElement.onkeydown = function(e) {
|
||||
// 32 - Space
|
||||
if (e.keyCode === 32) {
|
||||
if (videoElement.paused) {
|
||||
videoElement.play();
|
||||
} else {
|
||||
videoElement.pause();
|
||||
}
|
||||
}
|
||||
|
||||
// 37 - Left arrow
|
||||
if (e.keyCode === 37) {
|
||||
videoElement.currentTime -= 5;
|
||||
}
|
||||
// 39 - Right arrow
|
||||
else if (e.keyCode === 39) {
|
||||
videoElement.currentTime += 5;
|
||||
}
|
||||
|
||||
// 38 - Up arrow
|
||||
if (e.keyCode === 38 && videoElement.volume < 1) {
|
||||
if ((videoElement.volume + 0.1) < 1) {
|
||||
videoElement.volume += 0.1;
|
||||
} else {
|
||||
videoElement.volume = 1;
|
||||
}
|
||||
}
|
||||
// 40 - Down arrow
|
||||
else if (e.keyCode === 40 && videoElement.volume > 0) {
|
||||
if ((videoElement.volume - 0.1) >= 0) {
|
||||
videoElement.volume -= 0.1;
|
||||
} else {
|
||||
videoElement.volume = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 70 - F
|
||||
if (e.keyCode === 70) {
|
||||
videoElement.kspFullScreen();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return videoElement;
|
||||
}
|
||||
|
||||
function setSource(source) {
|
||||
videoElement.src = source;
|
||||
}
|
||||
|
||||
function setTitle(text) {
|
||||
if (text) {
|
||||
if (!titleElement) initTitleElement();
|
||||
titleElement.innerText = text;
|
||||
|
||||
if (!isShowTitle) {
|
||||
containerElement.insertBefore(titleElement, videoElement);
|
||||
isShowTitle = true;
|
||||
}
|
||||
} else {
|
||||
if (isShowTitle && titleElement) {
|
||||
containerElement.removeChild(titleElement);
|
||||
isShowTitle = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* --- CONSTRUCTOR --------- */
|
||||
|
||||
const containerElement = document.getElementById(containerId);
|
||||
if (containerElement === null) {
|
||||
throw `Container "${containerId}" not found!`;
|
||||
}
|
||||
|
||||
containerElement.insertAfter = function(newChild, refChild) {
|
||||
this.insertBefore(newChild, refChild.nextSibling);
|
||||
}
|
||||
|
||||
let videoElement = createVideoElement();
|
||||
|
||||
if (data.hasOwnProperty('title')) {
|
||||
this.setTitle(data.title);
|
||||
}
|
||||
|
||||
if (data.type === 'simple_serial') {
|
||||
let serialMenu = createSerialMenuElement(data.serials);
|
||||
containerElement.appendChild(serialMenu);
|
||||
containerElement.appendChild(document.createElement('br'));
|
||||
containerElement.appendChild(document.createElement('br'));
|
||||
} else if (data.type === 'seasons_serial') {
|
||||
let seasonMenu = createSeasonMenuElement(data.seasons);
|
||||
containerElement.appendChild(seasonMenu);
|
||||
containerElement.appendChild(document.createElement('br'));
|
||||
containerElement.appendChild(document.createElement('br'));
|
||||
}
|
||||
|
||||
containerElement.appendChild(videoElement);
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
const PlayerCore = function(playerObj, titleObj, videoData) {
|
||||
this.path = window.location.pathname;
|
||||
this.origDocTitle = document.title;
|
||||
this.timeLast = 0;
|
||||
|
||||
const _this = this;
|
||||
|
||||
/* временно отключаю возможность авто-сохранения времени просмотра
|
||||
// сохранение времени просмотра
|
||||
playerObj.bind('play', function() {
|
||||
_this.timeLast = $.now();
|
||||
});
|
||||
|
||||
playerObj.bind('timeupdate', function() {
|
||||
let timeCurrent = $.now();
|
||||
let sec = Math.floor((timeCurrent - _this.timeLast)/1000);
|
||||
if (sec >= 5) {
|
||||
let playerCurrentTime = playerObj[0].currentTime;
|
||||
if (Math.floor(playerCurrentTime) <= 10)
|
||||
return;
|
||||
let save_data = { 'time': playerCurrentTime };
|
||||
Cookies.set(_this.path, save_data, { 'expires': 30 });
|
||||
_this.timeLast = timeCurrent;
|
||||
console.debug({
|
||||
'path': _this.path,
|
||||
'saveTime': save_data
|
||||
}); //TODO убрать на продакшене
|
||||
}
|
||||
});
|
||||
*/
|
||||
this.getType = function() {
|
||||
return videoData.type;
|
||||
};
|
||||
|
||||
this.setTitle = function(title) {
|
||||
if (!title) {
|
||||
title = videoData.title;
|
||||
}
|
||||
document.title = title + " :: " + _this.origDocTitle;
|
||||
titleObj.text(title);
|
||||
titleObj.show();
|
||||
};
|
||||
|
||||
this.setupForOneFilm = function() {
|
||||
playerObj.attr('src', videoData.file);
|
||||
playerObj.load();
|
||||
};
|
||||
|
||||
this.setupForSimpleSerial = function(serialBlock) {
|
||||
let menu = serialBlock.find('.dropdown-menu');
|
||||
menu.html('');
|
||||
let _self = this;
|
||||
videoData.serials.forEach(function(item, i) {
|
||||
let aTag = $('<a/>', { 'href': '#', 'text': item.title });
|
||||
aTag.click(function() {
|
||||
_self.setSerial(i, serialBlock);
|
||||
});
|
||||
let liTag = $('<li/>');
|
||||
liTag.append(aTag);
|
||||
menu.append(liTag);
|
||||
});
|
||||
|
||||
serialBlock.removeClass('hide');
|
||||
};
|
||||
|
||||
this.setupForSeasonSerial = function(seasonBlock, serialBlock) {
|
||||
let menu = seasonBlock.find('.dropdown-menu');
|
||||
menu.html('');
|
||||
let _self = this;
|
||||
videoData.seasons.forEach(function(item, i) {
|
||||
let aTag = $('<a/>', { 'href': '#', 'text': item.title });
|
||||
aTag.click(function() {
|
||||
_self.setSeason(i, seasonBlock, serialBlock);
|
||||
});
|
||||
let liTag = $('<li/>');
|
||||
liTag.append(aTag);
|
||||
menu.append(liTag);
|
||||
});
|
||||
|
||||
seasonBlock.removeClass('hide');
|
||||
};
|
||||
|
||||
this.setSerial = function(idx, serialBlock, sidx) {
|
||||
if (!sidx) {
|
||||
sidx = 0;
|
||||
}
|
||||
|
||||
let title;
|
||||
let playerSrc;
|
||||
if (_this.getType() == 'seasons_serial') {
|
||||
title = videoData.seasons[sidx].serials[idx].title;
|
||||
playerSrc = videoData.seasons[sidx].serials[idx].file;
|
||||
} else {
|
||||
title = videoData.serials[idx].title;
|
||||
playerSrc = videoData.serials[idx].file;
|
||||
}
|
||||
_this.setTitle(title);
|
||||
|
||||
let menuBtn = serialBlock.find('#dropdownSerial');
|
||||
menuBtn.html(title + ' <span class="caret"></span>');
|
||||
|
||||
playerObj.attr('src', playerSrc);
|
||||
playerObj.attr('data-serial', idx);
|
||||
};
|
||||
|
||||
this.setTime = function(time) {
|
||||
playerObj[0].currentTime = time;
|
||||
};
|
||||
|
||||
this.load = function() {
|
||||
playerObj.load();
|
||||
};
|
||||
};
|
||||
|
||||
function msToTime(ms) {
|
||||
function addZ(n) {
|
||||
return (n < 10 ? '0' : '') + n;
|
||||
}
|
||||
|
||||
const _ms = ms % 1000;
|
||||
ms = (ms - _ms) / 1000;
|
||||
const _sec = ms % 60;
|
||||
ms = (ms - _sec) / 60;
|
||||
const _min = ms % 60;
|
||||
const _hr = (ms - _min) / 60;
|
||||
|
||||
return {
|
||||
'sec': addZ(_sec),
|
||||
'min': addZ(_min),
|
||||
'hour': addZ(_hr)
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
function loadPlayerCookieData(playerCore) {
|
||||
let data = Cookies.getJSON(playerCore.path);
|
||||
|
||||
if (data != null) {
|
||||
let fulltime = msToTime(data.time * 1000);
|
||||
$('#mdl-vtime').text(fulltime.hour + ':' + fulltime.min + ':' + fulltime.sec);
|
||||
|
||||
if (playerCore.getType() == 'simple_serial') {
|
||||
$('#mdl-serial').find('span').text(data.serial + 1);
|
||||
$('#mdl-serial').removeClass('hide');
|
||||
|
||||
$('#mdl-btn-yes').click(function() {
|
||||
playerCore.setSerial(data.serial, $('#pl-serial'));
|
||||
|
||||
playerCore.setTime(data.time);
|
||||
playerCore.load();
|
||||
});
|
||||
|
||||
$('#mdl-btn-no').click(function() {
|
||||
playerCore.load();
|
||||
});
|
||||
} else if (playerCore.getType() == 'seasons_serial') {
|
||||
$('#mdl-season').find('span').text(data.season + 1);
|
||||
$('#mdl-season').removeClass('hide');
|
||||
$('#mdl-serial').find('span').text(data.serial + 1);
|
||||
$('#mdl-serial').removeClass('hide');
|
||||
|
||||
$('#mdl-btn-yes').click(function() {
|
||||
playerCore.setSeason(data.season, $('#pl-season'));
|
||||
playerCore.setSerial(data.serial, $('#pl-serial'), data.season);
|
||||
|
||||
playerCore.setTime(data.time);
|
||||
playerCore.load();
|
||||
});
|
||||
|
||||
$('#mdl-btn-no').click(function() {
|
||||
playerCore.load();
|
||||
});
|
||||
}
|
||||
$('#modal').modal('show');
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
function initPlayer(video_data) {
|
||||
const playerCore = new PlayerCore($('#player'), $('#title'), video_data);
|
||||
|
||||
// загрузка ранее сохранённых данных
|
||||
//loadPlayerCookieData(playerCore);
|
||||
|
||||
if (playerCore.getType() == 'one_film') {
|
||||
playerCore.setTitle();
|
||||
playerCore.setupForOneFilm();
|
||||
} else if (playerCore.getType() == 'simple_serial') {
|
||||
playerCore.setupForSimpleSerial($('#pl-serial'));
|
||||
$('#title').hide();
|
||||
} else if (playerCore.getType() == 'seasons_serial') {
|
||||
playerCore.setupForSeasonSerial($('#pl-season'), $('#pl-serial'));
|
||||
$('#title').hide();
|
||||
} else {
|
||||
console.debug(video_data); //TODO убрать из продакшена
|
||||
}
|
||||
|
||||
return playerCore;
|
||||
}
|
||||
Reference in New Issue
Block a user