const cp = require("child_process"); const os = require("os"); let ffmpeg; if (os.platform() === "win32") { ffmpeg = `"${__dirname}\\..\\ffmpeg.exe"`; } else { ffmpeg = `"${__dirname}/../ffmpeg"`; } const fs = require("fs"); const path = require("path"); const { shell, ipcRenderer, clipboard } = require("electron"); const { default: YTDlpWrap } = require("yt-dlp-wrap-extended"); // Directories const homedir = os.homedir(); const appdir = path.join(homedir, "Downloads"); const hiddenDir = path.join(homedir, ".ytDownloader"); const i18n = new (require("../translations/i18n"))(); fs.mkdir(hiddenDir, { recursive: true }, () => {}); // Download directory let downloadDir = ""; // Global variables let title, onlyvideo, id, thumbnail, ytdlp, duration, extractFormat; let rangeCmd = ""; let subs = ""; let subLangs; // let autoSubs = "" let rangeOption = "--download-sections"; let cookieArg = ""; let browser = ""; // Video and audio preferences let preferredVideoQuality = ""; let preferredAudioQuality = ""; if (localStorage.getItem("preferredVideoQuality")) { preferredVideoQuality = localStorage.getItem("preferredVideoQuality"); } if (localStorage.getItem("preferredAudioQuality")) { preferredAudioQuality = localStorage.getItem("preferredAudioQuality"); getId("extractSelection").value = preferredAudioQuality; } function getId(id) { return document.getElementById(id); } function downloadPathSelection() { let localPath = localStorage.getItem("downloadPath"); if (localPath) { downloadDir = localPath; } else { downloadDir = appdir; localStorage.setItem("downloadPath", appdir); } fs.mkdir(downloadDir, { recursive: true }, () => {}); } downloadPathSelection(); // Checking for yt-dlp let ytDlp; let ytdlpPath = path.join(os.homedir(), ".ytDownloader", "ytdlp"); // ytdlp download path let ytdlpDownloadPath; if (os.platform() == "win32") { ytdlpDownloadPath = path.join(os.homedir(), ".ytDownloader", "ytdlp.exe"); } else { ytdlpDownloadPath = path.join(os.homedir(), ".ytDownloader", "ytdlp"); } // Downloading yt-dlp async function downloadYtdlp() { document.querySelector("#popupBox p").textContent = i18n.__( "Please wait, necessary files are being downloaded" ); getId("popupSvg").style.display = "inline"; // Downloading appropriate version of yt-dlp if (os.platform() == "linux") { // Checking python version try { const result = cp.execSync("python3 --version", { encoding: "utf-8", }); const minorVersion = Number(result.split(" ")[1].split(".")[1]); if (minorVersion >= 7) { await YTDlpWrap.downloadFromGithub(ytdlpDownloadPath); } else { // Downloading full binary if python version is less than 3.7 await YTDlpWrap.downloadFromGithub( ytdlpDownloadPath, "", "linux", true ); } } catch (error) { // Downloading full binary of python3 is not there await YTDlpWrap.downloadFromGithub( ytdlpDownloadPath, "", "linux", true ); } } else { // In case of windows/mac await YTDlpWrap.downloadFromGithub(ytdlpDownloadPath); } getId("popupBox").style.display = "none"; ytDlp = ytdlpPath; ytdlp = new YTDlpWrap(ytDlp); localStorage.setItem("ytdlp", ytDlp); getId("pasteUrl").style.display = "inline-block"; console.log("yt-dlp bin Path: " + ytDlp); } // Checking if yt-dlp has been installed by user cp.exec("yt-dlp --version", (error, stdout, stderr) => { if (error) { // Checking if yt-dlp has been installed by program cp.exec(`${ytdlpPath} --version`, (error, stdout, stderr) => { if (error) { getId("popupBox").style.display = "block"; process.on("uncaughtException", (reason, promise) => { document.querySelector("#popupBox p").textContent = i18n.__( "Failed to download necessary files. Please check your network and try again" ); getId("popupSvg").style.display = "none"; getId("popup").innerHTML += ``; console.log("Failed to download yt-dlp"); getId("tryBtn").addEventListener("click", () => { getId("popup").removeChild(getId("popup").lastChild); downloadYtdlp(); }); }); downloadYtdlp(); } else { console.log("yt-dlp binary is present in PATH"); ytDlp = ytdlpPath; ytdlp = new YTDlpWrap(ytDlp); localStorage.setItem("ytdlp", ytDlp); cp.spawn(`${ytDlp}`, ["-U"]).stdout.on("data", (data) => console.log(data.toString("utf8")) ); getId("pasteUrl").style.display = "inline-block"; console.log("yt-dlp bin Path: " + ytDlp); } }); } else { console.log("yt-dlp binary is present in PATH"); ytDlp = "yt-dlp"; ytdlp = new YTDlpWrap(ytDlp); localStorage.setItem("ytdlp", ytDlp); getId("pasteUrl").style.display = "inline-block"; console.log("yt-dlp bin Path: " + ytDlp); } }); function defaultVideoToggle() { videoToggle.style.backgroundColor = "var(--box-toggleOn)"; audioToggle.style.backgroundColor = "var(--box-toggle)"; getId("audioList").style.display = "none"; getId("videoList").style.display = "block"; } // Pasting url from clipboard function pasteUrl() { defaultVideoToggle(); getId("hidden").style.display = "none"; getId("loadingWrapper").style.display = "flex"; getId("incorrectMsg").textContent = ""; const url = clipboard.readText(); getInfo(url); } getId("closeHidden").addEventListener("click", () => { getId("hidden").style.display = "none"; getId("loadingWrapper").style.display = "none"; }); document.addEventListener("keydown", (event) => { if (event.ctrlKey && event.key == "v") { pasteUrl(); } }); getId("pasteUrl").addEventListener("click", () => { pasteUrl(); }); // Getting video info async function getInfo(url) { let selected = false; onlyvideo = false; let audioIsPresent = false; downloadPathSelection(); getId("videoFormatSelect").innerHTML = ""; getId("audioFormatSelect").innerHTML = ""; getId("startTime").value = ""; getId("endTime").value = ""; // Whether to use browser cookies or not if (localStorage.getItem("browser")) { browser = localStorage.getItem("browser"); } if (browser) { cookieArg = "--cookies-from-browser"; } else { cookieArg = ""; } let validInfo = true; let info = ""; const infoProcess = cp.spawn( ytDlp, ["-j", "--no-playlist", "--no-warnings", cookieArg, browser, `"${url}"`], { shell: true, } ); infoProcess.stdout.on("data", (data) => { info += data; }); infoProcess.stderr.on("data", (error) => { validInfo = false; console.log(error.toString("utf8")); getId("loadingWrapper").style.display = "none"; getId("incorrectMsg").textContent = i18n.__( "Some error has occured. Check your network and use correct URL" ); }); infoProcess.on("close", () => { if (validInfo) { info = JSON.parse(info); console.log(info); title = info.title; id = info.id; thumbnail = info.thumbnail; duration = info.duration; const formats = info.formats; console.log(formats); const urlElements = document.querySelectorAll(".url"); urlElements.forEach((element) => { element.value = url; }); getId("loadingWrapper").style.display = "none"; getId("hidden").style.display = "inline-block"; getId("title").innerHTML = `${i18n.__("Title ")}: ` + title; getId("videoList").style.display = "block"; videoToggle.style.backgroundColor = "rgb(67, 212, 164)"; let audioSize = 0; let defaultVideoFormat = 0; // Getting approx size of audio file and checking if audio is present for (let format of formats) { // Find the item with the preferred video format if ( format.height <= preferredVideoQuality && format.height > defaultVideoFormat && format.video_ext !== "none" ) { defaultVideoFormat = format.height; } if ( format.audio_ext !== "none" || (format.acodec !== "none" && format.video_ext === "none") ) { audioIsPresent = true; onlyvideo = true; audioSize = Number(format.filesize || format.filesize_approx) / 1000000; } } for (let format of formats) { let size; let selectedText = ""; if (format.height == defaultVideoFormat && !selected) { selectedText = " selected "; selected = true; } if (format.filesize || format.filesize_approx) { size = ( Number(format.filesize || format.filesize_approx) / 1000000 ).toFixed(2); } else { size = i18n.__("Unknown size"); } // For videos if ( format.video_ext !== "none" && format.audio_ext === "none" ) { if (size !== "Unknown size") { size = (Number(size) + 0 || Number(audioSize)).toFixed( 2 ); size = size + " " + i18n.__("MB"); } const format_id = format.format_id + "|" + format.ext + "|" + (format.height || "NO"); const element = ""; getId("videoFormatSelect").innerHTML += element; } // For audios else if ( format.audio_ext !== "none" || (format.acodec !== "none" && format.video_ext === "none") ) { size = size + " MB"; let audio_ext; if (format.audio_ext === "webm") { audio_ext = "opus"; } else { audio_ext = format.audio_ext; } const format_id = format.format_id + "|" + audio_ext; const element = ""; getId("audioFormatSelect").innerHTML += element; } // Both audio and video available else if ( format.audio_ext !== "none" || (format.acodec !== "none" && format.video_ext !== "none") ) { let size; if (format.filesize || format.filesize_approx) { size = ( Number(format.filesize || format.filesize_approx) / 1000000 ).toFixed(2); } else { size = i18n.__("Unknown size"); } const element = ""; getId("videoFormatSelect").innerHTML += element; } // When there is no audio if (audioIsPresent === false) { getId("audioPresent").style.display = "none"; } else { getId("audioPresent").style.display = "block"; } } } }); } // Video download event getId("videoDownload").addEventListener("click", (event) => { getId("hidden").style.display = "none"; download("video"); }); // Audio download event getId("audioDownload").addEventListener("click", (event) => { getId("hidden").style.display = "none"; download("audio"); }); getId("extractBtn").addEventListener("click", () => { const value = getId("extractSelection").value; extractFormat = value; preferredAudioQuality = value; localStorage.setItem("preferredAudioQuality", value); getId("hidden").style.display = "none"; download("extract"); }); // Restore previous uncompleted downloads // function restorePrevious() { // if (!localStorage.getItem("itemList")) return; // const items = JSON.parse(localStorage.getItem("itemList")); // if (items) { // console.log(items); // items.forEach((item) => { // const newItem = ` //