-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
129 lines (106 loc) · 4.18 KB
/
app.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
const express = require('express');
const ytdl = require('ytdl-core');
const path = require('path');
const sanitize = require('sanitize-filename');
const ffmpeg = require('fluent-ffmpeg');
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
ffmpeg.setFfmpegPath(ffmpegPath);
const app = express();
const port = 3000;
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
res.render('index');
});
app.get('/search', async (req, res) => {
const videoURL = req.query.url;
if (!videoURL) {
return res.status(400).send('URL is required');
}
try {
const info = await ytdl.getInfo(videoURL);
const formats = ytdl.filterFormats(info.formats, format => format.hasVideo);
const thumbnail = info.videoDetails.thumbnails[info.videoDetails.thumbnails.length - 1].url;
const title = info.videoDetails.title;
res.render('results', { url: videoURL, formats: formats, thumbnail: thumbnail, title: title });
} catch (error) {
console.error('Error fetching video information:', error);
res.status(500).send('Failed to fetch video information');
}
});
app.get('/stream', async (req, res) => {
const videoURL = req.query.url;
const quality = req.query.quality;
if (!videoURL || !quality) {
return res.status(400).send('URL and quality are required');
}
try {
const videoInfo = await ytdl.getInfo(videoURL);
const format = ytdl.chooseFormat(videoInfo.formats, { quality: quality });
if (!format) {
return res.status(404).send('No such format found');
}
console.log(`Streaming video in format with quality: ${quality}`);
res.header('Content-Type', 'video/mp4');
ytdl(videoURL, {
format: format,
requestOptions: {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
}
})
.on('error', (err) => {
console.error('Error streaming video:', err);
res.status(500).send('Failed to stream video');
})
.pipe(res);
} catch (error) {
console.error('Error fetching video info:', error);
res.status(500).send('Failed to stream video');
}
});
app.get('/download', async (req, res) => {
const videoURL = req.query.url;
const quality = req.query.quality;
let title = decodeURIComponent(req.query.title || 'video');
if (!videoURL || !quality) {
console.error('Missing URL or quality');
return res.status(400).send('URL and quality are required');
}
try {
console.log(`Fetching video info for URL: ${videoURL}`);
const videoInfo = await ytdl.getInfo(videoURL);
console.log('Video info fetched successfully');
console.log(`Choosing format with quality: ${quality}`);
const format = ytdl.chooseFormat(videoInfo.formats, { quality: quality });
if (!format) {
console.error('No matching format found');
return res.status(404).send('No such format found');
}
console.log('Format chosen successfully');
title = sanitize(title);
title = title.replace(/[^\x20-\x7E]/g, '');
res.header('Content-Disposition', `attachment; filename="${title}.mp4"`);
ytdl(videoURL, {
format: format,
requestOptions: {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
}
})
.on('error', (err) => {
console.error('Error downloading video:', err);
res.status(500).send('Failed to download video');
})
.pipe(res);
} catch (error) {
console.error('Error fetching video info:', error);
res.status(500).send('Failed to download video');
}
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});