fix: playlist related file format placeholders not working (#97)

This commit is contained in:
Jelle Glebbeek
2021-06-06 02:55:53 +02:00
parent 87c1bf405f
commit d49b6c4aa2
4 changed files with 89 additions and 8 deletions

View File

@@ -19,6 +19,7 @@ class QueryManager {
this.window = window;
this.environment = environment;
this.managedVideos = [];
this.playlistMetadata = [];
}
async manage(url) {
@@ -61,6 +62,7 @@ class QueryManager {
}
managePlaylist(initialQuery, url) {
this.playlistMetadata = this.playlistMetadata.concat(Utils.generatePlaylistMetadata(initialQuery));
let playlistVideo = new Video(url, "playlist", this.environment);
this.addVideo(playlistVideo);
const playlistQuery = new InfoQueryList(initialQuery, this.environment, new ProgressBar(this, playlistVideo));
@@ -145,6 +147,7 @@ class QueryManager {
downloadAllVideos(args) {
let videosToDownload = [];
let unifiedPlaylists = [];
let videoMetadata = [];
for(const videoObj of args.videos) {
let video = this.getVideo(videoObj.identifier);
if(video.videos == null) {
@@ -161,6 +164,10 @@ class QueryManager {
}
}
}
const videoMeta = Utils.getVideoInPlaylistMetadata(video.url, null, this.playlistMetadata);
if(videoMeta != null) {
videoMetadata.push(videoMeta);
}
video.audioQuality = (video.audioQuality != null) ? video.audioQuality : "best";
videosToDownload.push(video);
} else {
@@ -168,6 +175,10 @@ class QueryManager {
unifiedPlaylists.push(video);
this.getUnifiedVideos(video, video.videos, videoObj.type === "audio", videoObj.format, videoObj.downloadSubs);
for(const unifiedVideo of video.videos) {
const videoMeta = Utils.getVideoInPlaylistMetadata(unifiedVideo.url, video.url, this.playlistMetadata);
if(videoMeta != null) {
videoMetadata.push(videoMeta);
}
unifiedVideo.parentID = video.identifier;
unifiedVideo.parentSize = video.videos.length;
videosToDownload.push(unifiedVideo);
@@ -175,7 +186,7 @@ class QueryManager {
}
}
let progressBar = new ProgressBar(this, "queue");
let downloadList = new DownloadQueryList(videosToDownload, this.environment, this, progressBar);
let downloadList = new DownloadQueryList(videosToDownload, videoMetadata, this.environment, this, progressBar);
for(const unifiedPlaylist of unifiedPlaylists) { unifiedPlaylist.setQuery(downloadList) }
downloadList.start().then(() => {
for(const unifiedPlaylist of unifiedPlaylists) { unifiedPlaylist.downloaded = true }
@@ -217,10 +228,11 @@ class QueryManager {
downloadUnifiedPlaylist(args) {
const playlist = this.getVideo(args.identifier);
const videos = playlist.videos;
const metadata = videos.map(vid => Utils.getVideoInPlaylistMetadata(vid.url, playlist.url, this.playlistMetadata)).filter(entry => entry != null);
this.getUnifiedVideos(playlist, videos, args.type === "audio", args.format, playlist.downloadSubs);
playlist.audioQuality = (playlist.audioQuality != null) ? playlist.audioQuality : "best";
let progressBar = new ProgressBar(this, playlist);
playlist.setQuery(new DownloadQueryList(videos, this.environment, this, progressBar));
playlist.setQuery(new DownloadQueryList(videos, metadata, this.environment, this, progressBar));
playlist.query.start().then(() => {
//Backup done call, sometimes it does not trigger automatically from within the downloadQuery.
playlist.downloaded = true;

View File

@@ -146,5 +146,70 @@ class Utils {
}
return formats;
}
static generatePlaylistMetadata(query) {
const indexes = [];
if(query.entries == null || query.entries.length === 0) {
console.error("Cannot extract URLS, no entries in data.")
return indexes;
}
for(const entry of query.entries) {
let url;
if (entry.url == null) url = entry.webpage_url;
else url = (entry.ie_key != null && entry.ie_key === "Youtube") ? "https://youtube.com/watch?v=" + entry.url : entry.url;
if(url != null && url.length > 0) {
let playlist = "?";
if(query.title != null) {
playlist = query.title;
} else if(query.id != null) {
playlist = query.id;
}
indexes.push({
video_url: url,
playlist_url: query.webpage_url,
playlist_index: query.entries.indexOf(entry),
playlist_id: query.id,
playlist_title: query.title,
playlist: playlist,
playlist_uploader: query.uploader,
playlist_uploader_id: query.uploader_id
})
}
}
return indexes;
}
static getVideoInPlaylistMetadata(video_url, playlist_url, metadata) {
if(metadata == null) return null;
for(const video of metadata) {
if(video.video_url === video_url) {
if(playlist_url == null) {
return video;
} else if(playlist_url === video.playlist_url) {
return video;
}
}
}
return null;
}
static resolvePlaylistPlaceholders(format, metadata) {
if(metadata == null) {
console.error("No metadata was given for this playlist video.");
return format;
}
let formatParsed = format;
const regex = new RegExp(/%\((\w+)\)(s?)/g);
let z;
while((z=regex.exec(formatParsed)) != null) {
if(z[1] != null) {
if(metadata[z[1]] != null) {
formatParsed = formatParsed.replace(z[0], metadata[z[1]]);
}
}
}
return formatParsed;
}
}
module.exports = Utils;

View File

@@ -1,14 +1,15 @@
const Query = require("../types/Query")
const path = require("path")
const Utils = require("../Utils")
class DownloadQuery extends Query {
constructor(url, video, environment, progressBar, unifiedPlaylist) {
constructor(url, video, environment, progressBar, playlistMeta) {
super(environment, video.identifier);
this.playlistMeta = playlistMeta;
this.url = url;
this.video = video;
this.progressBar = progressBar;
this.format = video.formats[video.selected_format_index];
this.unifiedPlaylist = unifiedPlaylist;
}
cancel() {
@@ -17,7 +18,9 @@ class DownloadQuery extends Query {
async connect() {
let args = [];
let output = path.join(this.environment.paths.downloadPath, this.environment.settings.nameFormat);
console.log("DOWNLOADQUERY")
console.log(this.playlistMeta)
let output = path.join(this.environment.paths.downloadPath, Utils.resolvePlaylistPlaceholders(this.environment.settings.nameFormat, this.playlistMeta));
if(this.video.audioOnly) {
let numeralAudioQuality = (this.video.audioQuality === "best") ? "0" : "9";
args = [
@@ -85,7 +88,6 @@ class DownloadQuery extends Query {
let result = null;
try {
result = await this.environment.downloadLimiter.schedule(() => this.start(this.url, args, (liveData) => {
if(this.unifiedPlaylist) return;
if (!liveData.includes("[download]")) return;
if (!initialReset) {
initialReset = true;

View File

@@ -1,9 +1,11 @@
const DownloadQuery = require('./DownloadQuery');
const ProgressBar = require("../types/ProgressBar");
const Utils = require("../Utils");
class DownloadQueryList {
constructor(videos, environment, manager, progressBar) {
constructor(videos, playlistMetadata, environment, manager, progressBar) {
this.videos = videos;
this.playlistMetadata = playlistMetadata;
this.environment = environment;
this.progressBar = progressBar;
this.manager = manager;
@@ -25,7 +27,7 @@ class DownloadQueryList {
return await new Promise(((resolve) => {
for(let video of this.videos) {
let progressBar = new ProgressBar(this.manager, video);
let task = new DownloadQuery(video.webpage_url, video, this.environment, progressBar);
let task = new DownloadQuery(video.webpage_url, video, this.environment, progressBar, Utils.getVideoInPlaylistMetadata(video.url, null, this.playlistMetadata));
if(video.parentID != null && !this.parentProgress.some(e => e.id === video.parentID)) {
const bar = new ProgressBar(this.manager, video.parentID);
this.parentProgress.push({