Download Yt ( no thumbnail )

JavaScriptPublic
by zx-apiJul 24, 2026, 03:52 PMExpires: Never266 views
Download Yt ( no thumbnail )
Raw
1/**
2 *
3 * By Zx
4 * Source Kode:
5 * https://whatsapp.com/channel/0029Vb6P2e1E50UZYaX4wI0W
6 * Note: Kalau Mau Sher Lagi Pake Credit 
7 *
8**/
9
10const axios = require('axios');
11
12class Ytmp3Scraper {
13    constructor() {
14        this.baseUrl = 'https://a.ymcdn.org/api/v1';
15        this.headers = {
16            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
17            'Accept': 'application/json, text/plain, */*',
18            'Referer': 'https://id.ytmp3.mobi/'
19        };
20    }
21
22    extractVideoId(url) {
23        let match;
24        if (url.includes('youtube.com/shorts/') || url.includes('youtu.be/')) {
25            match = /\/([a-zA-Z0-9\-_]{11})/.exec(url);
26        } else if (url.includes('youtube.com')) {
27            match = /v=([a-zA-Z0-9\-_]{11})/.exec(url);
28        }
29        return match ? match[1] : null;
30    }
31
32    async init() {
33        const url = `${this.baseUrl}/init?p=y&23=1llum1n471&_=${Math.random()}`;
34        const response = await axios.get(url, { headers: this.headers });
35        return response.data;
36    }
37
38    async convert(convertURL, videoId, format) {
39        const url = `${convertURL}&v=${videoId}&f=${format}&_=${Math.random()}`;
40        const response = await axios.get(url, { headers: this.headers });
41        return response.data;
42    }
43
44    async checkProgress(progressURL, maxRetries = 60) {
45        let retries = 0;
46        let lastResponse = null;
47
48        while (retries < maxRetries) {
49            const response = await axios.get(progressURL, { headers: this.headers });
50            lastResponse = response.data;
51
52            if (lastResponse.error !== 0) {
53                throw new Error(`Progress Error Code: ${lastResponse.error}`);
54            }
55
56            if (lastResponse.progress === 3) {
57                return lastResponse;
58            }
59
60            await new Promise(resolve => setTimeout(resolve, 1000));
61            retries++;
62        }
63        throw new Error('Timeout: Konversi memakan waktu terlalu lama.');
64    }
65
66    async scrape(youtubeUrl, format = 'mp3') {
67        const startTime = Date.now();
68
69        try {
70            if (!['mp3', 'mp4'].includes(format)) {
71                return {
72                    success: false,
73                    error: 'FORMAT_INVALID',
74                    message: 'Format tidak valid. Gunakan "mp3" atau "mp4".'
75                };
76            }
77
78            const videoId = this.extractVideoId(youtubeUrl);
79            if (!videoId) {
80                return {
81                    success: false,
82                    error: 'INVALID_URL',
83                    message: 'URL YouTube tidak valid atau Video ID tidak ditemukan.'
84                };
85            }
86
87            const initResponse = await this.init();
88            if (initResponse.error !== 0) {
89                return {
90                    success: false,
91                    error: 'INIT_FAILED',
92                    message: `Gagal inisialisasi. Error code: ${initResponse.error}`,
93                    raw: { init: initResponse }
94                };
95            }
96
97            const convertResponse = await this.convert(initResponse.convertURL, videoId, format);
98            if (convertResponse.error !== 0) {
99                return {
100                    success: false,
101                    error: 'CONVERT_FAILED',
102                    message: `Gagal memulai konversi. Error code: ${convertResponse.error}`,
103                    raw: { init: initResponse, convert: convertResponse }
104                };
105            }
106
107            const progressResponse = await this.checkProgress(convertResponse.progressURL);
108
109            const result = {
110                success: true,
111                videoId: videoId,
112                title: convertResponse.title,
113                format: format,
114                hash: convertResponse.hash,
115                downloadUrl: convertResponse.downloadURL,
116                duration: `${((Date.now() - startTime) / 1000).toFixed(2)}s`,
117                metadata: {
118                    country: initResponse.country,
119                    convertURL: initResponse.convertURL,
120                    progressURL: convertResponse.progressURL,
121                    redirectURL: convertResponse.redirectURL || null,
122                    finalProgress: progressResponse
123                }
124            };
125
126            return result;
127
128        } catch (error) {
129            return {
130                success: false,
131                error: 'EXCEPTION',
132                message: error.message,
133                stack: error.stack
134            };
135        }
136    }
137}
138
139// ================= CARA SANGE =================
140/*(async () => {
141    const scraper = new Ytmp3Scraper();
142
143    const targetUrl = 'https://www.youtube.com/shorts/E0GhF4b_zVU';
144    const targetFormat = 'mp4'; // atau 'mp3'
145
146    console.log(`[*] Scraping: ${targetUrl} (format: ${targetFormat})\n`);
147
148    const result = await scraper.scrape(targetUrl, targetFormat);
149
150    console.log(JSON.stringify(result, null, 2));
151})();
152
153CONTOH SEL PUTIH
154{
155  "success": true,
156  "videoId": "E0GhF4b_zVU",
157  "title": "TUAN CRAB SEBENARNYA ANGKATAN LAUT #shorts",
158  "format": "mp4",
159  "hash": "4b9b719a55e6409c38cb15d9f860fe48",
160  "downloadUrl": "https://ydl.ymcdn.org/api/v1/download/4b9b719a55e6409c38cb15d9f860fe48/E0GhF4b_zVU",
161  "duration": "5.23s",
162  "metadata": {
163    "country": "ID",
164    "convertURL": "https://a.ymcdn.org/api/v1/convert?sig=A6LRGZXZNvKyCCMUvIgoxphXDNupPE3PhyDJfrgyUgqLN3wkhjCHkvIISFTp8fLW8l6TcmNi",
165    "progressURL": "https://a.ymcdn.org/api/v1/progress?id=4b9b719a55e6409c38cb15d9f860fe48",
166    "redirectURL": null,
167    "finalProgress": {
168      "sid": 7,
169      "error": 0,
170      "progress": 3,
171      "percent": 0,
172      "title": "TUAN CRAB SEBENARNYA ANGKATAN LAUT #shorts"
173    }
174  }
175}
176*/
176 lines·5,980 chars·5.8 KB