0

Merge branch 'dev-ksplayer' into dev

This commit is contained in:
2017-12-15 14:59:10 +03:00
3 changed files with 260 additions and 249 deletions

View File

@@ -1,60 +1,13 @@
[#ftl] [#ftl]
[#include "/header.inc.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="//cdnjs.cloudflare.com/ajax/libs/js-cookie/2.1.0/js.cookie.min.js"></script>
<script type="text/javascript" src="/js/player.js"></script> <script type="text/javascript" src="/js/ksplayer.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>
<hr> <hr>
<div id="pl-season" class="dropdown hide" style="display: inline-block;"> <div id="ksplayer"></div>
<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>
<br> <br>
<script type="text/javascript"> <script type="text/javascript">
const playerCore = initPlayer(${json}); const ksplayer = new KSPlayer('ksplayer', ${json});
</script> </script>
[#include "/fother.inc.ftl"] [#include "/fother.inc.ftl"]

View 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);
}

View File

@@ -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 + '&nbsp;<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;
}