mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-11 10:31:47 +00:00
add download feedback and progress
This commit is contained in:
@ -1,41 +1,12 @@
|
||||
const { existsSync, mkdirSync } = require("fs");
|
||||
const { join } = require("path");
|
||||
|
||||
const { dialog, ipcMain } = require("electron");
|
||||
const is = require("electron-is");
|
||||
const ytpl = require("ytpl");
|
||||
const chokidar = require('chokidar');
|
||||
const filenamify = require('filenamify');
|
||||
const { dialog } = require("electron");
|
||||
|
||||
const { setMenuOptions } = require("../../config/plugins");
|
||||
const { sendError } = require("./back");
|
||||
const { downloadSong } = require("./back-downloader");
|
||||
const { defaultMenuDownloadLabel, getFolder, presets, setBadge } = require("./utils");
|
||||
const { downloadPlaylist } = require("./back-downloader");
|
||||
const { defaultMenuDownloadLabel, getFolder, presets } = require("./utils");
|
||||
|
||||
let downloadLabel = defaultMenuDownloadLabel;
|
||||
let playingUrl = undefined;
|
||||
let callbackIsRegistered = false;
|
||||
|
||||
// Playlist radio modifier needs to be cut from playlist ID
|
||||
const INVALID_PLAYLIST_MODIFIER = 'RDAMPL';
|
||||
|
||||
const getPlaylistID = aURL => {
|
||||
const result = aURL?.searchParams.get("list") || aURL?.searchParams.get("playlist");
|
||||
if (result?.startsWith(INVALID_PLAYLIST_MODIFIER)) {
|
||||
return result.slice(6)
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports = (win, options) => {
|
||||
if (!callbackIsRegistered) {
|
||||
ipcMain.on("video-src-changed", async (_, data) => {
|
||||
playingUrl = JSON.parse(data)?.microformat?.microformatDataRenderer?.urlCanonical;
|
||||
});
|
||||
ipcMain.on("download-playlist-request", async (_event, url) => downloadPlaylist(url, win, options));
|
||||
callbackIsRegistered = true;
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
label: downloadLabel,
|
||||
@ -68,95 +39,3 @@ module.exports = (win, options) => {
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
async function downloadPlaylist(givenUrl, win, options) {
|
||||
if (givenUrl) {
|
||||
try {
|
||||
givenUrl = new URL(givenUrl);
|
||||
} catch {
|
||||
givenUrl = undefined;
|
||||
};
|
||||
}
|
||||
const playlistId = getPlaylistID(givenUrl)
|
||||
|| getPlaylistID(new URL(win.webContents.getURL()))
|
||||
|| getPlaylistID(new URL(playingUrl));
|
||||
|
||||
if (!playlistId) {
|
||||
sendError(new Error("No playlist ID found"));
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`trying to get playlist ID: '${playlistId}'`);
|
||||
let playlist;
|
||||
try {
|
||||
playlist = await ytpl(playlistId, {
|
||||
limit: options.playlistMaxItems || Infinity,
|
||||
});
|
||||
} catch (e) {
|
||||
sendError(e);
|
||||
return;
|
||||
}
|
||||
let isAlbum = playlist.title.startsWith('Album - ');
|
||||
if (isAlbum) {
|
||||
playlist.title = playlist.title.slice(8);
|
||||
}
|
||||
const safePlaylistTitle = filenamify(playlist.title, { replacement: ' ' });
|
||||
|
||||
const folder = getFolder(options.downloadFolder);
|
||||
const playlistFolder = join(folder, safePlaylistTitle);
|
||||
if (existsSync(playlistFolder)) {
|
||||
sendError(new Error(`The folder ${playlistFolder} already exists`));
|
||||
return;
|
||||
}
|
||||
mkdirSync(playlistFolder, { recursive: true });
|
||||
|
||||
dialog.showMessageBox({
|
||||
type: "info",
|
||||
buttons: ["OK"],
|
||||
title: "Started Download",
|
||||
message: `Downloading Playlist "${playlist.title}"`,
|
||||
detail: `(${playlist.items.length} songs)`,
|
||||
});
|
||||
|
||||
if (is.dev()) {
|
||||
console.log(
|
||||
`Downloading playlist "${playlist.title}" - ${playlist.items.length} songs (${playlistId})`
|
||||
);
|
||||
}
|
||||
|
||||
win.setProgressBar(2); // starts with indefinite bar
|
||||
|
||||
let downloadCount = 0;
|
||||
setBadge(playlist.items.length);
|
||||
|
||||
let dirWatcher = chokidar.watch(playlistFolder);
|
||||
const closeDirWatcher = () => {
|
||||
if (dirWatcher) {
|
||||
win.setProgressBar(-1); // close progress bar
|
||||
setBadge(0); // close badge counter
|
||||
dirWatcher.close().then(() => (dirWatcher = null));
|
||||
}
|
||||
};
|
||||
dirWatcher.on('add', () => {
|
||||
downloadCount += 1;
|
||||
if (downloadCount >= playlist.items.length) {
|
||||
closeDirWatcher();
|
||||
} else {
|
||||
win.setProgressBar(downloadCount / playlist.items.length);
|
||||
setBadge(playlist.items.length - downloadCount);
|
||||
}
|
||||
});
|
||||
|
||||
let counter = 1;
|
||||
|
||||
try {
|
||||
for (const song of playlist.items) {
|
||||
const trackId = isAlbum ? counter++ : undefined;
|
||||
await downloadSong(song.url, playlistFolder, trackId).catch((e) => sendError(e));
|
||||
}
|
||||
} catch (e) {
|
||||
sendError(e);
|
||||
} finally {
|
||||
closeDirWatcher();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user