mirror of https://github.com/FreeTubeApp/FreeTube
[Feature] Playlist Support mostly finished
This commit is contained in:
parent
a2cf6851b8
commit
c18046406e
138
src/js/player.js
138
src/js/player.js
|
@ -28,7 +28,7 @@
|
||||||
*
|
*
|
||||||
* @return {Void}
|
* @return {Void}
|
||||||
*/
|
*/
|
||||||
function playVideo(videoId) {
|
function playVideo(videoId, playlistId = '') {
|
||||||
hideViews();
|
hideViews();
|
||||||
|
|
||||||
playerView.playerSeen = true;
|
playerView.playerSeen = true;
|
||||||
|
@ -120,7 +120,7 @@ function playVideo(videoId) {
|
||||||
if (typeof (playerView.video720p) === 'undefined' && typeof (playerView.video480p) === 'undefined') {
|
if (typeof (playerView.video720p) === 'undefined' && typeof (playerView.video480p) === 'undefined') {
|
||||||
//useEmbedPlayer = true;
|
//useEmbedPlayer = true;
|
||||||
playerView.currentQuality = 'EMBED';
|
playerView.currentQuality = 'EMBED';
|
||||||
//playerView.playerSeen = false;
|
playerView.playerSeen = false;
|
||||||
//useEmbedPlayer = true;
|
//useEmbedPlayer = true;
|
||||||
showToast('Unable to get video file. Reverting to embeded player.');
|
showToast('Unable to get video file. Reverting to embeded player.');
|
||||||
}
|
}
|
||||||
|
@ -196,6 +196,49 @@ function playVideo(videoId) {
|
||||||
playerView.recommendedVideoList = playerView.recommendedVideoList.concat(data);
|
playerView.recommendedVideoList = playerView.recommendedVideoList.concat(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (playlistId != '') {
|
||||||
|
playerView.playlistSeen = true;
|
||||||
|
playerView.playlistShowList = true;
|
||||||
|
playerView.playlistId = playlistId;
|
||||||
|
playerView.playlistVideoList = [];
|
||||||
|
|
||||||
|
invidiousAPI('playlists', playlistId, {}, (data) => {
|
||||||
|
playerView.playlistTitle = data.title;
|
||||||
|
playerView.playlistChannelName = data.author;
|
||||||
|
playerView.playlistChannelId = data.authorId;
|
||||||
|
playerView.playlistTotal = data.videoCount;
|
||||||
|
|
||||||
|
let amountOfPages = Math.ceil(data.videoCount / 100);
|
||||||
|
|
||||||
|
console.log(amountOfPages);
|
||||||
|
|
||||||
|
for (let i = 1; i <= amountOfPages; i++) {
|
||||||
|
invidiousAPI('playlists', playlistId, {page: i}, (data) => {
|
||||||
|
data.videos.forEach((video) => {
|
||||||
|
let data = {};
|
||||||
|
|
||||||
|
if (video.videoId == videoId){
|
||||||
|
playerView.playlistIndex = video.index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.title = video.title;
|
||||||
|
data.videoId = video.videoId;
|
||||||
|
data.channelName = video.author;
|
||||||
|
data.index = video.index + 1;
|
||||||
|
data.thumbnail = video.videoThumbnails[4].url;
|
||||||
|
|
||||||
|
playerView.playlistVideoList[video.index] = data;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
playerView.playlistSeen = false;
|
||||||
|
playerView.playlistShowList = false;
|
||||||
|
playerView.playlistId = '';
|
||||||
|
}
|
||||||
|
|
||||||
loadingView.seen = false;
|
loadingView.seen = false;
|
||||||
|
|
||||||
if (subscriptionView.seen === false && aboutView.seen === false && headerView.seen === false && searchView.seen === false && settingsView.seen === false && popularView.seen === false && savedView.seen === false && historyView.seen === false && channelView.seen === false && channelVideosView.seen === false) {
|
if (subscriptionView.seen === false && aboutView.seen === false && headerView.seen === false && searchView.seen === false && settingsView.seen === false && popularView.seen === false && savedView.seen === false && historyView.seen === false && channelView.seen === false && channelVideosView.seen === false) {
|
||||||
|
@ -272,16 +315,22 @@ function checkVideoSettings() {
|
||||||
|
|
||||||
switch (defaultQuality) {
|
switch (defaultQuality) {
|
||||||
case '480':
|
case '480':
|
||||||
playerView.videoUrl = playerView.video480p;
|
if (typeof(playerView.video480p) !== 'undefined') {
|
||||||
playerView.currentQuality = '480p';
|
playerView.videoUrl = playerView.video480p;
|
||||||
|
playerView.currentQuality = '480p';
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '720':
|
case '720':
|
||||||
playerView.videoUrl = playerView.video720p;
|
if (typeof(playerView.video720p) !== 'undefined') {
|
||||||
playerView.currentQuality = '720p';
|
playerView.videoUrl = playerView.video720p;
|
||||||
|
playerView.currentQuality = '720p';
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
playerView.videoUrl = playerView.video720p;
|
if (typeof(playerView.video720p) !== 'undefined') {
|
||||||
playerView.currentQuality = '720p';
|
playerView.videoUrl = playerView.video720p;
|
||||||
|
playerView.currentQuality = '720p';
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,63 +341,32 @@ function checkVideoSettings() {
|
||||||
player.volume = currentVolume;
|
player.volume = currentVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function playNextVideo() {
|
||||||
* Change the quality of the current video.
|
let player = document.getElementById('videoPlayer');
|
||||||
*
|
|
||||||
* @param {string} videoHtml - The HTML of the video player to be set.
|
|
||||||
* @param {string} qualityType - The Quality Type of the video. Ex: 720p, 480p
|
|
||||||
* @param {boolean} isEmbed - Optional: Value on if the videoHtml is the embeded player.
|
|
||||||
*
|
|
||||||
* @return {Void}
|
|
||||||
*/
|
|
||||||
function changeQuality(url, qualityText, isEmbed = false) {
|
|
||||||
if (videoHtml == '') {
|
|
||||||
showToast('Video quality type is not available. Unable to change quality.')
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
videoHtml = videoHtml.replace(/\"\;/g, '"');
|
if (player.loop !== false || playerView.playlistSeen === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ft.log('HTML Video: ', videoHtml);
|
if (playerView.playlistShuffle === true) {
|
||||||
ft.log('(Is the video embeded?) isEmbed: ', isEmbed);
|
let randomVideo = Math.floor(Math.random() * playerView.playlistTotal);
|
||||||
|
|
||||||
// The YouTube API creates 2 more iFrames. This is why a boolean value is sent
|
loadingView.seen = true;
|
||||||
// with the function.
|
playVideo(playerView.playlistVideoList[randomVideo].videoId, playerView.playlistId);
|
||||||
const embedPlayer = document.getElementsByTagName('IFRAME')[0];
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const html5Player = document.getElementsByClassName('videoPlayer');
|
if (playerView.playlistLoop === true && playerView.playlistIndex == playerView.playlistTotal) {
|
||||||
|
loadingView.seen = true;
|
||||||
|
playVideo(playerView.playlistVideoList[0].videoId, playerView.playlistId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ft.log('Embeded Player Element: ', embedPlayer);
|
if (playerView.playlistIndex != playerView.playlistTotal) {
|
||||||
ft.log('HTML5 Player Element: ', html5Player);
|
loadingView.seen = true;
|
||||||
|
playVideo(playerView.playlistVideoList[playerView.playlistIndex].videoId, playerView.playlistId);
|
||||||
if (isEmbed && html5Player.length == 0) {
|
return;
|
||||||
// The embeded player is already playing. Return.
|
}
|
||||||
showToast('You are already using the embeded player.')
|
|
||||||
return;
|
|
||||||
} else if (isEmbed) {
|
|
||||||
// Switch from HTML 5 player to embeded Player
|
|
||||||
html5Player[0].remove();
|
|
||||||
const mainHtml = $('#main').html();
|
|
||||||
$('#main').html(videoHtml + mainHtml);
|
|
||||||
$('#currentQuality').html(qualityType);
|
|
||||||
} else if (html5Player.length == 0) {
|
|
||||||
// Switch from embeded player to HTML 5 player
|
|
||||||
embedPlayer.remove();
|
|
||||||
let videoPlayer = document.createElement('video');
|
|
||||||
videoPlayer.className = 'videoPlayer';
|
|
||||||
videoPlayer.src = videoHtml;
|
|
||||||
videoPlayer.controls = true;
|
|
||||||
videoPlayer.autoplay = true;
|
|
||||||
$('#main').prepend(videoPlayer);
|
|
||||||
$('#currentQuality').html(qualityType);
|
|
||||||
} else {
|
|
||||||
// Switch src on HTML 5 player
|
|
||||||
const currentPlayBackTime = $('.videoPlayer').get(0).currentTime;
|
|
||||||
html5Player[0].src = videoHtml;
|
|
||||||
html5Player[0].load();
|
|
||||||
$('.videoPlayer').get(0).currentTime = currentPlayBackTime;
|
|
||||||
$('#currentQuality').html(qualityType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,9 +19,12 @@ function showPlaylist(playlistId) {
|
||||||
hideViews();
|
hideViews();
|
||||||
loadingView.seen = true;
|
loadingView.seen = true;
|
||||||
|
|
||||||
|
playlistView.videoList = [];
|
||||||
|
|
||||||
invidiousAPI('playlists', playlistId, {}, (data) => {
|
invidiousAPI('playlists', playlistId, {}, (data) => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
|
|
||||||
|
playlistView.playlistId = playlistId;
|
||||||
playlistView.channelName = data.author;
|
playlistView.channelName = data.author;
|
||||||
playlistView.channelId = data.authorId;
|
playlistView.channelId = data.authorId;
|
||||||
playlistView.channelThumbnail = data.authorThumbnails[3].url;
|
playlistView.channelThumbnail = data.authorThumbnails[3].url;
|
||||||
|
@ -34,43 +37,66 @@ function showPlaylist(playlistId) {
|
||||||
dateString.setDate(dateString.getDate() + 1);
|
dateString.setDate(dateString.getDate() + 1);
|
||||||
playlistView.lastUpdated = dateFormat(dateString, "mmm dS, yyyy");
|
playlistView.lastUpdated = dateFormat(dateString, "mmm dS, yyyy");
|
||||||
|
|
||||||
data.videos.forEach((video) => {
|
let amountOfPages = Math.ceil(data.videoCount / 100);
|
||||||
let videoData = {};
|
|
||||||
|
|
||||||
let time = video.lengthSeconds;
|
console.log(amountOfPages);
|
||||||
let hours = 0;
|
|
||||||
|
|
||||||
if (time >= 3600) {
|
for (let i = 1; i <= amountOfPages; i++) {
|
||||||
hours = Math.floor(time / 3600);
|
invidiousAPI('playlists', playlistId, {page: i}, (data) => {
|
||||||
time = time - hours * 3600;
|
console.log(data);
|
||||||
}
|
data.videos.forEach((video) => {
|
||||||
|
let videoData = {};
|
||||||
|
|
||||||
let minutes = Math.floor(time / 60);
|
let time = video.lengthSeconds;
|
||||||
let seconds = time - minutes * 60;
|
let hours = 0;
|
||||||
|
|
||||||
if (seconds < 10) {
|
if (time >= 3600) {
|
||||||
seconds = '0' + seconds;
|
hours = Math.floor(time / 3600);
|
||||||
}
|
time = time - hours * 3600;
|
||||||
|
}
|
||||||
|
|
||||||
if (minutes < 10 && hours > 0) {
|
let minutes = Math.floor(time / 60);
|
||||||
minutes = '0' + minutes;
|
let seconds = time - minutes * 60;
|
||||||
}
|
|
||||||
|
|
||||||
if (hours > 0) {
|
if (seconds < 10) {
|
||||||
videoData.duration = hours + ":" + minutes + ":" + seconds;
|
seconds = '0' + seconds;
|
||||||
} else {
|
}
|
||||||
videoData.duration = minutes + ":" + seconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
videoData.id = video.videoId;
|
if (minutes < 10 && hours > 0) {
|
||||||
videoData.title = video.title;
|
minutes = '0' + minutes;
|
||||||
videoData.channelName = video.author;
|
}
|
||||||
videoData.channelId = video.authorId;
|
|
||||||
videoData.thumbnail = video.videoThumbnails[4].url;
|
|
||||||
|
|
||||||
playlistView.videoList[video.index] = videoData;
|
if (hours > 0) {
|
||||||
});
|
videoData.duration = hours + ":" + minutes + ":" + seconds;
|
||||||
loadingView.seen = false;
|
} else {
|
||||||
playlistView.seen = true;
|
videoData.duration = minutes + ":" + seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
videoData.id = video.videoId;
|
||||||
|
videoData.title = video.title;
|
||||||
|
videoData.channelName = video.author;
|
||||||
|
videoData.channelId = video.authorId;
|
||||||
|
videoData.thumbnail = video.videoThumbnails[4].url;
|
||||||
|
|
||||||
|
playlistView.videoList[video.index] = videoData;
|
||||||
|
});
|
||||||
|
if (playlistView.seen !== false) {
|
||||||
|
playlistView.seen = false;
|
||||||
|
playlistView.seen = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
loadingView.seen = false;
|
||||||
|
playlistView.seen = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function togglePlaylist() {
|
||||||
|
if (playerView.playlistShowList !== false) {
|
||||||
|
playerView.playlistShowList = false;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
playerView.playlistShowList = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -288,6 +288,7 @@ let playlistView = new Vue({
|
||||||
el: '#playlistView',
|
el: '#playlistView',
|
||||||
data: {
|
data: {
|
||||||
seen: false,
|
seen: false,
|
||||||
|
playlistId: '',
|
||||||
channelName: '',
|
channelName: '',
|
||||||
channelId: '',
|
channelId: '',
|
||||||
thumbnail: '',
|
thumbnail: '',
|
||||||
|
@ -301,7 +302,7 @@ let playlistView = new Vue({
|
||||||
methods: {
|
methods: {
|
||||||
play: (videoId) => {
|
play: (videoId) => {
|
||||||
loadingView.seen = true;
|
loadingView.seen = true;
|
||||||
playVideo(videoId);
|
playVideo(videoId, playlistView.playlistId);
|
||||||
},
|
},
|
||||||
channel: (channelId) => {
|
channel: (channelId) => {
|
||||||
goToChannel(channelId);
|
goToChannel(channelId);
|
||||||
|
@ -433,6 +434,7 @@ let playerView = new Vue({
|
||||||
el: '#playerView',
|
el: '#playerView',
|
||||||
data: {
|
data: {
|
||||||
seen: false,
|
seen: false,
|
||||||
|
playlistSeen: false,
|
||||||
firstLoad: true,
|
firstLoad: true,
|
||||||
publishedDate: '',
|
publishedDate: '',
|
||||||
videoUrl: '',
|
videoUrl: '',
|
||||||
|
@ -461,6 +463,13 @@ let playerView = new Vue({
|
||||||
videoLikes: 0,
|
videoLikes: 0,
|
||||||
videoDislikes: 0,
|
videoDislikes: 0,
|
||||||
playerSeen: true,
|
playerSeen: true,
|
||||||
|
playlistTitle: '',
|
||||||
|
playlistChannelName: '',
|
||||||
|
playlistIndex: 1,
|
||||||
|
playlistTotal: 1,
|
||||||
|
playlistLoop: false,
|
||||||
|
playlistShuffle: false,
|
||||||
|
playlistShowList: true,
|
||||||
recommendedVideoList: [],
|
recommendedVideoList: [],
|
||||||
playlistVideoList: [],
|
playlistVideoList: [],
|
||||||
},
|
},
|
||||||
|
@ -500,9 +509,9 @@ let playerView = new Vue({
|
||||||
save: (videoId) => {
|
save: (videoId) => {
|
||||||
toggleSavedVideo(videoId);
|
toggleSavedVideo(videoId);
|
||||||
},
|
},
|
||||||
play: (videoId) => {
|
play: (videoId, playlistId = '') => {
|
||||||
loadingView.seen = true;
|
loadingView.seen = true;
|
||||||
playVideo(videoId);
|
playVideo(videoId, playlistId);
|
||||||
},
|
},
|
||||||
loop: () => {
|
loop: () => {
|
||||||
let player = document.getElementById('videoPlayer');
|
let player = document.getElementById('videoPlayer');
|
||||||
|
@ -519,6 +528,26 @@ let playerView = new Vue({
|
||||||
playlist: (playlistId) => {
|
playlist: (playlistId) => {
|
||||||
showPlaylist(playlistId);
|
showPlaylist(playlistId);
|
||||||
},
|
},
|
||||||
|
playlistLoopToggle: () => {
|
||||||
|
if (playerView.playlistLoop !== false) {
|
||||||
|
showToast('Playlist will no longer loop');
|
||||||
|
playerView.playlistLoop = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
showToast('Playlist will now loop');
|
||||||
|
playerView.playlistLoop = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
playlistShuffleToggle: () => {
|
||||||
|
if (playerView.playlistShuffle !== false) {
|
||||||
|
showToast('Playlist will no longer shuffle');
|
||||||
|
playerView.playlistShuffle = false;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
showToast('Playlist will now shuffle');
|
||||||
|
playerView.playlistShuffle = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
template: playerTemplate
|
template: playerTemplate
|
||||||
});
|
});
|
||||||
|
|
|
@ -459,7 +459,7 @@ function checkVideoUrls(video480p, video720p, videoAudio) {
|
||||||
default:
|
default:
|
||||||
ft.log('480p is valid');
|
ft.log('480p is valid');
|
||||||
if (currentQuality === '720p' && typeof (video720p) === 'undefined') {
|
if (currentQuality === '720p' && typeof (video720p) === 'undefined') {
|
||||||
changeQuality(video480p);
|
playerView.currentQuality = '480p';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -477,7 +477,7 @@ function checkVideoUrls(video480p, video720p, videoAudio) {
|
||||||
showToast('Found valid URL for 720p, but returned a 404. Video type might be available in the future.');
|
showToast('Found valid URL for 720p, but returned a 404. Video type might be available in the future.');
|
||||||
playerView.valid720p = false;
|
playerView.valid720p = false;
|
||||||
if (typeof (valid480) !== 'undefined') {
|
if (typeof (valid480) !== 'undefined') {
|
||||||
changeQuality(video480p, '480p');
|
playerView.currentQuality = '480p';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 403:
|
case 403:
|
||||||
|
|
|
@ -267,3 +267,7 @@ input[type=text] {
|
||||||
#comments {
|
#comments {
|
||||||
background-color: #424242;
|
background-color: #424242;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#miniPL {
|
||||||
|
background-color: #424242;
|
||||||
|
}
|
||||||
|
|
|
@ -211,3 +211,7 @@ body {
|
||||||
#comments {
|
#comments {
|
||||||
background: #eee;
|
background: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#miniPL {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ a {
|
||||||
height: 3px;
|
height: 3px;
|
||||||
background-color: #f44336;
|
background-color: #f44336;
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
|
@ -71,3 +71,78 @@
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#miniPL {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.miniPLVideo {
|
||||||
|
width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.miniPLThumbnail {
|
||||||
|
width: 120px;
|
||||||
|
height: 80px;
|
||||||
|
margin-right: 5px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.miniPLIndex {
|
||||||
|
float: left;
|
||||||
|
position: relative;
|
||||||
|
width: 15px;
|
||||||
|
top: 30px;
|
||||||
|
margin-right: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.miniPLVideoTitle {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.miniPLVideoChannelName {
|
||||||
|
font-size: 12px;
|
||||||
|
position: relative;
|
||||||
|
bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#miniPLTitle {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 20px;
|
||||||
|
margin-left: 20px;
|
||||||
|
padding-top: 25px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#miniPLChannelName {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
#miniPLVideoList {
|
||||||
|
padding: 10px;
|
||||||
|
overflow: scroll;
|
||||||
|
height: 375px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#miniPLLoop {
|
||||||
|
margin-left: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#miniPLShuffle {
|
||||||
|
margin-left: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#miniPLDropdown {
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 20px;
|
||||||
|
position: relative;
|
||||||
|
top: 20px;
|
||||||
|
right: 15px;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div v-if='seen'>
|
<div v-if='seen'>
|
||||||
<div v-if='playerSeen'>
|
<div v-if='playerSeen'>
|
||||||
<video class="videoPlayer" id='videoPlayer' type="application/x-mpegURL" object-fit='cover' onmousemove="hideMouseTimeout()" onmouseleave="removeMouseTimeout()" onloadstart='checkVideoSettings()' onvolumechange='updateVolume()' controls="" :src='videoUrl' :poster="videoThumbnail" v-html="subtitleHtml">
|
<video class="videoPlayer" id='videoPlayer' type="application/x-mpegURL" object-fit='cover' onmousemove="hideMouseTimeout()" onmouseleave="removeMouseTimeout()" onloadstart='checkVideoSettings()' onvolumechange='updateVolume()' controls="" onended='playNextVideo()' :src='videoUrl' :poster="videoThumbnail" v-html="subtitleHtml">
|
||||||
</video>
|
</video>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
|
@ -79,6 +79,23 @@
|
||||||
<span v-html="description"></span>
|
<span v-html="description"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if='playlistSeen' id='miniPL'>
|
||||||
|
<i id='miniPLDropdown' onclick='togglePlaylist()' class='fas fa-angle-down'></i>
|
||||||
|
<p id='miniPLTitle'><span v-on:click='playlist(playlistId)'>{{playlistTitle}}</span><br /><span id='miniPLChannelName' v-on:click='channel(playlistChannelId)'>{{playlistChannelName}} - {{playlistIndex}} / {{playlistTotal}}</span></p>
|
||||||
|
<i id='miniPLLoop' v-on:click='playlistLoopToggle' class='fas fa-redo'></i>
|
||||||
|
<i id='miniPLShuffle' v-on:click='playlistShuffleToggle' class='fas fa-random'></i>
|
||||||
|
<br /><br />
|
||||||
|
<div v-if='playlistShowList' id='miniPLVideoList'>
|
||||||
|
<div v-for='video in playlistVideoList'>
|
||||||
|
<div v-on:click='play(video.videoId, playlistId)' class='miniPLVideo'>
|
||||||
|
<span class='miniPLIndex'>{{video.index}}</span>
|
||||||
|
<img :src='video.thumbnail' class='miniPLThumbnail'></>
|
||||||
|
<p class='miniPLVideoTitle'>{{video.title}}</p>
|
||||||
|
<p class='miniPLVideoChannelName'>{{video.channelName}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id='showComments'>
|
<div id='showComments'>
|
||||||
Show Comments <i class="far fa-comments"></i> (Max of 100)
|
Show Comments <i class="far fa-comments"></i> (Max of 100)
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<p>{{videoCount}} videos - {{viewCount}} views - Last updated on {{lastUpdated}}</p>
|
<p>{{videoCount}} videos - {{viewCount}} views - Last updated on {{lastUpdated}}</p>
|
||||||
<p v-html='description'></p>
|
<p v-html='description'></p>
|
||||||
<br />
|
<br />
|
||||||
<div class='playlistChannel'>
|
<div v-on:click='channel(channelId)' class='playlistChannel'>
|
||||||
<img :src='channelThumbnail' />
|
<img :src='channelThumbnail' />
|
||||||
<h3>{{channelName}}</h3>
|
<h3>{{channelName}}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
<div class='video'>
|
<div class='video'>
|
||||||
<div class='videoThumbnail'>
|
<div class='videoThumbnail'>
|
||||||
<img v-on:click='playlist(video.id)' :src='video.thumbnail' />
|
<img v-on:click='playlist(video.id)' :src='video.thumbnail' />
|
||||||
<div class='videoPlaylist'>
|
<div class='videoPlaylist' v-on:click='playlist(video.id)'>
|
||||||
<span class='videoPlaylistTotals'>{{video.videoCount}}</span>
|
<span class='videoPlaylistTotals'>{{video.videoCount}}</span>
|
||||||
<i class='fas fa-list-ol videoPlaylistIcon'></i>
|
<i class='fas fa-list-ol videoPlaylistIcon'></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue