Fixing the bugs

pull/9/head
aandrew-me 3 years ago
parent 9c479fca00
commit 8cced332ff

@ -57,7 +57,8 @@ body {
.item {
display: flex;
width: 80%;
position: relative;
width: 86%;
height: 100px;
background-color: rgb(100, 100, 100);
margin: 10px auto;
@ -67,9 +68,9 @@ body {
justify-content: space-between;
}
@media screen and (max-width:650px) {
.item{
width:90%;
@media screen and (max-width: 650px) {
.item {
width: 90%;
}
}
@ -77,19 +78,35 @@ body {
max-width: 160px;
max-height: 90px;
border-radius: 10px;
padding:5px;
margin: 0 10px 0 0;
}
.itemTitle{
.itemTitle {
font-family: sans-serif;
}
.itemBody{
height:90%;
width:100%;
display:flex;
.itemBody {
height: 90%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.itemProgress{
font-weight:bold;
cursor: pointer;
}
.itemClose{
position: absolute;
top:5px;
right:5px;
cursor: pointer;
cursor: pointer;
width:15px;
height:15px;
}
@keyframes clickAnimation {
0% {
@ -106,15 +123,20 @@ body {
#hidden {
display: none;
/* display: inline-block; */
position: absolute;
z-index: 1;
left: 0;
right: 0;
margin: auto;
top:20%;
background-color: var(--box-main);
border-radius: 10px;
width: 80%;
padding: 10px 10px 20px 10px;
color: var(--text);
}
#videoProgressBox,
#audioProgressBox {
display: none;
.hiddenVideoProgress, .hiddenAudioProgress{
display:none;
}
#btnContainer {
@ -164,6 +186,7 @@ label {
font-size: large;
cursor: pointer;
display: inline-block;
outline:none;
animation-duration: 0.5s;
animation-timing-function: linear;
@ -174,6 +197,7 @@ label {
}
#loadingWrapper {
/* Default is flex */
display: none;
flex-direction: row;
justify-content: center;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -28,22 +28,67 @@
</div>
<button id="pasteUrl" class="submitBtn">Click to paste video URL or Id</button>
<button id="pasteUrl" class="submitBtn">Click to paste video URL or ID (Ctrl + V)</button>
<div id="loadingWrapper">
<span>Processing </span>
<svg version="1.1" id="L4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve">
<circle fill="rgb(84, 171, 222)" stroke="none" cx="6" cy="50" r="6">
<animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.1" />
</circle>
<circle fill="rgb(84, 171, 222)" stroke="none" cx="26" cy="50" r="6">
<animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.2" />
</circle>
<circle fill="rgb(84, 171, 222)" stroke="none" cx="46" cy="50" r="6">
<animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.3" />
</circle>
</svg>
</div>
<p id="incorrectMsg"></p>
<div id="hidden">
<div id="btnContainer">
<button class="toggleBtn" id="videoToggle">Video</button>
<button class="toggleBtn" id="audioToggle">Audio</button>
</div>
<p id="title">Title: </p>
<div id="videoList">
<label>Select Format - </label>
<select id="videoFormatSelect">
</select>
<br>
<input type="hidden" name="url" class="url" id="url">
<button class="submitBtn" id="videoDownload">Download</button>
</div>
<div id="audioList">
<label>Select Format - </label>
<select id="audioFormatSelect">
</select>
<br>
<input type="hidden" name="url" class="url">
<button class="submitBtn" id="audioDownload">Download</button>
</div>
</div>
<br><br><br><br>
<!-- Downloads list -->
<!-- Downloads list -->
<div id="list">
<div class="item">
<!-- <div class="item">
<img src="https://img.youtube.com/vi/pXkctRYYGjo/mqdefault.jpg" alt="thumbnail" class="itemIcon">
<div class="itemBody">
<div class="itemTitle">Qt5 C++ GUI Development Full Course For Beginners | C++ GUI</div>
<div class="itemProgress">20% downloaded</div>
</div>
</div>
</div> -->
</div>

@ -3,12 +3,14 @@ const ytdl = require("ytdl-core");
const cp = require("child_process");
const os = require("os");
const ffmpeg = require("ffmpeg-static");
const path = require("path")
const path = require("path");
const { shell, ipcRenderer, clipboard } = require("electron");
const { get } = require("http");
const { exit } = require("process");
// Directories
const homedir = os.homedir();
const appdir = path.join(homedir,".ytDownloader");
const appdir = path.join(homedir, ".ytDownloader");
const tempDir = path.join(appdir, "temp");
fs.mkdirSync(path.join(homedir, ".ytDownloader/temp"), { recursive: true });
let config;
@ -20,60 +22,75 @@ function getId(id) {
return document.getElementById(id);
}
let localPath = localStorage.getItem("downloadPath")
let localPath = localStorage.getItem("downloadPath");
if (localPath){
downloadDir = localPath
}
else{
downloadDir = appdir
localStorage.setItem("downloadPath", appdir)
if (localPath) {
downloadDir = localPath;
} else {
downloadDir = appdir;
localStorage.setItem("downloadPath", appdir);
}
// Clearing tempDir
fs.readdirSync(tempDir).forEach((f) => fs.rmSync(`${tempDir}/${f}`));
fs.readdirSync(tempDir).forEach((f) => fs.rmdir(`${tempDir}/${f}`, () => {}));
// Collecting info from youtube
async function getVideoInfo(url) {
let info;
await ytdl.getInfo(url)
.then((data)=>{
info = data
})
.catch((error)=>{
})
await ytdl
.getInfo(url)
.then((data) => {
info = data;
})
.catch((error) => {});
return info;
}
// Pasting url from clipboard
let url;
getId("pasteUrl").addEventListener("click", ()=>{
url = clipboard.readText()
console.log(url);
})
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);
}
document.addEventListener("keydown", (event) => {
if (event.ctrlKey && event.key == "v") {
pasteUrl();
}
});
getId("pasteUrl").addEventListener("click", () => {
pasteUrl();
});
// Getting video info
async function getInfo() {
incorrectMsg.textContent = "";
loadingMsg.style.display = "flex";
async function getInfo(url) {
getId("videoFormatSelect").innerHTML = "";
getId("audioFormatSelect").innerHTML = "";
const url = getId("url").value;
let info = await getVideoInfo(url)
let info = await getVideoInfo(url);
if (info) {
let title = info.videoDetails.title;
let formats = info.formats;
const title = info.videoDetails.title;
const formats = info.formats;
console.log(formats);
const urlElements = document.querySelectorAll(".url");
urlElements.forEach((element) => {
element.value = url;
});
loadingMsg.style.display = "none";
getId("hidden").style.display = "inline-block";
getId("title").innerHTML = "<b>Title</b>: " + title;
getId("videoList").style.display = "block";
@ -160,34 +177,39 @@ async function getInfo() {
}
}
} else {
loadingMsg.style.display = "none";
incorrectMsg.textContent =
getId("loadingWrapper").style.display = "none";
getId("incorrectMsg").textContent =
"Some error has occured. Check your connection and use correct URL";
}
}
// Video download event
getId("videoDownload").addEventListener("click", (event) => {
getId("preparingBox").style.display = "flex";
getId("hidden").style.display = "none";
clickAnimation("videoDownload");
download("video");
});
// Audio download event
getId("audioDownload").addEventListener("click", (event) => {
getId("preparingBox").style.display = "flex";
getId("hidden").style.display = "none";
clickAnimation("audioDownload");
download("audio");
});
// Downloading with ytdl
function download(type) {
getId("videoProgressBox").style.display = "none";
getId("audioProgressBox").style.display = "none";
getId("savedMsg").innerHTML = "";
const url = getId("url").value;
const newFolderName = Math.random().toFixed(10).toString().slice(2);
const newFolderPath = path.join(tempDir, newFolderName);
fs.mkdir(newFolderPath, (err) => {
if (err) {
console.log("Temp directory couldn't be created");
}
});
let itag;
if (type === "video") {
@ -198,6 +220,38 @@ function download(type) {
// Finding info of the link and downloading
findInfo(url, itag).then((info) => {
const id = info.id;
const newItem = `
<div class="item" id="${newFolderName}">
<img src="../assets/images/close.png" onClick="fadeItem('${newFolderName}')" class="itemClose"}" id="${
newFolderName + ".close"
}">
<img src="https://img.youtube.com/vi/${id}/mqdefault.jpg" alt="thumbnail" class="itemIcon">
<div class="itemBody">
<div class="itemTitle">${info.title}</div>
<div class="itemType">${info.filetype}</div>
<input disabled type="range" value="0" class="hiddenVideoProgress" id="${
newFolderName + "vid"
}"></input>
<input disabled type="range" value="0" class="hiddenAudioProgress" id="${
newFolderName + "aud"
}"></input>
<div id="${newFolderName + "prog"}" class="itemProgress"></div>
</div>
</div>
`;
getId("list").innerHTML += newItem;
getId("loadingWrapper").style.display = "none";
let cancelled = false;
getId(newFolderName + ".close").addEventListener("click", () => {
if (getId(newFolderName)) {
fadeItem(newFolderName);
}
cancelled = true;
});
const format = info.format;
const extension = info.extension;
let filename = "";
@ -231,6 +285,7 @@ function download(type) {
// If video
if (format.hasVideo) {
getId(newFolderName + "prog").textContent = "Starting...";
// Temporary audio and video files
let videoName =
Math.random().toString("16").slice(2) + "." + extension;
@ -239,60 +294,107 @@ function download(type) {
const arr = [
new Promise((resolve, reject) => {
if (cancelled) {
reject("cancelled");
}
// Downloading only video
ytdl(url, { quality: itag })
.on("progress", (_, downloaded, size) => {
videoProgress = (downloaded / size) * 100;
const videoDownload = ytdl(url, { quality: itag });
if (videoProgress != 100) {
getId("videoProgressBox").style.display =
"block";
getId("preparingBox").style.display = "none";
getId("videoProgress").value = videoProgress;
}
if (videoProgress == 100) {
resolve("video downloaded");
videoDownload
.on("progress", (_, downloaded, size) => {
if (cancelled) {
console.log("Cancelled video");
videoDownload.destroy();
reject();
} else {
videoProgress = (downloaded / size) * 100;
getId(newFolderName + "vid").value =
videoProgress;
if (videoProgress != 100) {
getId(newFolderName + "prog").textContent =
"Downloading";
getId(newFolderName + "vid").style.display =
"block";
getId(newFolderName + "aud").style.display =
"block";
}
if (videoProgress == 100) {
resolve("video downloaded");
}
}
})
.pipe(fs.createWriteStream(path.join(tempDir, videoName)));
.pipe(
fs.createWriteStream(
path.join(newFolderPath, videoName)
)
);
}),
new Promise((resolve, reject) => {
if (cancelled) {
reject("cancelled");
}
// Downloading only audio
ytdl(url, {
const audioDownload = ytdl(url, {
highWaterMark: 1 << 25,
quality: audioTag,
})
.on("progress", (_, downloaded, size) => {
audioProgress = (downloaded / size) * 100;
});
if (audioProgress != 100) {
getId("preparingBox").style.display = "none";
getId("audioProgress").value = audioProgress;
} else if (audioProgress == 100) {
resolve("audio downloaded");
audioDownload
.on("progress", (_, downloaded, size) => {
if (cancelled) {
console.log("Cancelled audio");
audioDownload.destroy();
reject();
} else {
audioProgress = (downloaded / size) * 100;
getId(newFolderName + "aud").value =
audioProgress || 0;
if (audioProgress != 100) {
} else if (audioProgress == 100) {
resolve("audio downloaded");
}
}
})
.pipe(fs.createWriteStream(path.join(tempDir, audioName)));
.pipe(
fs.createWriteStream(
path.join(newFolderPath, audioName)
)
);
}),
];
Promise.all([arr[0], arr[1]])
.then((response) => {
getId(newFolderName + "aud").style.display = "none";
getId(newFolderName + "vid").style.display = "none";
cp.exec(
`"${ffmpeg}" -i "${path.join(tempDir, videoName)}" -i "${
path.join(tempDir, audioName)
}" -c copy "${path.join(downloadDir, filename)}"`,
`"${ffmpeg}" -i "${path.join(
newFolderPath,
videoName
)}" -i "${path.join(
newFolderPath,
audioName
)}" -c copy "${path.join(downloadDir, filename)}"`,
(error, stdout, stderr) => {
if (error) {
console.log(error);
} else if (stderr) {
console.log("video saved");
// Clear temp dir
fs.readdirSync(tempDir).forEach((f) =>
fs.rmSync(`${tempDir}/${f}`)
fs.readdirSync(newFolderPath).forEach((f) =>
fs.rm(`${newFolderPath}/${f}`, () => {})
);
getId(newFolderName + "prog").textContent =
"Saved successfully";
afterSave(
downloadDir,
filename,
newFolderName + "prog"
);
afterSave(downloadDir, filename);
}
}
);
@ -304,41 +406,70 @@ function download(type) {
// If audio
else {
ytdl(url, { quality: itag })
getId(newFolderName + "prog").textContent = "Starting...";
const audioDownloading = ytdl(url, { quality: itag });
audioDownloading
.on("progress", (_, downloaded, size) => {
const progress = (downloaded / size) * 100;
if (progress != 100) {
getId("preparingBox").style.display = "none";
getId("audioProgressBox").style.display = "block";
getId("onlyAudioProgress").value = progress;
} else if (progress == 100) {
afterSave(downloadDir, filename);
if (cancelled) {
console.log("Cancelled");
audioDownloading.destroy();
fs.rm(path.join(downloadDir, filename), (err) => {
if (err) {
console.log(err);
}
});
return;
}
const progress = ((downloaded / size) * 100).toFixed(0);
getId(
newFolderName + "prog"
).textContent = `Progress: ${progress}%`;
})
.on("end", ()=>{
afterSave(
downloadDir,
filename,
newFolderName + "prog"
);
})
.pipe(fs.createWriteStream(path.join(downloadDir, filename)));
}
});
}
// Removing item
function fadeItem(id) {
let count = 0;
let opacity = 1;
const fade = setInterval(() => {
if (count >= 10) {
clearInterval(fade);
if (getId(id)) {
getId(id).remove();
}
} else {
opacity -= 0.1;
getId(id).style.opacity = opacity;
count++;
}
}, 50);
}
// After saving video
function afterSave(location, filename) {
function afterSave(location, filename, progressId) {
const notify = new Notification("ytDownloader", {
body: "File saved successfully.",
icon: "../assets/images/icon.png",
});
getId("videoProgressBox").style.display = "none";
getId("audioProgressBox").style.display = "none";
document.querySelector(".submitBtn").style.display = "inline-block";
getId(
"savedMsg"
).innerHTML = `File saved. Click to open <b title="Click to open" class="savedMsg">${location}</b>`;
getId("savedMsg").addEventListener("click", (e) => {
getId(progressId).innerHTML = `<b>File saved. Click to Open</b>`;
getId(progressId).addEventListener("click", () => {
shell.showItemInFolder(path.join(location, filename));
log(path.join(location, filename))
});
}
@ -347,16 +478,21 @@ async function findInfo(url, itag) {
const data = await ytdl.getInfo(url);
const format = ytdl.chooseFormat(data.formats, { quality: itag });
const title = data.videoDetails.title;
const id = data.videoDetails.videoId;
let type;
let extension;
if (format.hasVideo) {
extension = format.mimeType.split("; ")[0].split("/")[1];
type = "Video";
} else {
type = "Audio";
if (format.audioCodec === "mp4a.40.2") {
extension = "m4a";
} else {
extension = format.audioCodec;
}
}
let filetype = type + "/" + extension;
let quality;
if (format.hasVideo) {
@ -372,6 +508,8 @@ async function findInfo(url, itag) {
extension: extension,
quality: quality,
filename: filename,
id: id,
filetype: filetype,
};
return info;
}
@ -379,9 +517,9 @@ async function findInfo(url, itag) {
// Opening windows
getId("preferenceWin").addEventListener("click", () => {
ipcRenderer.send("load-page", __dirname + "/preferences.html")
ipcRenderer.send("load-page", __dirname + "/preferences.html");
});
getId("aboutWin").addEventListener("click", ()=>{
ipcRenderer.send("load-page", __dirname + "/about.html")
})
getId("aboutWin").addEventListener("click", () => {
ipcRenderer.send("load-page", __dirname + "/about.html");
});

Loading…
Cancel
Save