diff --git a/public/index.html b/public/index.html
index a9b9f7d..1096980 100644
--- a/public/index.html
+++ b/public/index.html
@@ -3,7 +3,7 @@
- Page Title
+ Ben's YouTube Downloader
@@ -21,7 +21,9 @@
-
+
diff --git a/public/index.js b/public/index.js
index b311a23..14f337a 100644
--- a/public/index.js
+++ b/public/index.js
@@ -27,20 +27,20 @@ let VideoPreview = [];
function renderPreview() {
if (isDownloading) return;
- document.getElementById('VideoPreview').innerText = '';
+ document.getElementById('VideoBox').innerText = '';
for (const [key, value] of Object.entries(VideoPreview)) {
if (document.getElementById(key) == null) {
if (!value.found) {
- document.getElementById('VideoPreview').innerHTML += `${key}: Video not found
`;
+ document.getElementById('VideoBox').innerHTML += `${key}: Video not found
`;
} else {
- document.getElementById('VideoPreview').innerHTML += `${key}: ${value.title}
`;
+ document.getElementById('VideoBox').innerHTML += `${key}: ${value.title}
`;
}
}
}
}
function clearPreview() {
- document.getElementById('VideoPreview').innerText = '';
+ document.getElementById('VideoBox').innerText = '';
}
socket.on('video-preview', async (data) => {
@@ -56,10 +56,40 @@ socket.on('video-preview', async (data) => {
document.getElementById('Download').addEventListener('click', async (event) => {
if (isDownloading) return;
socket.emit('download', document.getElementById('VideosToRecord').value.split('\n'));
- document.getElementById('VideoPreview').innerText = '\nDownloading...';
- document.getElementById('VideosToRecord').value = null;
+ document.getElementById('VideoBox').innerText = 'Downloading...';
+ // document.getElementById('VideosToRecord').value = null;
isDownloading = true;
console.log('Asked server for download...');
});
+let downloads = [];
+let downloadCount = 0;
+let completedDownloads = 0;
+function renderDownloads() {
+ document.getElementById('VideoBox').innerText = '';
+ for (const [key, value] of Object.entries(downloads)) {
+ document.getElementById('VideoBox').innerHTML += `${value.title}: ${value.percent}
`;
+ }
+}
+
+socket.on('download-count', async (data) => {
+ downloadCount = data.num;
+});
+
+socket.on('download-done', async(data) => {
+ completedDownloads++;
+
+ downloads[data.video] = {title: data.title, percent: 'Complete!'};
+ renderDownloads();
+ if (completedDownloads == downloadCount) {
+ completedDownloads = 0; downloadCount = 0;
+ isDownloading = false;
+ downloads = [];
+ }
+});
+
+socket.on('download-progress', async (data) => {
+ downloads[data.video] = data;
+ renderDownloads();
+});
diff --git a/public/resources/YouTube Logo.png b/public/resources/YouTube Logo.png
new file mode 100644
index 0000000..f88fdb2
Binary files /dev/null and b/public/resources/YouTube Logo.png differ
diff --git a/public/style.css b/public/style.css
index ad6d181..9133357 100644
--- a/public/style.css
+++ b/public/style.css
@@ -30,7 +30,12 @@ textarea {
height: 100px;
}
-#VideoPreview {
+.VideoContainer {
+ padding: 30px, 0px, 30px, 0px;
+}
+
+#VideoBox {
+ padding-top: 10px;
font-weight: lighter;
}
diff --git a/src/index.js b/src/index.js
index 60ed9f1..c393c27 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,7 +1,7 @@
const server = require('./server');
let config = {
- serverPort: 80,
+ serverPort: 8080,
downloadLocation: './'
};
diff --git a/src/server.js b/src/server.js
index a9f476f..e2926c3 100644
--- a/src/server.js
+++ b/src/server.js
@@ -37,8 +37,9 @@ module.exports.listen = async () => {
});
socket.on('download', async (data) => {
- logger.log(`Socket id ${socket.id}' is requesting a download`);
- youtube.downloadVideos(data, socket, {path: main.config.downloadLocation});
+ logger.log(`Socket id '${socket.id}' is requesting a download`);
+ let toDownload = await youtube.resolveVideos(data);
+ youtube.downloadVideos(toDownload.data, socket, {path: main.config.downloadLocation});
});
});
}
diff --git a/src/youtubehelper.js b/src/youtubehelper.js
index a8559aa..55e743f 100644
--- a/src/youtubehelper.js
+++ b/src/youtubehelper.js
@@ -1,3 +1,6 @@
+const logger = require('./logger');
+
+const fs = require('fs');
const ytdl = require('ytdl-core');
module.exports.resolveVideos = async (arr) => {
@@ -29,6 +32,39 @@ module.exports.resolveVideos = async (arr) => {
module.exports.downloadVideos = async (arr, socket, options) => {
let path = options.path ? options.path : './'
-
+ let numOfDownloads = 0;
+ for (const [key, value] of Object.entries(arr)) {
+ if (ytdl.validateURL(key)) {
+ try {
+ const stream = await ytdl(key, {quality: 'highest'});
+ stream.pipe(fs.createWriteStream(`${path}/${value.title}.mp4`));
+
+ stream.on('response', (res) => {
+ let totalSize = res.headers['content-length'];
+ let dataRead = 0;
+ let lastPercent = 0;
+ res.on('data', (data) => {
+ dataRead += data.length;
+ let percent = Math.floor((dataRead / totalSize) * 100) + '%';
+ if (percent != lastPercent) {
+ socket.emit('download-progress', {video: key, percent: percent, title: value.title});
+ }
+ lastPercent = percent;
+ });
+ res.on('end', () => {
+ logger.log(`Socket id '${socket.id}' finished downloading ${value.title}`)
+ socket.emit('download-done', {video: key, title: value.title});
+ });
+ });
+
+ logger.log(`Socket id '${socket.id}' is downloading ${value.title}`);
+ } catch (e) {
+ logger.log(`Socket id '${socket.id}' failed to download ${value.title}`);
+ socket.emit('download-done', {video: key, title: value.title});
+ }
+ numOfDownloads++;
+ }
+ }
+ socket.emit('download-count', {num: numOfDownloads});
}