Ytconvert
downloader ytmp4 mp3
6 Juni 20261402 file
ytconvert.jsjavascript · 101 baris
/** * Ytconvert download mp4/mp3 * base: https://ytconvert.org/ * Creator: ShanMolvyr * * * Note: cek https://gist.vyr.my.id/shanmolvyr/ytconvert/README.md * Sumber: https://whatsapp.com/channel/0029VbB4Kw8EFeXfeExaXc3Q */const BASE = 'https://ytdl.y2mp3.co/api';const H = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'User-Agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Mobile Safari/537.36', 'Referer': 'https://ytconvert.org/',};function extractId(url) { const m = url.match(/(?:youtu\.be\/|v=|embed\/|shorts\/)([A-Za-z0-9_-]{11})/); if (m) return m[1]; if (/^[A-Za-z0-9_-]{11}$/.test(url)) return url; throw new Error('Invalid YouTube URL');}async function getInfo(url) { const r = await fetch(`https://www.youtube.com/oembed?url=${encodeURIComponent(url)}&format=json`); if (!r.ok) throw new Error(`oEmbed ${r.status}`); const d = await r.json(); return { title: d.title, author: d.author_name, thumbnail: d.thumbnail_url };}async function submit(url, type, format, quality) { const r = await fetch(`${BASE}/v2/download`, { method: 'POST', headers: H, body: JSON.stringify({ url, output: { type, format, quality } }), }); if (!r.ok) throw new Error(`Submit ${r.status}`); const d = await r.json(); if (!d.statusUrl) throw new Error('No statusUrl'); return d;}async function poll(statusUrl, interval = 3000, timeout = 120000) { const deadline = Date.now() + timeout; while (Date.now() < deadline) { const r = await fetch(statusUrl, { headers: H }); if (!r.ok) throw new Error(`Poll ${r.status}`); const d = await r.json(); if (d.status === 'completed') return d; if (d.status === 'error' || d.status === 'failed') throw new Error(`Job ${d.status}`); process.stderr.write(`\r [${d.status}] ${d.progress ?? 0}% `); await new Promise(res => setTimeout(res, interval)); } throw new Error('Timeout');}async function run(url, format, quality) { const isAudio = format === 'mp3'; const type = isAudio ? 'audio' : 'video'; const q = quality || (isAudio ? '320' : '2160p'); const [info, job] = await Promise.all([ getInfo(url), submit(url, type, format, q), ]); const result = await poll(job.statusUrl); process.stderr.write('\n'); return { title: info.title, author: info.author, thumbnail: info.thumbnail, format, requested_quality: q, selected_quality: job.selectedQuality ?? result.selectedQuality, quality_changed: job.qualityChanged ?? false, quality_change_reason: job.qualityChangeReason ?? null, duration: result.duration, download_url: result.downloadUrl, };}if (require.main === module) { const [,, url, format = 'mp4', quality] = process.argv; if (!url) { console.error('Usage: node ytconvert.js <url> [mp4|mp3] [quality]'); console.error(' node ytconvert.js https://youtu.be/xxx'); console.error(' node ytconvert.js https://youtu.be/xxx mp4 720p'); console.error(' node ytconvert.js https://youtu.be/xxx mp3 128'); process.exit(1); } run(url, format, quality) .then(r => console.log(JSON.stringify(r, null, 2))) .catch(e => { console.error(e.message); process.exit(1); });}module.exports = { extractId, getInfo, submit, poll, run };README.mdmarkdown · 17 baris
Cara Pakai
* node ytconvert.js https://youtu.be/xxx
* node ytconvert.js https://youtu.be/xxx mp4
* node ytconvert.js https://youtu.be/xxx mp4 1080p
* node ytconvert.js https://youtu.be/xxx mp3
* node ytconvert.js https://youtu.be/xxx mp3 128
Quality yang tersedia
* MP4: 360p 480p 720p 1080p 1440p 2160p
* MP3: 128 192 256 320
Komentar
Masuk untuk ikut berkomentar.
Belum ada komentar.