You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
478 lines
16 KiB
478 lines
16 KiB
function toHHMMSS(num) {
|
|
var sec_num = parseInt(num, 10); // don't forget the second param
|
|
var hours = Math.floor(sec_num / 3600);
|
|
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
|
|
var seconds = sec_num - (hours * 3600) - (minutes * 60);
|
|
|
|
if (hours < 10) {hours = '0'+hours;}
|
|
if (minutes < 10) {minutes = '0'+minutes;}
|
|
if (seconds < 10) {seconds = '0'+seconds;}
|
|
|
|
var times = '';
|
|
if(hours > 0){times += hours+':'}
|
|
return times + minutes + ':' + seconds;
|
|
}
|
|
|
|
let player = null;
|
|
let sliderTrack = null;
|
|
let sliderSound = null;
|
|
|
|
function launchPlayer(view) {
|
|
let lastTimeMouseMoved = null;
|
|
let timeout = null;
|
|
let buffered = null;
|
|
let totaltime = null;
|
|
|
|
let left = null;
|
|
|
|
let data_movie = $(view)[0];
|
|
let movie_src = $(data_movie).data('src');
|
|
let movie_type = $(data_movie).data('movie-type');
|
|
let data_movie_id = $(view)[2];
|
|
let movie_id = $(data_movie_id).data('movie-id');
|
|
|
|
let movie_stream = document.querySelector('#movie_stream');
|
|
movie_stream.innerHTML = '';
|
|
let videoControles = document.querySelector('#video_controls');
|
|
videoControles.innerHTML = '';
|
|
videoControles.innerHTML += view;
|
|
|
|
let width = window.innerWidth;
|
|
let height = window.innerHeight;
|
|
|
|
document.querySelector('#divVideo').style.backgroundImage = 'url("/cover/movie?movie_id=' + movie_id + '&width=' + width + '&height=' + height + '&art=true")';
|
|
document.querySelector('#divVideo').style.backgroundColor = '#000000';
|
|
|
|
initSliders();
|
|
|
|
$('#divVideo').show();
|
|
|
|
player = new Clappr.Player({
|
|
source: movie_src,
|
|
parentId: '#movie_stream',
|
|
width: '100%',
|
|
height: '100%',
|
|
playback: {
|
|
preload: 'metadata',
|
|
controls: false,
|
|
recycleVideo: Clappr.Browser.isMobile
|
|
},
|
|
events: {
|
|
onReady: function () {
|
|
$(document).find('#movie_stream .player-poster').remove();
|
|
// PREVENT PLAY IF THE PLAYER IS NOT VISIBLE
|
|
setTimeout(function (event) {
|
|
$('button[role="playCenter"]').click();
|
|
}, 10);
|
|
left = parseInt($(sliderTrack.domNode).css('left').replace('px',''));
|
|
},
|
|
onPause: function () {
|
|
$('button[data-qa-id="resumeButton"] i').toggleClass('plex-icon-player-pause-560 plex-icon-player-play-560');
|
|
$('button[role="playCenter"]').show();
|
|
},
|
|
onTimeUpdate: function(progress) {
|
|
let timeplay = progress.current;
|
|
let percent = timeplay / totaltime;
|
|
|
|
$('.media-time').html(toHHMMSS(timeplay));
|
|
|
|
$('.SeekBar-seekBarFill-1Lcu0').css('transform', 'scaleX('+ percent +')');
|
|
$(sliderTrack.railDomNode).css('transform', 'translateX(-' + parseFloat(100 - percent*100) + '%)');
|
|
|
|
percent = parseInt(percent * 100);
|
|
|
|
if(movie_type === 'episode' && percent > 97) {
|
|
showNext();
|
|
} else {
|
|
removeNext();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
player.on(Clappr.Events.PLAYER_PLAY, function(){player.core.mediaControl.disable()});
|
|
|
|
/** EVENT PLAYER WHEN LOADED GET TOTATL TIME **/
|
|
player.core.activeContainer.on(Clappr.Events.CONTAINER_LOADEDMETADATA, function(metadata) {
|
|
totaltime = metadata.duration;
|
|
});
|
|
|
|
/** EVENT PLAYER TO GET CURRENT TIME **/
|
|
/** BUFFER BAR PROGRESS **/
|
|
player.core.activeContainer.on(Clappr.Events.CONTAINER_PROGRESS, function(progress) {
|
|
var buffer = progress.current / progress.total;
|
|
$('.SeekBar-seekBarBuffer-3bUz9').css('transform', 'scaleX('+ buffer +')');
|
|
});
|
|
|
|
/** PLAY CENTER **/
|
|
$(document).on('click', 'button[role="playCenter"]', function () {
|
|
$(document).find('button[role="playCenter"]').hide();
|
|
$(document).find('button[data-qa-id="resumeButton"] i').toggleClass('plex-icon-player-pause-560 plex-icon-player-play-560');
|
|
player.play();
|
|
});
|
|
/** RESUME **/
|
|
$(document).on('click', 'button[data-qa-id="resumeButton"]', function () {
|
|
if(!player.isPlaying())
|
|
$(document).find('button[role="playCenter"]').click();
|
|
else
|
|
player.pause();
|
|
});
|
|
/** CLOSE **/
|
|
$(document).on('click', '.AudioVideoPlayerControls-closeButton-2ULmA', function () {
|
|
$('#divVideo').hide();
|
|
player.destroy();
|
|
videoControles.innerHTML = '';
|
|
clearTimeout(timeout);
|
|
clearTimeout(buffered);
|
|
});
|
|
/** FULLSCREEN **/
|
|
$(document).on('click', '.FullPlayerTopControls-topButton-2iGrJ[data-qa-id="fullscreenButton"]', function () {
|
|
if(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement)
|
|
exitFullScreen();
|
|
else
|
|
fullScreen();
|
|
});
|
|
/** QUEUELIST **/
|
|
$(document).on('click', '.PlayerIconButton-playerButton-1DmNp[data-qa-id="playQueueButton"]', function () {
|
|
$('.AudioVideoFullPlayer-content-37T7O').toggleClass('hidden');
|
|
});
|
|
|
|
/** SETTINGS AUDIO VIDEO AND SUBTITLES **/
|
|
$(document).on('click', '.AudioVideoPlayerControls-buttonGroupRight-17650 .AudioVideoPlayerControls-auxButtons-2YhIh > button', function (event) {
|
|
var video_audio_control = $('.AudioVideoPlaybackSettings-container-2pTAj.AudioVideoStripeContainer-container-MI02O');
|
|
|
|
if(video_audio_control.css('transform') === 'matrix(1, 0, 0, 1, 0, 246)')
|
|
video_audio_control.css('transform', 'translateY(0px)');
|
|
else
|
|
video_audio_control.css('transform', 'translateY(246px)');
|
|
});
|
|
|
|
/** HOVER PLAYER, BUTTON CENTER AND NAVBAR SHOW NAVBAR **/
|
|
$(document).on('mouseover', '#divVideo, #movie_stream , button[role="playCenter"], .AudioVideoFullPlayer-topBar-2XUGM, .AudioVideoFullPlayer-bottomBar-2yixi, .AudioVideoPlaybackSettings-container-2pTAj.AudioVideoStripeContainer-container-MI02O', function (event) {
|
|
clearTimeout(timeout);
|
|
$('.AudioVideoFullPlayer-topBar-2XUGM').css('transform', 'translateY(60px)');
|
|
$('.AudioVideoFullPlayer-bottomBar-2yixi').css('transform', 'translateY(-86px)');
|
|
});
|
|
/** BUTTON CENTER AND NAVBAR HIDE NAVBAR **/
|
|
$(document).on('mouseleave', '#divVideo, #movie_stream, #video_controls', function (event) {
|
|
$('.AudioVideoFullPlayer-topBar-2XUGM').css('transform', '');
|
|
$('.AudioVideoFullPlayer-bottomBar-2yixi').css('transform', '');
|
|
$('.AudioVideoPlaybackSettings-container-2pTAj.AudioVideoStripeContainer-container-MI02O').css('transform', 'translateY(246px)');
|
|
});
|
|
/** MOUSE MOVE ON PLAYER KEEP VISIBLE NAVBAR **/
|
|
$(document).on('mousemove', '#divVideo, #movie_stream, button[role="playCenter"]', function () {
|
|
$('button[role="playCenter"], #movie_stream, video').css('cursor', 'pointer');
|
|
$('button[role="playCenter"], .AudioVideoFullPlayer-topBar-2XUGM, .AudioVideoFullPlayer-bottomBar-2yixi').mouseover();
|
|
lastTimeMouseMoved = new Date().getTime();
|
|
timeout = setInterval(function() {
|
|
var currentTime = new Date().getTime();
|
|
if ((currentTime - lastTimeMouseMoved) > 1000) {
|
|
$('button[role="playCenter"], #movie_stream, video').css('cursor', 'none');
|
|
$('#movie_stream, #video_controls').mouseleave();
|
|
clearTimeout(timeout);
|
|
}
|
|
}, 1000);
|
|
});
|
|
|
|
/** NEXT EPISODE **/
|
|
$(document).on('click', '#next', function () {
|
|
var movie_id = $(this).data('id');
|
|
if (movie_id === '')
|
|
return;
|
|
|
|
event.stopPropagation();
|
|
|
|
$.ajax({
|
|
url: '/rest/movie/stream',
|
|
method: 'GET',
|
|
data: {movie_id: movie_id},
|
|
dataType: 'html'
|
|
}).done(function (view) {
|
|
launchPlayer(view);
|
|
}).fail(function (data) {
|
|
console.error(data.responseText);
|
|
show_alert('error', data.responseText);
|
|
});
|
|
})
|
|
}
|
|
|
|
function showNext() {
|
|
$('#movie_stream').css({
|
|
'position': 'relative',
|
|
'height': '240px',
|
|
'width': '380px',
|
|
'top': '100px',
|
|
'left': '200px'
|
|
});
|
|
$('.Next').removeClass('hidden');
|
|
}
|
|
|
|
function removeNext() {
|
|
$('#movie_stream').css({
|
|
'position': 'relative',
|
|
'height': '100%',
|
|
'width': '100%',
|
|
'top': 0,
|
|
'left': 0
|
|
});
|
|
$('.Next').addClass('hidden');
|
|
}
|
|
|
|
// Enter full screen
|
|
function fullScreen()
|
|
{
|
|
// check if user allows full screen of elements. This can be enabled or disabled in browser config. By default its enabled.
|
|
//its also used to check if browser supports full screen api.
|
|
if("fullscreenEnabled" in document || "webkitFullscreenEnabled" in document || "mozFullScreenEnabled" in document || "msFullscreenEnabled" in document)
|
|
{
|
|
if(document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled)
|
|
{
|
|
$('button[data-qa-id="fullscreenButton"] i').get(0).setAttribute('class', 'plex-icon-player-windowed-560');
|
|
var element = document.getElementById('divVideo');
|
|
//requestFullscreen is used to display an element in full screen mode.
|
|
if("requestFullscreen" in element)
|
|
{
|
|
element.requestFullscreen();
|
|
}
|
|
else if ("webkitRequestFullscreen" in element)
|
|
{
|
|
element.webkitRequestFullscreen();
|
|
}
|
|
else if ("mozRequestFullScreen" in element)
|
|
{
|
|
element.mozRequestFullScreen();
|
|
}
|
|
else if ("msRequestFullscreen" in element)
|
|
{
|
|
element.msRequestFullscreen();
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
console.log("User doesn't allow full screen");
|
|
}
|
|
}
|
|
// Exit full screen
|
|
function exitFullScreen() {
|
|
$('button[data-qa-id="fullscreenButton"] i').get(0).setAttribute('class', 'plex-icon-player-fullscreen-560');
|
|
if ("exitFullscreen" in document)
|
|
{
|
|
document.exitFullscreen();
|
|
}
|
|
else if ("webkitExitFullscreen" in document)
|
|
{
|
|
document.webkitExitFullscreen();
|
|
}
|
|
else if ("mozCancelFullScreen" in document)
|
|
{
|
|
document.mozCancelFullScreen();
|
|
}
|
|
else if ("msExitFullscreen" in document)
|
|
{
|
|
document.msExitFullscreen();
|
|
}
|
|
}
|
|
|
|
// Initialise Sliders on the page
|
|
function initSliders () {
|
|
|
|
sliderTrack = new Slider($('.Slider-thumbTrack-21hGV .Slider-thumb-2QGiU').get(0));
|
|
sliderTrack.clickElementBefore = $('.SeekBar-seekBarTrack-3Gu5R').get(0);
|
|
sliderTrack.init();
|
|
|
|
sliderSound = new Slider($('.VolumeSlider-slider-1QXdT .Slider-thumb-2QGiU').get(0));
|
|
sliderSound.clickElementBefore = $('.VolumeSlider-fill-3XkYy').get(0);
|
|
sliderSound.clickElementAfter = $('.VolumeSlider-track-2WJDz').get(0);
|
|
sliderSound.init();
|
|
|
|
};
|
|
|
|
var Slider = function (domNode) {
|
|
|
|
this.domNode = domNode;
|
|
this.railDomNode = domNode.parentNode;
|
|
|
|
this.clickElementBefore = domNode.parentNode;
|
|
this.clickElementAfter = domNode.parentNode;
|
|
|
|
this.valueMin = 0;
|
|
this.valueMax = 100;
|
|
this.valueNow = 50;
|
|
|
|
this.railWidth = 0;
|
|
|
|
this.keyCode = Object.freeze({
|
|
'left': 37,
|
|
'up': 38,
|
|
'right': 39,
|
|
'down': 40,
|
|
'pageUp': 33,
|
|
'pageDown': 34,
|
|
'end': 35,
|
|
'home': 36
|
|
});
|
|
};
|
|
|
|
// Initialize slider
|
|
Slider.prototype.init = function () {
|
|
|
|
if (this.domNode.getAttribute('aria-valuemin')) {
|
|
this.valueMin = parseInt((this.domNode.getAttribute('aria-valuemin')));
|
|
}
|
|
if (this.domNode.getAttribute('aria-valuemax')) {
|
|
this.valueMax = parseInt((this.domNode.getAttribute('aria-valuemax')));
|
|
}
|
|
if (this.domNode.getAttribute('aria-valuenow')) {
|
|
this.valueNow = parseInt((this.domNode.getAttribute('aria-valuenow')));
|
|
}
|
|
|
|
this.railWidth = parseInt(this.railDomNode.offsetWidth || !window.getComputedStyle(this.railDomNode.parentElement).width.match(/%/) ? window.getComputedStyle(this.railDomNode.parentElement).width : null || document.body.clientWidth);
|
|
//this.railWidth = parseInt(this.railDomNode.offsetWidth || document.body.clientWidth);
|
|
|
|
|
|
if (this.domNode.tabIndex != 0) {
|
|
this.domNode.tabIndex = 0;
|
|
}
|
|
|
|
document.addEventListener('keydown', this.handleKeyDown.bind(this));
|
|
// add onmousedown, move, and onmouseup
|
|
this.domNode.addEventListener('mousedown', this.handleMouseDown.bind(this));
|
|
|
|
this.clickElementBefore.addEventListener('click', this.handleClick.bind(this));
|
|
this.clickElementAfter.addEventListener('click', this.handleClick.bind(this));
|
|
|
|
this.moveSliderTo(this.valueNow);
|
|
};
|
|
|
|
Slider.prototype.moveSliderTo = function (value) {
|
|
|
|
if (value > this.valueMax) {
|
|
value = this.valueMax;
|
|
}
|
|
|
|
if (value < this.valueMin) {
|
|
value = this.valueMin;
|
|
}
|
|
|
|
this.valueNow = value;
|
|
|
|
this.domNode.setAttribute('aria-valuenow', this.valueNow);
|
|
|
|
var percent = (this.valueNow * 100) / this.valueMax;
|
|
|
|
this.railDomNode.style.transform = 'translateX(-' + (100 - percent) + '%)';
|
|
|
|
if(this.domNode.id === 'buttonTrack') {
|
|
document.getElementsByClassName('SeekBar-seekBarFill-1Lcu0')[0].style.transform = 'scaleX(' + percent / 100 + ')';
|
|
if(player) {
|
|
player.seekPercentage(percent);
|
|
}
|
|
}
|
|
else if(this.domNode.id === 'buttonVolume') {
|
|
document.getElementsByClassName('VolumeSlider-fill-3XkYy')[0].style.transform = 'scaleX(' + percent / 100 + ')';
|
|
if(player) {
|
|
player.setVolume(percent);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
Slider.prototype.handleKeyDown = function (event) {
|
|
|
|
var flag = false;
|
|
|
|
switch (event.keyCode) {
|
|
case this.keyCode.left:
|
|
this.moveSliderTo(this.valueNow - 1);
|
|
flag = true;
|
|
break;
|
|
|
|
case this.keyCode.down:
|
|
this.moveSliderTo(this.valueNow - 1);
|
|
flag = true;
|
|
break;
|
|
|
|
case this.keyCode.right:
|
|
this.moveSliderTo(this.valueNow + 1);
|
|
flag = true;
|
|
break;
|
|
|
|
case this.keyCode.up:
|
|
this.moveSliderTo(this.valueNow + 1);
|
|
flag = true;
|
|
break;
|
|
|
|
case this.keyCode.pageDown:
|
|
this.moveSliderTo(this.valueNow - 10);
|
|
flag = true;
|
|
break;
|
|
|
|
case this.keyCode.pageUp:
|
|
this.moveSliderTo(this.valueNow + 10);
|
|
flag = true;
|
|
break;
|
|
|
|
case this.keyCode.home:
|
|
this.moveSliderTo(this.valueMin);
|
|
flag = true;
|
|
break;
|
|
|
|
case this.keyCode.end:
|
|
this.moveSliderTo(this.valueMax);
|
|
flag = true;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (flag) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
}
|
|
|
|
};
|
|
|
|
Slider.prototype.handleMouseDown = function (event) {
|
|
|
|
var self = this;
|
|
|
|
var handleMouseMove = function (event) {
|
|
|
|
var diffX = event.pageX - (self.railDomNode.offsetLeft ? self.railDomNode.offsetLeft : self.railDomNode.parentElement.offsetLeft);
|
|
self.valueNow = parseInt(((self.valueMax - self.valueMin) * diffX) / self.railWidth);
|
|
self.moveSliderTo(self.valueNow);
|
|
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
};
|
|
|
|
var handleMouseUp = function (event) {
|
|
|
|
document.removeEventListener('mousemove', handleMouseMove);
|
|
document.removeEventListener('mouseup', handleMouseUp);
|
|
|
|
};
|
|
|
|
// bind a mousemove event handler to move pointer
|
|
document.addEventListener('mousemove', handleMouseMove);
|
|
|
|
// bind a mouseup event handler to stop tracking mouse movements
|
|
document.addEventListener('mouseup', handleMouseUp);
|
|
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
};
|
|
|
|
// handleMouseMove has the same functionality as we need for handleMouseClick on the rail
|
|
Slider.prototype.handleClick = function (event) {
|
|
|
|
var diffX = event.pageX - this.railDomNode.offsetLeft;
|
|
this.valueNow = parseInt(((this.valueMax - this.valueMin) * diffX) / this.railWidth);
|
|
this.moveSliderTo(this.valueNow);
|
|
|
|
};
|