/*
This file is part of FreeTube.
FreeTube is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FreeTube is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeTube. If not, see .
*/
/*
* File for functions related to videos.
*/
/**
* Display the video player and play a video
*
* @param {string} videoId - The video ID of the video to be played.
*
* @return {Void}
*/
function playVideo(videoId) {
hideViews();
playerView.videoId = videoId;
playerView.video480p = undefined;
playerView.video720p = undefined;
playerView.embededHtml = "";
const checkSavedVideo = videoIsSaved(videoId);
// Change the save button icon and text depending on if the user has saved the video or not.
checkSavedVideo.then((results) => {
if (results === false) {
playerView.savedText = 'FAVORITE';
playerView.savedIconType = 'far unsaved';
} else {
playerView.savedText = 'FAVORITED';
playerView.savedIconType = 'fas saved';
}
});
youtubeAPI('videos', {
part: 'statistics',
id: videoId,
}, function (data) {
// Figure out the width for the like/dislike bar.
playerView.videoLikes = data['items'][0]['statistics']['likeCount'];
playerView.videoDislikes = data['items'][0]['statistics']['dislikeCount'];
let totalLikes = parseInt(playerView.videoLikes) + parseInt(playerView.videoDislikes);
playerView.likePercentage = parseInt((playerView.videoLikes / totalLikes) * 100);
});
/*
* FreeTube calls youtube-dl to grab the direct video URL.
*/
youtubedlGetInfo(videoId, (info) => {
playerView.videoTitle = info['title'];
playerView.channelName = info['author']['name'];
playerView.channelId = info['author']['id'];
playerView.channelIcon = info['author']['avatar'];
let videoUrls = info['formats'];
// Add commas to the video view count.
playerView.videoViews = info['view_count'].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
playerView.videoThumbnail = info['player_response']['videoDetails']['thumbnail']['thumbnails'][3]['url'];
// Format the date to a more readable format.
let dateString = new Date(info['published']);
dateString.setDate(dateString.getDate() + 1);
playerView.publishedDate = dateFormat(dateString, "mmm dS, yyyy");
let description = info['description'];
// Adds clickable links to the description.
playerView.description = autolinker.link(description);
// Search through the returned object to get the 480p and 720p video URLs (If available)
Object.keys(videoUrls).forEach((key) => {
switch (videoUrls[key]['itag']) {
case '18':
playerView.video480p = decodeURIComponent(videoUrls[key]['url']);
//console.log(video480p);
break;
case '22':
playerView.video720p = decodeURIComponent(videoUrls[key]['url']);
//console.log(video720p);
break;
}
});
let useEmbedPlayer = false;
// Default to the embeded player if the URLs cannot be found.
if (typeof(playerView.video720p) === 'undefined' && typeof(playerView.video480p) === 'undefined') {
//useEmbedPlayer = true;
playerView.currentQuality = 'EMBED';
playerView.playerSeen = false;
useEmbedPlayer = true;
showToast('Unable to get video file. Reverting to embeded player.');
} else if (typeof(video720p) === 'undefined' && typeof(video480p) !== 'undefined') {
// Default to the 480p video if the 720p URL cannot be found.
playerView.videoUrl = playerView.video480p;
playerView.currentQuality = '480p';
} else {
// Default to the 720p video.
playerView.videoUrl = playerView.video720p;
playerView.currentQuality = '720p';
}
if (!useEmbedPlayer) {
let videoHtml = '';
if (typeof(info.player_response.captions) === 'object') {
if (typeof(info.player_response.captions.playerCaptionsTracklistRenderer.captionTracks) === 'object') {
const videoSubtitles = info.player_response.captions.playerCaptionsTracklistRenderer.captionTracks;
videoSubtitles.forEach((subtitle) => {
let subtitleUrl = 'https://www.youtube.com/api/timedtext?lang=' + subtitle.languageCode + '&fmt=vtt&name=&v=' + videoId;
if (subtitle.kind == 'asr') {
//subtitleUrl = subtitle.baseUrl;
return;
}
videoHtml = videoHtml + '