Video resolver working, download to complete
This commit is contained in:
6
README.md
Normal file
6
README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# youtube-downloader
|
||||||
|
|
||||||
|
Simple to use youtube downloader, simply run the index javascript file with node and then go to localhost on your browser, by default the video will download to this folder but can be changed in src/index.js
|
||||||
|
|
||||||
|
# Contrubutors
|
||||||
|
- Ben (plane000)#8618 <benjaminkyd@gmail.com>
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
# youtube-downloader
|
|
||||||
|
|
||||||
Simple to use youtube downloader, simply fill up the text files with videos you wish to download, sepperated by lines. run `npm i` and `node index.js` to download all of the videos in the file!
|
|
||||||
|
|
||||||
# Contrubutors
|
|
||||||
- Ben (plane000)#8618 <benjaminkyd@gmail.com>
|
|
||||||
5
package-lock.json
generated
5
package-lock.json
generated
@@ -389,6 +389,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/miniget/-/miniget-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/miniget/-/miniget-1.5.1.tgz",
|
||||||
"integrity": "sha512-KJ3AyIVZ76QuWAq43BWjkK+jLdhxhy3s4tsdg9Je91+cIFkeOSW2VEj2lSeKw50CPu1eCCkSbiQEBKL36mpA5w=="
|
"integrity": "sha512-KJ3AyIVZ76QuWAq43BWjkK+jLdhxhy3s4tsdg9Je91+cIFkeOSW2VEj2lSeKw50CPu1eCCkSbiQEBKL36mpA5w=="
|
||||||
},
|
},
|
||||||
|
"moment": {
|
||||||
|
"version": "2.23.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.23.0.tgz",
|
||||||
|
"integrity": "sha512-3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA=="
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.16.4",
|
"express": "^4.16.4",
|
||||||
|
"moment": "^2.23.0",
|
||||||
"socket.io": "^2.2.0",
|
"socket.io": "^2.2.0",
|
||||||
"ytdl-core": "^0.28.3"
|
"ytdl-core": "^0.28.3"
|
||||||
}
|
}
|
||||||
|
|||||||
0
public/favicon.ico
Normal file
0
public/favicon.ico
Normal file
@@ -6,10 +6,11 @@
|
|||||||
<title>Page Title</title>
|
<title>Page Title</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" type="text/css" media="screen" href="style.css" />
|
<link rel="stylesheet" type="text/css" media="screen" href="style.css" />
|
||||||
|
<script src="/socket.io/socket.io.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="Instructions">
|
<div id="Instructions">
|
||||||
<h1 id="CurrentDirectory">Currently saving videos to: <code>~/Desktop</code></h1>
|
<h1 id="CurrentDirectory">Currently saving videos to: <code id="saveloc">./</code></h1>
|
||||||
|
|
||||||
Videos to record (seperate different videos by new lines):
|
Videos to record (seperate different videos by new lines):
|
||||||
</div>
|
</div>
|
||||||
@@ -18,7 +19,10 @@
|
|||||||
<textarea id="VideosToRecord"></textarea>
|
<textarea id="VideosToRecord"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <button id="ChangeDirectory" type="button">Video save location</button> -->
|
<button id="Download">Download</button>
|
||||||
|
|
||||||
|
<div id="VideoPreview"></div>
|
||||||
|
|
||||||
<script src="index.js"></script>
|
<script src="index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,10 +1,65 @@
|
|||||||
|
let socket = io();
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
console.log('Starting up');
|
console.log('Starting up');
|
||||||
})();
|
})();
|
||||||
|
|
||||||
let VideosToDownload = [];
|
socket.on('path', async (data) => {
|
||||||
|
document.getElementById('saveloc').innerText = data;
|
||||||
|
});
|
||||||
|
|
||||||
|
let isDownloading = false;
|
||||||
|
let VideosToDownload = {};
|
||||||
document.getElementById('VideosToRecord').addEventListener('keyup', (e) => {
|
document.getElementById('VideosToRecord').addEventListener('keyup', (e) => {
|
||||||
|
if (isDownloading) return;
|
||||||
let current = document.getElementById('VideosToRecord').value;
|
let current = document.getElementById('VideosToRecord').value;
|
||||||
VideosToDownload = current.split('\n');
|
VideosToDownload = current.split('\n');
|
||||||
console.log(VideosToDownload);
|
|
||||||
|
let payload = {
|
||||||
|
ExpectPreview: true,
|
||||||
|
VideosToDownload: VideosToDownload
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.emit('video-list', payload);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let VideoPreview = [];
|
||||||
|
|
||||||
|
function renderPreview() {
|
||||||
|
if (isDownloading) return;
|
||||||
|
document.getElementById('VideoPreview').innerText = '';
|
||||||
|
for (const [key, value] of Object.entries(VideoPreview)) {
|
||||||
|
if (document.getElementById(key) == null) {
|
||||||
|
if (!value.found) {
|
||||||
|
document.getElementById('VideoPreview').innerHTML += `<div id="${key}">${key}: <h>Video not found</h></div>`;
|
||||||
|
} else {
|
||||||
|
document.getElementById('VideoPreview').innerHTML += `<div id="${key}">${key}: <h>${value.title}</h></div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearPreview() {
|
||||||
|
document.getElementById('VideoPreview').innerText = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.on('video-preview', async (data) => {
|
||||||
|
if (isDownloading) return;
|
||||||
|
if (!data || !data.data || data.contents == false) {
|
||||||
|
clearPreview();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
VideoPreview = data.data;
|
||||||
|
renderPreview();
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
isDownloading = true;
|
||||||
|
console.log('Asked server for download...');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,3 +29,11 @@ textarea {
|
|||||||
width: 400px;
|
width: 400px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#VideoPreview {
|
||||||
|
font-weight: lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
h {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
const server = require('./server');
|
const server = require('./server');
|
||||||
|
|
||||||
|
let config = {
|
||||||
|
serverPort: 80,
|
||||||
|
downloadLocation: './'
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.config = config;
|
||||||
|
|
||||||
module.exports.main = async () => {
|
module.exports.main = async () => {
|
||||||
await server.init();
|
await server.init();
|
||||||
await server.listen();
|
await server.listen();
|
||||||
|
|||||||
7
src/logger.js
Normal file
7
src/logger.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const moment = require('moment');
|
||||||
|
const dateFormat = 'DD-MM-YY HH:mm:ss'
|
||||||
|
|
||||||
|
module.exports.log = function(log) {
|
||||||
|
let d = moment().format(dateFormat);
|
||||||
|
console.log('[' + d.toLocaleString() + '] ' + log);
|
||||||
|
}
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
const logger = require('./logger')
|
||||||
|
const main = require('./index');
|
||||||
|
const youtube = require('./youtubehelper');
|
||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
|
|
||||||
let app;
|
let app;
|
||||||
@@ -9,14 +13,34 @@ module.exports.init = async () => {
|
|||||||
http = require('http').Server(app);
|
http = require('http').Server(app);
|
||||||
io = require('socket.io')(http);
|
io = require('socket.io')(http);
|
||||||
|
|
||||||
http.listen(8080, () => {
|
http.listen(main.config.serverPort, () => {
|
||||||
console.log('HTTP server listening on port 8080');
|
logger.log(`HTTP server listening on port ${main.config.serverPort}`);
|
||||||
console.log('WebSocket server listening');
|
logger.log(`WebSocket server listening on ${main.config.serverPort}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.listen = async () => {
|
module.exports.listen = async () => {
|
||||||
app.use(express.static('public'));
|
app.use(express.static('public'));
|
||||||
|
|
||||||
|
io.on('connection', async (socket) => {
|
||||||
|
logger.log(`New socket connection from id: ${socket.id}`);
|
||||||
|
|
||||||
|
socket.emit('path', main.config.downloadLocation);
|
||||||
|
|
||||||
|
socket.on('video-list', async (data) => {
|
||||||
|
if (data.ExpectPreview) {
|
||||||
|
logger.log(`Socket id '${socket.id}' is requesting a video preview`);
|
||||||
|
let response = await youtube.resolveVideos(data.VideosToDownload);
|
||||||
|
socket.emit('video-preview', response);
|
||||||
|
logger.log(`Finished preview for socket id '${socket.id}'`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('download', async (data) => {
|
||||||
|
logger.log(`Socket id ${socket.id}' is requesting a download`);
|
||||||
|
youtube.downloadVideos(data, socket, {path: main.config.downloadLocation});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.app = app;
|
module.exports.app = app;
|
||||||
|
|||||||
34
src/youtubehelper.js
Normal file
34
src/youtubehelper.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
const ytdl = require('ytdl-core');
|
||||||
|
|
||||||
|
module.exports.resolveVideos = async (arr) => {
|
||||||
|
let output = {contents: false, data: {}};
|
||||||
|
|
||||||
|
for (let video of arr) {
|
||||||
|
if (video == '' || video == ' ') continue;
|
||||||
|
if (await ytdl.validateURL(video)) {
|
||||||
|
const info = await ytdl.getBasicInfo(video);
|
||||||
|
if (!info) {
|
||||||
|
output.data[video] = {found: false};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
output.data[video] = {
|
||||||
|
found: true,
|
||||||
|
title: info.title,
|
||||||
|
thumbnail: info.thumbnail_url.replace('default', 'maxresdefault'),
|
||||||
|
runtime: info.length_seconds
|
||||||
|
}
|
||||||
|
output.contents = true;
|
||||||
|
} else {
|
||||||
|
output.data[video] = {found: false};
|
||||||
|
output.contents = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.downloadVideos = async (arr, socket, options) => {
|
||||||
|
let path = options.path ? options.path : './'
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user