This commit is contained in:
Isaac Grynsztein
2018-01-13 22:14:10 -05:00
parent d6cb024de1
commit 1eaf897be0
26 changed files with 284 additions and 12 deletions

View File

@@ -9,7 +9,10 @@
"outDir": "dist",
"assets": [
"assets",
"favicon.ico"
"favicon.ico",
"backend/audio",
"backend/video",
"backend"
],
"index": "index.html",
"main": "main.ts",

4
.gitignore vendored
View File

@@ -40,3 +40,7 @@ testem.log
# System Files
.DS_Store
Thumbs.db
node_modules/*
backend/node_modules/*
YoutubeDL-Material/node_modules/*

206
backend/app.js Normal file
View File

@@ -0,0 +1,206 @@
var async = require('async');
var fs = require('fs');
var path = require('path');
var youtubedl = require('youtube-dl');
var config = require('config');
const https = require('https');
var express = require("express");
var bodyParser = require("body-parser");
var app = express();
var appAnchor = express();
var hostURL = config.get("YoutubeDL-Material.Host.url");
var hostPort = config.get("YoutubeDL-Material.Host.port");
var usingEncryption = config.get("YoutubeDL-Material.Encryption.use-encryption");
var basePath = config.get("YoutubeDL-Material.Downloader.path-base");
var audioPath = config.get("YoutubeDL-Material.Downloader.path-audio");
var videoPath = config.get("YoutubeDL-Material.Downloader.path-video");
if (usingEncryption)
{
var certFilePath = path.resolve(config.get("YoutubeDL-Material.Encryption.cert-file-path"));
var keyFilePath = path.resolve(config.get("YoutubeDL-Material.Encryption.key-file-path"));
var certKeyFile = fs.readFileSync(certFilePath);
var certFile = fs.readFileSync(keyFilePath);
var options = {
key: certKeyFile,
cert: certFile
};
}
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
appAnchor.use(bodyParser.urlencoded({ extended: false }));
appAnchor.use(bodyParser.json());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", hostURL);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
appAnchor.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", hostURL);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
appAnchor.get('/url', function(req, res) {
res.send(JSON.stringify(("localhost" + ":" + hostPort + "/")));
res.end("yes");
});
appAnchor.get('/using-encryption', function(req, res) {
res.send(usingEncryption);
res.end("yes");
});
app.post('/tomp3', function(req, res) {
var url = req.body.url;
var date = Date.now();
var path = audioPath;
var audiopath = Date.now();
youtubedl.exec(url, ['--no-check-certificate','-o', path + audiopath + ".mp3", '-x', '--audio-format', 'mp3'], {}, function(err, output) {
if (err) {
audiopath = "-1";
throw err;
}
});
var completeString = "done";
var audiopathEncoded = encodeURIComponent(audiopath);
res.send(audiopathEncoded);
res.end("yes");
});
app.post('/tomp4', function(req, res) {
var url = req.body.url;
var date = Date.now();
var path = videoPath;
var videopath = Date.now();
youtubedl.exec(url, ['--no-check-certificate', '-o', path + videopath + ".mp4", '-f', 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/mp4'], {}, function(err, output) {
if (err) {
videopath = "-1";
throw err;
}
});
var completeString = "done";
var videopathEncoded = encodeURIComponent(videopath);
res.send(videopathEncoded);
res.end("yes");
});
app.post('/mp3fileexists', function(req, res) {
var name = req.body.name + "";
var exists = "";
var fullpath = audioPath + name + ".mp3";
if (fs.existsSync(fullpath)) {
exists = basePath + audioPath + name;
}
else
{
exists = "failed";
}
//console.log(exists + " " + name);
res.send(JSON.stringify(exists));
res.end("yes");
});
app.post('/mp4fileexists', function(req, res) {
var name = req.body.name;
var exists = "";
var fullpath = videoPath + name + ".mp4";
if (fs.existsSync(fullpath)) {
exists = basePath + videoPath + name;
}
else
{
exists = "failed";
}
//console.log(exists + " " + name);
res.send(JSON.stringify(exists));
res.end("yes");
});
app.get('/video/:id', function(req , res){
const path = "video/" + req.params.id + ".mp4";
const stat = fs.statSync(path)
const fileSize = stat.size
const range = req.headers.range
if (range) {
const parts = range.replace(/bytes=/, "").split("-")
const start = parseInt(parts[0], 10)
const end = parts[1]
? parseInt(parts[1], 10)
: fileSize-1
const chunksize = (end-start)+1
const file = fs.createReadStream(path, {start, end})
const head = {
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
'Accept-Ranges': 'bytes',
'Content-Length': chunksize,
'Content-Type': 'video/mp4',
}
res.writeHead(206, head);
file.pipe(res);
} else {
const head = {
'Content-Length': fileSize,
'Content-Type': 'video/mp4',
}
res.writeHead(200, head)
fs.createReadStream(path).pipe(res)
}
});
app.get('/audio/:id', function(req , res){
const path = "audio/" + req.params.id + ".mp3";
const stat = fs.statSync(path)
const fileSize = stat.size
const range = req.headers.range
if (range) {
const parts = range.replace(/bytes=/, "").split("-")
const start = parseInt(parts[0], 10)
const end = parts[1]
? parseInt(parts[1], 10)
: fileSize-1
const chunksize = (end-start)+1
const file = fs.createReadStream(path, {start, end})
const head = {
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
'Accept-Ranges': 'bytes',
'Content-Length': chunksize,
'Content-Type': 'audio/mp3',
}
res.writeHead(206, head);
file.pipe(res);
} else {
const head = {
'Content-Length': fileSize,
'Content-Type': 'audio/mp3',
}
res.writeHead(200, head)
fs.createReadStream(path).pipe(res)
}
});
appAnchor.listen(17442,function(){
console.log("Anchor set on 17442");
});
if (usingEncryption)
{
https.createServer(options, app).listen(hostPort, function() {
console.log('HTTPS: Started on PORT ' + hostPort);
});
}
else
{
app.listen(hostPort,function(){
console.log("HTTP: Started on PORT " + hostPort);
});
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,18 @@
{
"YoutubeDL-Material": {
"Host": {
"url": "example.com",
"port": "8088"
},
"Encryption": {
"use-encryption": false,
"cert-file-path": "fullchain.pem",
"key-file-path": "privkey.pem"
},
"Downloader": {
"path-base": "http://localhost:8088/",
"path-audio": "audio/",
"path-video": "video/"
}
}
}

View File

@@ -0,0 +1,18 @@
{
"YoutubeDL-Material": {
"Host": {
"url": "http://localhost:4200",
"port": "8088"
},
"Encryption": {
"use-encryption": false,
"cert-file-path": "fullchain.pem",
"key-file-path": "privkey.pem"
},
"Downloader": {
"path-base": "http://localhost:8088/",
"path-audio": "audio/",
"path-video": "video/"
}
}
}

BIN
backend/ffmpeg.exe Normal file

Binary file not shown.

BIN
backend/ffplay.exe Normal file

Binary file not shown.

BIN
backend/ffprobe.exe Normal file

Binary file not shown.

23
backend/package.json Normal file
View File

@@ -0,0 +1,23 @@
{
"name": "backend",
"version": "1.0.0",
"description": "backend for hda",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Tzahi12345/hda-backend.git"
},
"author": "Isaac Grynsztein",
"license": "MIT",
"bugs": {
"url": "https://github.com/Tzahi12345/hda-backend/issues"
},
"homepage": "https://github.com/Tzahi12345/hda-backend#readme",
"dependencies": {
"exe": "^1.0.2",
"youtube-dl": "1.11.1"
}
}

Binary file not shown.

Binary file not shown.

BIN
backend/youtube-dl.exe Normal file

Binary file not shown.

View File

@@ -27,7 +27,7 @@
</form>
<br/>
<mat-checkbox [(ngModel)]="audioOnly" style="float: left; margin-top: -12px">Only Audio</mat-checkbox>
<button style="float: right; margin-top: -16px" (click)="downloadClicked()" [disabled]="downloadingmp3" type="submit" mat-raised-button color="primary">Download</button>
<button style="float: right; margin-top: -16px" (click)="downloadClicked()" [disabled]="downloadingfile" type="submit" mat-raised-button color="primary">Download</button>
</mat-card-content>
</div>
</mat-card>

View File

@@ -13,12 +13,12 @@ import 'rxjs/add/operator/toPromise';
styleUrls: ['./app.component.css']
})
export class AppComponent {
downloadingmp3: boolean = false;
downloadingfile: boolean = false;
audioOnly: boolean;
urlError: boolean = false;
path: string = '';
url: string = '';
exists: boolean = false;
exists: string = "";
topBarTitle: string = "Youtube Downloader";
constructor(private postsService: PostsService) {
this.audioOnly = true;
@@ -48,13 +48,13 @@ export class AppComponent {
{
this.postsService.getFileStatusMp3(name).subscribe(fileExists => {
this.exists = fileExists;
if (this.exists == false)
if (this.exists == "failed")
{
this.downloadHelperMp3(name);
}
else
{
window.location.href = 'https://grynsztein.com/audio/' + this.path + ".mp3";
window.location.href = this.exists;
}
});
@@ -64,13 +64,13 @@ export class AppComponent {
{
this.postsService.getFileStatusMp4(name).subscribe(fileExists => {
this.exists = fileExists;
if (this.exists == false)
if (this.exists == "failed")
{
this.downloadHelperMp4(name);
}
else
{
window.location.href = 'https://grynsztein.com/video/' + this.path + ".mp4";
window.location.href = this.exists;
}
});
@@ -85,7 +85,7 @@ export class AppComponent {
if (this.audioOnly)
{
this.downloadingmp3 = true;
this.downloadingfile = true;
this.postsService.makeMP3(this.url).subscribe(posts => {
this.path = posts;
if (this.path != "-1")
@@ -97,7 +97,7 @@ export class AppComponent {
}
else
{
this.downloadingmp3 = true;
this.downloadingfile = true;
this.postsService.makeMP4(this.url).subscribe(posts => {
this.path = posts;
if (this.path != "-1")

View File

@@ -48,12 +48,12 @@ export class PostsService {
.map(res => res.json());
}
getFileStatusMp3(name: string): Observable<boolean> {
getFileStatusMp3(name: string): Observable<string> {
return this.http.post(this.path + "mp3fileexists",{name: name})
.map(res => res.json());
}
getFileStatusMp4(name: string): Observable<boolean> {
getFileStatusMp4(name: string): Observable<string> {
return this.http.post(this.path + "mp4fileexists",{name: name})
.map(res => res.json());
}