File size: 6,171 Bytes
8c38b3e
 
 
 
9198234
8c38b3e
 
b34c222
9198234
8c38b3e
 
 
 
 
 
 
 
 
 
 
9198234
8c38b3e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9198234
8c38b3e
9198234
8c38b3e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9198234
 
8c38b3e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e802f17
 
fde7417
 
 
 
b34c222
fde7417
 
e802f17
3c604d8
 
fde7417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3c604d8
8c38b3e
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
155
156
157
158
159
160
161
162
const yts = require('yt-search');
const morgan = require('morgan');
const express = require('express');
const { File } = require('megajs');

// Regex untuk mengidentifikasi URL YouTube dan Mega
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-_]+))?/;

// Fungsi untuk melakukan HTTP POST request
const post = async (url, form, headers = {}) => {
    const response = await fetch(url, {
        method: 'post',
        body: new URLSearchParams(form),
        headers
    });
    return response;
};

// Fungsi untuk mengkonversi video dari YouTube
const convert = async (url, v_id, ftype, fquality, fname, token, timeExpire) => {
    let params = {
        v_id,
        ftype,
        fquality,
        fname,
        token,
        timeExpire,
        client: 'yt5s.com'
    };

    // Mengirim permintaan konversi
    let resServer = await (await post(url, params, { 'x-requested-key': 'de0cfuirtgf67a' })).json();
    let server = resServer.c_server;

    // Jika tidak ada server dan tipe file adalah mp3, kembalikan null
    if (!server && ftype === 'mp3') return server || resServer.d_url || '';

    // Mengambil data hasil konversi
    let data = await (await post(`${server}/api/json/convert`, params)).json();
    let result;

    // Memeriksa status kode hasil konversi
    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;
};

// Fungsi untuk mendownload video dari YouTube
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;
        const match = url.match(megaRegex);
        if (!match) return res.json({ message: 'Invalid URL' });

        const id = match[1];
        const query = match[2] || ''; // Jika tidak ada query, gunakan string kosong

        // If there's a query, add a hash symbol to the URL
        const fileURL = query ? `https://mega.nz/file/${id}#${query}` : `https://mega.nz/file/${id}`;

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

        const data = await file.downloadBuffer();
        res.json({
            name: file.name, // Nama file
            size: file.size, // Ukuran file dalam byte
            contents: data.toString() // Konten file dalam format string
        });
    } catch (error) {
        console.error(error);
        res.json({ message: error.message });
    }
})

    .listen(7860, () => console.log('App running on port 7860'));