-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
154 lines (126 loc) · 4.15 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
var express = require('express');
var app = express();
var router = express.Router();
var sanitize = require("sanitize-filename");
var contentDisposition = require('content-disposition')
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var path = require('path');
var ytdl = require('ytdl-core');
var ffmpeg = require('fluent-ffmpeg');
//Serve static content from public folder
app.use(express.static(path.join(__dirname, 'public')));
router.get('/info/*', function(req, res, next) {
//@Accept both url and video id
if (typeof req.query.v == 'undefined') {
throw new Error("Invalid youtube link");
}
console.log("Getting info...");
ytdl.getInfo(req.query.v, (err, info) => {
if (err) throw err;
videoinfo = {
title: info.videoDetails.title,
duration: info.videoDetails.lengthSeconds,
//rating: info.avg_rating,//Removed by youtube, and i dont need it for now
uploaded_by: info.author.name,
thumbnail: info.thumbnail_url
};
/*
console.log('title:', info.videoDetails.title);
console.log('duration:', info.videoDetails.lengthSeconds);
console.log('rating:', info.avg_rating);
console.log('uploaded by:', info.author.name);
console.log('thumbnail:', info.thumbnail_url);
*/
res.json(videoinfo);
//@TODO: Add other thumbnails??? (If there is any...)
//@TODO: Add story urls (maybe use image from there???)
});
});
router.get('/mp3/:bitrate/*', function(req, res, next) {
var bitrate = 320;
if('undefined' != typeof req.params.bitrate && req.params.bitrate) {
bitrate = parseInt(req.params.bitrate);
}
var videoid = req.query.v;
var title = 'download';
var download = ytdl(videoid, { filter: 'audioonly', quality: 'highest' })
.on('info', (info, format) => {
//console.log(info);
title = sanitize(info.videoDetails.title);
console.log('Download '+ title +' has stated...\n');
var size = (((info.videoDetails.lengthSeconds*bitrate) / 8)*1024);
console.log('Length '+ info.videoDetails.lengthSeconds +' ( Size: ' + size + ')...\n');
res.setHeader('Content-Length', size.toString());
res.setHeader('Set-Cookie', 'fileDownload=true; path=/');
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
// res.setHeader('Content-Disposition', contentDisposition(title + '.mp3'))
res.attachment(title + ".mp3");
console.log('Headers set...');
})
.on('response', (ytres) => {
console.log('Video response from youtube is here\n');
})
.on('progress', (chunkLength, downloaded, total) => {
//var floatDownloaded = downloaded / total;
//var downloadedMinutes = (Date.now() - starttime) / 1000 / 60;
})
.on('error', err => {
console.error(err);
});
//ffmpeg('audio.mp4')
ffmpeg(download)
.addInput(`https://i.ytimg.com/vi/${videoid}/maxresdefault.jpg`)
.addOutputOption('-metadata:s:a', 'title="Album cover"')
.addOutputOption('-metadata:s:a', 'comment="Cover (front)"')
.audioCodec('libmp3lame')
.audioBitrate(bitrate)//@TODO: Make dynamic (user can chose)
.format('mp3')//@TODO: Make dynamic (let user chose what he wants)
.on('error', (err) => {
console.error(err);
next(err);
})
/*
.on('progress', function(info) {
console.log('ffmpeg progress ' + info.percent + '%');
})
.on('data', function(chunk) {
console.log('ffmpeg just wrote ' + chunk.length + ' bytes');
})
*/
.on('end', () => {
console.log('Download " '+ title +' " finished!');
})
// .saveToFile(testFile);//Dont write to file, pipe it to response (<3 you Node.js !)
.pipe(res, {
end: true
});
});
//User our routes
app.use(router);
// catch 404 and forward to error handler
app.use((req,res,next)=>{
const err = new Error('Not Found');
err.status = 404;
next(err);
});
//error handling from api
app.use((err,req,res,next)=>{
const error = app.get('env') === 'development'?err:{};
const status = err.status || 500;
res.status(status).json({
error:{
code: err.status,
message: error.message
}
})
console.log(error);
})
let port = process.env.PORT;
if (port == null || port == "") {
port = 3000;
}
app.listen(port,()=>{
console.log(' ytdl is running on port ' + port);
});