loaderto
YouTube video dan music downloader support 4k(WEBM)
20 Juni 2026862 file
loaderto.jsjavascript · 119 baris
const BASE = "https://p.savenow.to";const DEFAULT_APIKEY = "dfcb6d76f2f6a9894gjkege8a4ab232222";const REFERER = "https://en.loader.to/";const FORMATS = ["mp3", "m4a", "webm", "aac", "flac", "opus", "ogg", "wav", "144", "240", "360", "480", "720", "1080", "1440", "4k"];const baseHeaders = { "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", "Referer": REFERER};function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms));}async function health() { try { await fetch(`${BASE}/api/health`, { method: "HEAD", headers: baseHeaders }); } catch (_) {}}async function requestDownload(sourceUrl, format, apikey, addInfo) { const params = new URLSearchParams({ format, url: sourceUrl, apikey }); if (addInfo) params.set("add_info", "1"); const res = await fetch(`${BASE}/api/v2/download?${params.toString()}`, { headers: baseHeaders }); const data = await res.json(); if (!data.success) throw new Error(data.error || "permintaan download ditolak oleh server"); return data;}async function checkProgress(id) { const res = await fetch(`${BASE}/api/progress?id=${encodeURIComponent(id)}&_=${Date.now()}`, { headers: baseHeaders }); return res.json();}function isFailureStatus(progress) { if (progress.error) return true; const text = (progress.text || "").toLowerCase(); return text.includes("fail") || text.includes("error") || text.includes("gagal");}async function waitForResult(id, { intervalMs = 1500, maxAttempts = 60 } = {}) { for (let attempt = 0; attempt < maxAttempts; attempt++) { const progress = await checkProgress(id); if (progress.download_url) return progress; if (isFailureStatus(progress)) throw new Error(progress.text || progress.error || "proses download gagal"); await sleep(intervalMs); } throw new Error("timeout menunggu hasil download");}async function probe(url) { try { const res = await fetch(url, { method: "HEAD", headers: { Referer: REFERER } }); return { ok: res.ok, status: res.status, contentType: res.headers.get("content-type") || null, contentLength: res.headers.get("content-length") ? Number(res.headers.get("content-length")) : null }; } catch (_) { return null; }}async function download(sourceUrl, format, options = {}) { if (!sourceUrl) throw new Error("url wajib diisi"); if (!FORMATS.includes(format)) throw new Error(`format tidak dikenal, pilih salah satu: ${FORMATS.join(", ")}`); const apikey = options.apikey || DEFAULT_APIKEY; const addInfo = options.addInfo !== false; await health(); const initial = await requestDownload(sourceUrl, format, apikey, addInfo); let final = initial; if (!initial.url && !initial.download_url) { final = await waitForResult(initial.id, options); } const downloadUrl = final.download_url || final.url || initial.url; const fileInfo = options.probe === false ? null : await probe(downloadUrl); return { tool: "loaderto-wrapper by ShanMolvyr", success: true, sourceUrl, format, id: initial.id, title: initial.info ? initial.info.title || null : null, thumbnail: initial.info ? initial.info.image || null : null, downloadUrl, filename: final.filename || null, expiresIn: final.expires_in || null, file: fileInfo };}async function main() { const [sourceUrl, format = "mp3", apikey] = process.argv.slice(2); try { const result = await download(sourceUrl, format, { apikey }); console.log(JSON.stringify(result, null, 2)); } catch (err) { console.log(JSON.stringify({ tool: "loaderto-wrapper by ShanMolvyr", success: false, error: err.message }, null, 2)); process.exitCode = 1; }}if (require.main === module) { main();}module.exports = { download, FORMATS };README.mdmarkdown · 20 baris
Cara Pakai
node loaderto.js https://youtu.be/xxxx <format>
node loaderto.js https://youtu.be/xxxx <format>
📥 Available Formats
Komentar
Masuk untuk ikut berkomentar.
Belum ada komentar.