| 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 = async (url, form, headers = {}) => { |
| const response = await fetch(url, { |
| method: 'post', |
| body: new URLSearchParams(form), |
| headers |
| }); |
| return response; |
| }; |
|
|
| |
| 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(); |
| let result; |
|
|
| |
| if (data.statusCode === 200) result = data.result; |
| while (!result) { |
| let json = await (await post(`${server}/api/json/convert`, params)).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 { |
| let { url } = req.query; |
| url = url.replace('#', '%23'); |
| 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, |
| size: file.size, |
| contents: data.toString() |
| }); |
| } catch (error) { |
| console.error(error); |
| res.json({ message: error.message }); |
| } |
| }) |
| .listen(7860, () => console.log('App running on port 7860')); |
|
|