Merging playlist branch

Adding playlist download support
pull/40/head
Andrew 3 years ago committed by GitHub
commit 47bcfd763e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -26,7 +26,7 @@ input[type="text"]{
border-radius: 8px;
border:none;
color:rgb(255, 255, 255);
background-color: rgb(56, 209, 56);
background-color: rgb(49, 215, 49);
cursor: pointer;
}
#save:active{

@ -113,7 +113,19 @@ body {
padding: 20px 10px;
align-items: center;
justify-content: space-between;
box-shadow: var(--box-shadow);
}
.playlistItem{
display: flex;
position: relative;
width: 86%;
background-color: var(--item-bg);
color: var(--text);
padding:10px 25px;
border-radius: 25px;
align-items: center;
justify-content: space-between;
margin: 10px auto;
}
@media screen and (max-width: 650px) {
@ -183,7 +195,16 @@ body {
width: 80%;
padding: 10px 10px 20px 10px;
color: var(--text);
box-shadow: var(--box-shadow);
}
#options{
display:none;
position:relative;
top:20px;
background-color: var(--box-main);
border-radius: 10px;
padding: 10px;
color: var(--text);
}
#btnContainer {

@ -10,6 +10,7 @@
<link rel="stylesheet" href="../assets/css/index.css">
<script src="../src/renderer.js" defer></script>
<script src="../src/index.js" defer></script>
<script src="../src/common.js" defer></script>
<!-- Translating -->
<script>window.i18n = new (require('../translations/i18n'));</script>
@ -47,6 +48,7 @@
<!-- Menu -->
<div id="menu">
<a id="playlistWin" class="menuItem">Download Playlist</a>
<a id="preferenceWin" class="menuItem">Preferences</a>
<a id="aboutWin" class="menuItem">About</a>
</div>

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Playlist download</title>
<link rel="stylesheet" href="../assets/css/index.css">
<script src="../src/playlist.js" defer></script>
<script src="../src/common.js" defer></script>
<!-- Translating -->
<script>window.i18n = new (require('../translations/i18n'));</script>
<style>
#playlistName {
padding: 30px;
}
</style>
</head>
<body>
<!-- Theme toggle -->
<div id="themeToggle" onclick="toggle()">
<div id="themeToggleInside"></div>
</div>
<!-- Menu icon -->
<img src="../assets/images/menu.png" alt="menu" id="menuIcon">
<!-- Menu -->
<div id="menu">
<a id="homeWin" class="menuItem">Homepage</a>
<a id="preferenceWin" class="menuItem">Preferences</a>
<a id="aboutWin" class="menuItem">About</a>
</div>
<button class="submitBtn" id="pasteLink">Click to paste playlist link from clipboard [Ctrl + V]</button>
<div id="options">
<br>
<strong>Link:</strong><span id="link"></span>
<br><br>
<label>Select Format</label>
<select id="select">
<option value="144">144p</option>
<option value="240">240p</option>
<option value="360">360p</option>
<option value="480">480p</option>
<option value="720">720p (HD)</option>
<option value="1080">1080p (FHD)</option>
<option value="1440">1440p</option>
<option value="2160">2160p (4k)</option>
</select>
<button class="submitBtn" id="download">Download</button>
<p id="incorrectMsg"></p>
</div>
<h2 id="playlistName"></h2>
<div id="list">
</div>
</body>
</html>

