Update index.js
Browse files
index.js
CHANGED
|
@@ -1,137 +1,154 @@
|
|
| 1 |
-
const yts = require('yt-search')
|
| 2 |
-
const morgan = require('morgan')
|
| 3 |
-
const express = require('express')
|
| 4 |
-
const { File } = require('megajs')
|
| 5 |
|
| 6 |
-
|
|
|
|
| 7 |
const megaRegex = /https:\/\/mega\.nz\/file\/[A-Za-z0-9]+#[A-Za-z0-9-_]+/;
|
| 8 |
-
const post = (url, form, headers = {}) => fetch(url, {
|
| 9 |
-
method: 'post',
|
| 10 |
-
body: new URLSearchParams(form),
|
| 11 |
-
headers
|
| 12 |
-
})
|
| 13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
const convert = async (url, v_id, ftype, fquality, fname, token, timeExpire) => {
|
| 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 |
const youtubedl = async (url) => {
|
| 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 |
const app = express()
|
| 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 |
.get('/megajs', async (req, res) => {
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
|
| 123 |
-
|
| 124 |
-
|
| 125 |
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
})
|
| 137 |
-
|
|
|
|
| 1 |
+
const yts = require('yt-search');
|
| 2 |
+
const morgan = require('morgan');
|
| 3 |
+
const express = require('express');
|
| 4 |
+
const { File } = require('megajs');
|
| 5 |
|
| 6 |
+
// Regex untuk mengidentifikasi URL YouTube dan Mega
|
| 7 |
+
const ytIdRegex = /(?:http(?:s|):\/\/|)(?:(?:www\.|)?youtube(?:\-nocookie|)\.com\/(?:shorts\/)?(?:watch\?.*(?:|\&)v=|embed\/|v\/)?|youtu\.be\/)([-_0-9A-Za-z]{11})/;
|
| 8 |
const megaRegex = /https:\/\/mega\.nz\/file\/[A-Za-z0-9]+#[A-Za-z0-9-_]+/;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
+
// Fungsi untuk melakukan HTTP POST request
|
| 11 |
+
const post = async (url, form, headers = {}) => {
|
| 12 |
+
const response = await fetch(url, {
|
| 13 |
+
method: 'post',
|
| 14 |
+
body: new URLSearchParams(form),
|
| 15 |
+
headers
|
| 16 |
+
});
|
| 17 |
+
return response;
|
| 18 |
+
};
|
| 19 |
+
|
| 20 |
+
// Fungsi untuk mengkonversi video dari YouTube
|
| 21 |
const convert = async (url, v_id, ftype, fquality, fname, token, timeExpire) => {
|
| 22 |
+
let params = {
|
| 23 |
+
v_id,
|
| 24 |
+
ftype,
|
| 25 |
+
fquality,
|
| 26 |
+
fname,
|
| 27 |
+
token,
|
| 28 |
+
timeExpire,
|
| 29 |
+
client: 'yt5s.com'
|
| 30 |
+
};
|
| 31 |
+
|
| 32 |
+
// Mengirim permintaan konversi
|
| 33 |
+
let resServer = await (await post(url, params, { 'x-requested-key': 'de0cfuirtgf67a' })).json();
|
| 34 |
+
let server = resServer.c_server;
|
| 35 |
+
|
| 36 |
+
// Jika tidak ada server dan tipe file adalah mp3, kembalikan null
|
| 37 |
+
if (!server && ftype === 'mp3') return server || resServer.d_url || '';
|
| 38 |
+
|
| 39 |
+
// Mengambil data hasil konversi
|
| 40 |
+
let data = await (await post(`${server}/api/json/convert`, params)).json();
|
| 41 |
+
let result;
|
| 42 |
+
|
| 43 |
+
// Memeriksa status kode hasil konversi
|
| 44 |
+
if (data.statusCode === 200) result = data.result;
|
| 45 |
+
while (!result) {
|
| 46 |
+
let json = await (await post(`${server}/api/json/convert`, params)).json();
|
| 47 |
+
if (json.statusCode === 200) {
|
| 48 |
+
result = json.result;
|
| 49 |
+
break;
|
| 50 |
+
}
|
| 51 |
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
| 52 |
+
}
|
| 53 |
+
return result;
|
| 54 |
+
};
|
| 55 |
|
| 56 |
+
// Fungsi untuk mendownload video dari YouTube
|
| 57 |
const youtubedl = async (url) => {
|
| 58 |
+
let html = await (await fetch('https://yt5s.com/en32')).text();
|
| 59 |
+
let urlAjax = (html.match(/k_url_search="(.*?)"/) || [])[1];
|
| 60 |
+
let urlConvert = (html.match(/k_url_convert="(.*?)"/) || [])[1];
|
| 61 |
+
let json = await (await post(urlAjax, { q: url, vt: 'home' })).json();
|
| 62 |
+
let video = {}, audio = {};
|
| 63 |
+
if (!json?.links) throw json.mess;
|
| 64 |
+
Object.values(json.links.mp4).map(({ k, size }) => video[k] = {
|
| 65 |
+
quality: k,
|
| 66 |
+
fileSizeH: size,
|
| 67 |
+
fileSize: parseFloat(size) * (/MB$/.test(size) ? 1000 : 1),
|
| 68 |
+
download: convert.bind(null, urlConvert, json.vid, 'mp4', k, json.fn, json.token, parseInt(json.timeExpires))
|
| 69 |
+
});
|
| 70 |
+
|
| 71 |
+
Object.values(json.links.mp3).map(({ key, size }) => audio[key] = {
|
| 72 |
+
quality: key,
|
| 73 |
+
fileSizeH: size,
|
| 74 |
+
fileSize: parseFloat(size) * (/MB$/.test(size) ? 1000 : 1),
|
| 75 |
+
download: convert.bind(null, urlConvert, json.vid, 'mp3', key.replace(/kbps/i, ''), json.fn, json.token, parseInt(json.timeExpires))
|
| 76 |
+
});
|
| 77 |
+
|
| 78 |
+
return {
|
| 79 |
+
id: json.vid,
|
| 80 |
+
title: json.title,
|
| 81 |
+
thumbnail: `https://i.ytimg.com/vi/${json.vid}/0.jpg`,
|
| 82 |
+
video,
|
| 83 |
+
audio
|
| 84 |
+
};
|
| 85 |
+
};
|
| 86 |
|
| 87 |
const app = express()
|
| 88 |
+
.set('json spaces', 4)
|
| 89 |
+
.use(morgan('dev'))
|
| 90 |
+
.use(express.json())
|
| 91 |
+
.all('/', (_, res) => res.send('Hello World'))
|
| 92 |
+
.get('/yt', async (req, res) => {
|
| 93 |
+
const host = 'https://' + req.get('host');
|
| 94 |
+
try {
|
| 95 |
+
let { url, type, quality, json } = req.query;
|
| 96 |
+
if (!ytIdRegex.test(url)) return res.json({ message: 'Invalid URL' });
|
| 97 |
+
if (!!json) {
|
| 98 |
+
let ytId = ytIdRegex.exec(url)?.[1];
|
| 99 |
+
if (!ytId) return res.json({ message: 'No video id found' });
|
| 100 |
+
let data = await yts({ videoId: ytId });
|
| 101 |
+
return res.json({
|
| 102 |
+
...data,
|
| 103 |
+
download: {
|
| 104 |
+
audio: `${host}/yt?url=${url}&type=audio&quality=`,
|
| 105 |
+
video: `${host}/yt?url=${url}&type=video&quality=`,
|
| 106 |
+
}
|
| 107 |
+
});
|
| 108 |
+
}
|
| 109 |
+
if (!type || !/audio|video/i.test(type)) type = 'video';
|
| 110 |
+
let data = await youtubedl(url).catch(e => console.log(e));
|
| 111 |
+
if (!data) return res.json({ message: 'Error: link download not found' });
|
| 112 |
+
type = type.toLowerCase();
|
| 113 |
+
let result = quality ? Object.values(data[type]).find(x => x.quality == quality) : Object.values(data[type])[0];
|
| 114 |
+
if (quality && !result) return res.json({ message: `Invalid quality: ${quality}, available quality (${Object.keys(data[type]).join('/')})` });
|
| 115 |
+
if (!result) return res.json({ message: 'Error: can\'t download' });
|
| 116 |
+
res.redirect(await result.download());
|
| 117 |
+
} catch (e) {
|
| 118 |
+
console.log(e);
|
| 119 |
+
res.json({ message: e });
|
| 120 |
+
}
|
| 121 |
+
})
|
| 122 |
+
.get('/search', async (req, res) => {
|
| 123 |
+
try {
|
| 124 |
+
let q = req.query.q || req.query.query;
|
| 125 |
+
if (!q) return res.json({ message: 'Input parameter q' });
|
| 126 |
+
let data = await yts(q);
|
| 127 |
+
if (!data.all[0]) return res.json({ message: 'Not found' });
|
| 128 |
+
res.json(data.all);
|
| 129 |
+
} catch (e) {
|
| 130 |
+
console.log(e);
|
| 131 |
+
res.json({ message: e });
|
| 132 |
+
}
|
| 133 |
})
|
| 134 |
.get('/megajs', async (req, res) => {
|
| 135 |
+
try {
|
| 136 |
+
let { url } = req.query;
|
| 137 |
+
url = url.replace('#', '%23');
|
| 138 |
+
if (!megaRegex.test(url)) return res.json({ message: 'Invalid URL' });
|
| 139 |
|
| 140 |
+
const file = File.fromURL(url);
|
| 141 |
+
await file.loadAttributes();
|
| 142 |
|
| 143 |
+
const data = await file.downloadBuffer();
|
| 144 |
+
res.json({
|
| 145 |
+
name: file.name, // file name
|
| 146 |
+
size: file.size, // file size in bytes
|
| 147 |
+
contents: data.toString() // file contents
|
| 148 |
+
});
|
| 149 |
+
} catch (error) {
|
| 150 |
+
console.error(error);
|
| 151 |
+
res.json({ message: error.message });
|
| 152 |
+
}
|
| 153 |
+
})
|
| 154 |
+
.listen(7860, () => console.log('App running on port 7860'));
|