File size: 4,719 Bytes
9198234
 
 
e802f17
9198234
 
e802f17
9198234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9c65292
9198234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e802f17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9198234
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
const yts = require('yt-search')
const morgan = require('morgan')
const express = require('express')
const { File } = require('megajs')

const ytIdRegex = /(?:http(?:s|):\/\/|)(?:(?:www\.|)?youtube(?:\-nocookie|)\.com\/(?:shorts\/)?(?:watch\?.*(?:|\&)v=|embed\/|v\/)?|youtu\.be\/)([-_0-9A-Za-z]{11})/
const megaRegex = /https:\/\/mega\.nz\/file\/[A-Za-z0-9]+#[A-Za-z0-9-_]+/;
const post = (url, form, headers = {}) => fetch(url, {
	method: 'post',
	body: new URLSearchParams(form),
	headers
})

const convert = async (url, v_id, ftype, fquality, fname, token, timeExpire) => {
	let params = {
		v_id, ftype,
		fquality, fname,
		token, timeExpire,
		client: 'yt5s.com'
	}
	let resServer = await (await post(url, params, { 'x-requested-key': 'de0cfuirtgf67a' })).json()
	let server = resServer.c_server
	if (!server && ftype === 'mp3') return server || resServer.d_url || ''
	let data = await (await post(`${server}/api/json/convert`, params)).json()
	// console.log(data)
	let result
	if (data.statusCode === 200) result = data.result
	while (!result) {
		let json = await (await post(`${server}/api/json/convert`, params)).json()
		// console.log(json)
		if (json.statusCode === 200) {
			result = json.result
			break
		}
		await new Promise(resolve => setTimeout(resolve, 2000))
	}
	return result
}

const youtubedl = async (url) => {
	let html = await (await fetch('https://yt5s.com/en32')).text()
	let urlAjax = (html.match(/k_url_search="(.*?)"/) || [])[1]
	let urlConvert = (html.match(/k_url_convert="(.*?)"/) || [])[1]
	let json = await (await post(urlAjax, { q: url, vt: 'home' })).json()
	let video = {}, audio = {}
	if (!json?.links) throw json.mess
	Object.values(json.links.mp4).map(({ k, size }) => video[k] = {
		quality: k,
		fileSizeH: size,
		fileSize: parseFloat(size) * (/MB$/.test(size) ? 1000 : 1),
		download: convert.bind(null, urlConvert, json.vid, 'mp4', k, json.fn, json.token, parseInt(json.timeExpires))
	})
	
	Object.values(json.links.mp3).map(({ key, size }) => audio[key] = {
		quality: key,
		fileSizeH: size,
		fileSize: parseFloat(size) * (/MB$/.test(size) ? 1000 : 1),
		download: convert.bind(null, urlConvert, json.vid, 'mp3', key.replace(/kbps/i, ''), json.fn, json.token, parseInt(json.timeExpires))
	})
	
	return {
		id: json.vid,
		title: json.title,
		thumbnail: `https://i.ytimg.com/vi/${json.vid}/0.jpg`,
		video,
		audio
	}
}

const app = express()
	.set('json spaces', 4)
	.use(morgan('dev'))
	.use(express.json())
	.all('/', (_, res) => res.send('Hello World'))
	.get('/yt', async (req, res) => {
		const host = 'https://' + req.get('host')
		try {
			let { url, type, quality, json } = req.query
			if (!ytIdRegex.test(url)) return res.json({ message: 'Invalid URL' })
			if (!!json) {
				let ytId = ytIdRegex.exec(url)?.[1]
				if (!ytId) return res.json({ message: 'No video id found' })
				let data = await yts({ videoId: ytId })
				return res.json({
					...data,
					download: {
						audio: `${host}/yt?url=${url}&type=audio&quality=`,
						video: `${host}/yt?url=${url}&type=video&quality=`,
					}
				})
			}
			if (!type || !/audio|video/i.test(type)) type = 'video'
			let data = await youtubedl(url).catch(e => console.log(e))
			if (!data) return res.json({ message: 'Error: link download not found' })
			type = type.toLowerCase()
			let result = quality ? Object.values(data[type]).find(x => x.quality == quality) : Object.values(data[type])[0]
			if (quality && !result) return res.json({ message: `Invalid quality: ${quality}, available quality (${Object.keys(data[type]).join('/')})` })
			if (!result) return res.json({ message: 'Error: can\'t download' })
			res.redirect(await result.download())
		} catch (e) {
			console.log(e)
			res.json({ message: e })
		}
	})
	.get('/search', async (req, res) => {
		try {
			let q = req.query.q || req.query.query
			if (!q) return res.json({ message: 'Input parameter q' })
			let data = await yts(q)
			if (!data.all[0]) return res.json({ message: 'Not found' })
			res.json(data.all)
		} catch (e) {
			console.log(e)
			res.json({ message: e })
		}
    })
    .get('/megajs', async (req, res) => {
    try {
        const { url } = req.query;
        if (!megaRegex.test(url)) return res.json({ message: 'Invalid URL' });

        const file = File.fromURL(url);
        await file.loadAttributes();

        const data = await file.downloadBuffer();
        res.json({
            name: file.name, // file name
            size: file.size, // file size in bytes
            contents: data.toString() // file contents
        });
    } catch (error) {
        console.error(error);
        res.json({ message: error.message });
    }
})
	.listen(7860, () => console.log('App running on port 7860'))