@ -56,6 +56,9 @@ ipcMain.on("get-version", () => {
secondaryWindow.webContents.send("version", version);
});
ipcMain.on("load-win", (event, file)=>{
win.loadFile(file)
})
ipcMain.on("load-page", (event, file) => {
secondaryWindow = new BrowserWindow({
webPreferences: {

@ -5,7 +5,7 @@
"yt-dlp-wrap-extended": "^2.3.12"
},
"name": "ytdownloader",
"version": "3.4.1",
"version": "3.5.0",
"main": "main.js",
"scripts": {
"start": "electron .",

@ -0,0 +1,100 @@
function getId(id) {
return document.getElementById(id);
}
let menuIsOpen = false;
getId("menuIcon").addEventListener("click", (event) => {
if (menuIsOpen) {
getId("menuIcon").style.transform = "rotate(0deg)";
menuIsOpen = false;
let count = 0;
let opacity = 1;
const fade = setInterval(() => {
if (count >= 10) {
getId("menu").style.display = "none"
clearInterval(fade);
} else {
opacity -= 0.1;
getId("menu").style.opacity = opacity;
count++;
}
}, 50);
} else {
getId("menuIcon").style.transform = "rotate(90deg)";
menuIsOpen = true;
setTimeout(() => {
getId("menu").style.display = "flex";
getId("menu").style.opacity = 1;
}, 150);
}
});
// Toggle theme
let circle = getId("themeToggleInside");
let darkTheme = true;
circle.style.left = "25px";
const root = document.querySelector(":root");
let enabledTransparent = localStorage.getItem("enabledTransparent");
let bgColor = "";
if (enabledTransparent == "true") {
bgColor = "rgba(40,40,40, .9)";
} else {
bgColor = "rgb(40,40,40)";
}
function toggle() {
if (darkTheme == false) {
// Switching to dark theme
circle.style.left = "25px";
root.style.setProperty("--background", bgColor);
root.style.setProperty("--text", "white");
root.style.setProperty("--box-main", "rgb(80,80,80)");
root.style.setProperty("--box-toggle", "rgb(70,70,70)");
root.style.setProperty("--theme-toggle", "rgb(80, 193, 238)");
root.style.setProperty("--item-bg", "rgb(75, 75, 75)");
darkTheme = true;
localStorage.setItem("theme", "dark");
} else {
// Switching to light theme
circle.style.left = "0px";
root.style.setProperty("--background", "whitesmoke");
root.style.setProperty("--text", "rgb(45, 45, 45)");
root.style.setProperty("--box-main", "rgb(174 249 224)");
root.style.setProperty("--box-toggle", "rgb(108, 231, 190)");
root.style.setProperty("--theme-toggle", "rgb(147, 174, 185)");
root.style.setProperty("--item-bg", "#dddddd");
darkTheme = false;
localStorage.setItem("theme", "light");
}
}
const storageTheme = localStorage.getItem("theme");
if (storageTheme == "dark") {
darkTheme = false;
toggle();
} else if (storageTheme == "light") {
darkTheme = true;
toggle();
}
////
let advancedHidden = true;
function advancedToggle() {
if (advancedHidden) {
getId("advanced").style.display = "block";
advancedHidden = false;
} else {
getId("advanced").style.display = "none";
advancedHidden = true;
}
}

@ -7,35 +7,6 @@ function getId(id) {
return document.getElementById(id);
}
let menuIsOpen = false;
getId("menuIcon").addEventListener("click", (event) => {
if (menuIsOpen) {
getId("menuIcon").style.transform = "rotate(0deg)";
menuIsOpen = false;
let count = 0;
let opacity = 1;
const fade = setInterval(() => {
if (count >= 10) {
getId("menu").style.display = "none"
clearInterval(fade);
} else {
opacity -= 0.1;
getId("menu").style.opacity = opacity;
count++;
}
}, 50);
} else {
getId("menuIcon").style.transform = "rotate(90deg)";
menuIsOpen = true;
setTimeout(() => {
getId("menu").style.display = "flex";
getId("menu").style.opacity = 1;
}, 150);
}
});
// Video and audio toggle
videoToggle.addEventListener("click", (event) => {
@ -53,74 +24,3 @@ audioToggle.addEventListener("click", (event) => {
});
/////////////
// Toggle theme
let circle = getId("themeToggleInside");
let darkTheme = true;
circle.style.left = "25px";
const root = document.querySelector(":root");
let enabledTransparent = localStorage.getItem("enabledTransparent");
let bgColor = "";
if (enabledTransparent == "true") {
bgColor = "rgba(40,40,40, .9)";
} else {
bgColor = "rgb(40,40,40)";
}
function toggle() {
if (darkTheme == false) {
circle.style.left = "25px";
root.style.setProperty("--background", bgColor);
root.style.setProperty("--text", "white");
root.style.setProperty("--box-main", "rgb(80,80,80)");
root.style.setProperty("--box-toggle", "rgb(70,70,70)");
root.style.setProperty("--theme-toggle", "rgb(80, 193, 238)");
root.style.setProperty("--item-bg", "rgb(75, 75, 75)");
root.style.setProperty("--box-shadow", "none");
darkTheme = true;
localStorage.setItem("theme", "dark");
} else {
circle.style.left = "0px";
root.style.setProperty("--background", "whitesmoke");
root.style.setProperty("--text", "rgb(45, 45, 45)");
root.style.setProperty("--box-main", "rgb(174 249 224)");
root.style.setProperty("--box-toggle", "rgb(108, 231, 190)");
root.style.setProperty("--theme-toggle", "rgb(147, 174, 185)");
root.style.setProperty("--item-bg", "#ececec");
root.style.setProperty("--box-shadow", "3px 3px 10px gray");
root.style.setProperty(
"--box-shadow",
"2px 2px 5px rgb(92, 92, 92), -2px -2px 5px rgb(219, 219, 219)"
);
darkTheme = false;
localStorage.setItem("theme", "light");
}
}
const storageTheme = localStorage.getItem("theme");
if (storageTheme == "dark") {
darkTheme = false;
toggle();
} else if (storageTheme == "light") {
darkTheme = true;
toggle();
}
////
let advancedHidden = true;
function advancedToggle() {
if (advancedHidden) {
getId("advanced").style.display = "block";
advancedHidden = false;
} else {
getId("advanced").style.display = "none";
advancedHidden = true;
}
}

@ -0,0 +1,145 @@
const { clipboard, shell, ipcRenderer } = require("electron");
const { default: YTDlpWrap } = require("yt-dlp-wrap-extended");
const path = require("path");
let url;
const ytDlp = localStorage.getItem("ytdlp");
const ytdlp = new YTDlpWrap(ytDlp);
const downloadDir = localStorage.getItem("downloadPath");
const i18n = new (require("../translations/i18n"))();
function getId(id) {
return document.getElementById(id);
}
function pasteLink() {
url = clipboard.readText();
getId("link").textContent = " " + url;
getId("options").style.display = "block";
getId("incorrectMsg").textContent = "";
}
getId("pasteLink").addEventListener("click", () => {
pasteLink();
});
document.addEventListener("keydown", (event) => {
if (event.ctrlKey && event.key == "v") {
pasteLink();
}
});
// Patterns
const playlistTxt = "Downloading playlist: ";
const videoIndex = "Downloading video ";
// Downloading playlist: Inkscape Tutorials
// Downloading video 1 of 82
getId("download").addEventListener("click", () => {
let count = 0;
let playlistName;
getId("options").style.display = "none";
getId("pasteLink").style.display = "none";
getId("playlistName").textContent = i18n.__("Processing") + "..."
const quality = getId("select").value;
const format = `"mp4[height<=${quality}]+m4a/mp4[height<=${quality}]/bv[height<=${quality}]+ba/best[height<=${quality}]/best"`;
const controller = new AbortController();
const downloadProcess = ytdlp.exec(
[
"-f",
format,
"--yes-playlist",
"-o",
`"${path.join(
downloadDir,
"%(playlist_title)s",
"%(title)s_%(playlist_index)s.%(ext)s"
)}"`,
`"${url}"`,
],
{ shell: true, detached: false },
controller.signal
);
downloadProcess.on("ytDlpEvent", (eventType, eventData) => {
console.log(eventData);
if (eventData.includes(playlistTxt)) {
playlistName = eventData.split(":")[1].slice(1)
getId("playlistName").textContent = i18n.__("Downloading playlist:") + " "+ playlistName;
console.log(playlistName);
}
if (eventData.includes(videoIndex)) {
count += 1;
const itemTitle = i18n.__("Video") + " " + eventData.split(" ")[3];
if (count > 1) {
getId(`p${count - 1}`).textContent = i18n.__("File saved. Click to Open")
}
const item = `<div class="playlistItem">
<p class="itemTitle">${itemTitle}</p>
<p class="itemProgress" onclick="openFolder('${path.join(downloadDir, playlistName)}')" id="p${count}">${i18n.__("Downloading...")}</p>
</div>`;
getId("list").innerHTML += item;
}
});
downloadProcess.on("progress", (progress) => {
if (getId(`p${count}`)) {
getId(`p${count}`).textContent = `${i18n.__("Progress")} ${progress.percent}% | ${i18n.__("Speed")} ${progress.currentSpeed}`
}
});
downloadProcess.on("error", (error) => {
getId("pasteLink").style.display = "inline-block"
getId("options").style.display = "block";
getId("playlistName").textContent = ""
getId("incorrectMsg").textContent = error;
});
downloadProcess.on("close", ()=>{
getId("pasteLink").style.display = "inline-block";
})
});
function openFolder(location){
shell.openPath(location)
}
function closeMenu() {
getId("menuIcon").style.transform = "rotate(0deg)";
menuIsOpen = false;
let count = 0;
let opacity = 1;
const fade = setInterval(() => {
if (count >= 10) {
clearInterval(fade);
} else {
opacity -= 0.1;
getId("menu").style.opacity = opacity;
count++;
}
}, 50);
}
getId("preferenceWin").addEventListener("click", () => {
closeMenu();
ipcRenderer.send("load-page", __dirname + "/preferences.html");
});
getId("aboutWin").addEventListener("click", () => {
closeMenu();
ipcRenderer.send("load-page", __dirname + "/about.html");
});
getId("homeWin").addEventListener("click", ()=>{
closeMenu();
ipcRenderer.send("load-win", __dirname + "/index.html");
})

@ -105,6 +105,7 @@ async function downloadYtdlp() {
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);
}
@ -137,6 +138,7 @@ cp.exec("yt-dlp --version", (error, stdout, stderr) => {
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"))
);
@ -148,6 +150,7 @@ cp.exec("yt-dlp --version", (error, stdout, stderr) => {
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);
}
@ -569,7 +572,7 @@ function download(type) {
audioFormat = "ba";
}
let controller = new AbortController();
const controller = new AbortController();
console.log(rangeOption + " " + rangeCmd);
if (type === "video" && onlyvideo) {
@ -790,3 +793,8 @@ getId("aboutWin").addEventListener("click", () => {
closeMenu();
ipcRenderer.send("load-page", __dirname + "/about.html");
});
getId("playlistWin").addEventListener("click", ()=>{
closeMenu();
ipcRenderer.send("load-win", __dirname + "/playlist.html");
})
Loading…
Cancel
Save