/** * Ytmp3 * base: https://id.ytmp3.mobi/v1/ * Creator: ShanMolvyr * Jangan Hapus Kreator hargai rakyat kecil * Note: cek https://snippet.vyr.my.id/shanmolvyr/ytmp3/README.md * Sumber: https://whatsapp.com/channel/0029VbB4Kw8EFeXfeExaXc3Q */ const BASE = "https://a.ymcdn.org/api/v1"; const rand = () => Math.random(); const BASE_HEADERS = { "User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36", "Referer": "https://id.ytmp3.mobi/", "Origin": "https://id.ytmp3.mobi", "Accept": "*/*", "Accept-Language": "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7", "Cache-Control": "no-cache", "Pragma": "no-cache", }; function extractVideoId(input) { const patterns = [ /(?:v=|youtu\.be\/|embed\/|shorts\/)([A-Za-z0-9_-]{11})/, /^([A-Za-z0-9_-]{11})$/, ]; for (const p of patterns) { const m = input.match(p); if (m) return m[1]; } throw new Error("Invalid YouTube URL or video ID: " + input); } function extractCookie(res, existing = "") { const setCookie = res.headers.get("set-cookie"); if (!setCookie) return existing; const newCookie = setCookie.split(";")[0]; if (!existing) return newCookie; const key = newCookie.split("=")[0]; const parts = existing.split("; ").filter(p => !p.startsWith(key + "=")); parts.push(newCookie); return parts.join("; "); } async function init() { const res = await fetch(`${BASE}/init?p=y&23=1llum1n471&_=${rand()}`, { headers: BASE_HEADERS }); const cookie = extractCookie(res); const data = await res.json(); if (data.error !== 0) throw new Error("Init failed: " + JSON.stringify(data)); return { convertURL: data.convertURL, cookie }; } async function convert(convertURL, videoId, format, cookie) { const res = await fetch(`${convertURL}&v=${videoId}&f=${format}&_=${rand()}`, { headers: { ...BASE_HEADERS, ...(cookie ? { Cookie: cookie } : {}) }, }); const data = await res.json(); if (data.error !== 0) throw new Error("Convert failed: " + JSON.stringify(data)); return data; } export async function ytmp3(youtubeUrl, format = "mp3") { const videoId = extractVideoId(youtubeUrl); const { convertURL, cookie } = await init(); const { title, downloadURL, hash } = await convert(convertURL, videoId, format, cookie); return { title, downloadURL, format, videoId, hash }; } // ─── CLI ───────────────────────────────────────────────────────────────────── const args = process.argv.slice(2); const url = args[0] || "https://www.youtube.com/watch?v=kffacxfA7G4"; const format = args[1] || "mp3"; process.stderr.write(`[ytmp3] Converting: ${url} → ${format}\n`); try { const result = await ytmp3(url, format); console.log(JSON.stringify(result, null, 2)); } catch (err) { console.log(JSON.stringify({ error: err.message }, null, 2)); process.exit(1); }