hasil data : judul, artis, sampul, audio, ukuran
No comments yet. Be the first to comment!
1/**
2 * Soundclouds Downloader
3 * Base : https://downcloudme.com
4 * Author : Gienetic
5 * Request : knz
6 */
7
8import fs from 'fs';
9
10const sandi = "b4f28fefc8";
11const markas = "https://downcloudme.com/download-track";
12const pantau = "https://www.scloudme.com/dl/status/";
13const meta = "https://soundcloud.com/oembed";
14const agen = "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36 AlohaBrowser/8.8.0 (Gienetic)";
15
16const argumen = process.argv.slice(2);
17const target = argumen.find(a => a.includes("soundcloud.com/"));
18
19const jeda = (ms) => new Promise(r => setTimeout(r, ms));
20
21const bersih = (teks) => teks.replace(/[<>:"/\\|?*]+/g, "_").replace(/\s+/g, " ").trim();
22
23const lacak = (teks) => {
24 const m = teks.match(/const jobId\s*=\s*"([^"]+)"/);
25 return m ? m[1] : null;
26};
27
28const namai = (teks) => {
29 const m = teks.match(/const fileName\s*=\s*"([^"]+)"/);
30 return m ? m[1] : "unduhan.mp3";
31};
32
33const intai = async (url) => {
34 try {
35 const balasan = await fetch(`${meta}?url=${encodeURIComponent(url)}&format=json`);
36 if (!balasan.ok) return null;
37 const data = await balasan.json();
38 return {
39 judul: data.title || null,
40 artis: data.author_name || null,
41 sampul: data.thumbnail_url || null
42 };
43 } catch {
44 return null;
45 }
46};
47
48const tembak = async (url) => {
49 const muatan = new URLSearchParams();
50 muatan.append("url", url);
51 muatan.append("downloader_verify", sandi);
52
53 const balasan = await fetch(markas, {
54 method: "POST",
55 headers: {
56 "content-type": "application/x-www-form-urlencoded",
57 "origin": "https://downcloudme.com",
58 "referer": "https://downcloudme.com/enTc/",
59 "user-agent": agen
60 },
61 body: muatan.toString()
62 });
63
64 const teks = await balasan.text();
65 const id = lacak(teks);
66 const nama = namai(teks);
67
68 if (!id) throw new Error("Gagal");
69 return { id, nama };
70};
71
72const tunggu = async (id) => {
73 for (let i = 0; i < 120; i++) {
74 await jeda(1000);
75 const balasan = await fetch(pantau + id, {
76 headers: {
77 "origin": "https://downcloudme.com",
78 "user-agent": agen,
79 "x-requested-with": "AlohaBrowser"
80 }
81 });
82
83 if (balasan.status !== 200) continue;
84
85 const data = await balasan.json();
86 if (data.api2?.rapid_url) return data.api2.rapid_url;
87 if (data.api2?.error) {
88 if (data.api1?.download_link) return data.api1.download_link;
89 throw new Error(data.api2.error);
90 }
91 }
92 throw new Error("Batas");
93};
94
95const sedot = async (url, tujuan) => {
96 const balasan = await fetch(url);
97 if (!balasan.ok) throw new Error("Gagal");
98
99 const kepingan = [];
100 const pembaca = balasan.body.getReader();
101
102 while (true) {
103 const { done, value } = await pembaca.read();
104 if (done) break;
105 kepingan.push(value);
106 }
107
108 const utuh = Buffer.concat(kepingan);
109 fs.writeFileSync(tujuan, utuh);
110 return utuh.length;
111};
112
113const sikat = async (url) => {
114 if (!url) {
115 console.error(JSON.stringify({ status: false, galat: "Nihil" }, null, 2));
116 return;
117 }
118
119 try {
120 const hasil = { status: false, target: url, info: null, audio: null, ukuran: 0 };
121 const info = await intai(url);
122 if (info) hasil.info = info;
123
124 const { id, nama } = await tembak(url);
125 const tautan = await tunggu(id);
126
127 let berkas = bersih(nama);
128 if (info && info.artis && info.judul) {
129 let tajuk = info.judul;
130 if (tajuk.endsWith(` by ${info.artis}`)) {
131 tajuk = tajuk.slice(0, -(4 + info.artis.length));
132 }
133 berkas = bersih(`${info.artis} - ${tajuk}.mp3`);
134 }
135
136 const ukuran = await sedot(tautan, berkas);
137 hasil.audio = berkas;
138 hasil.ukuran = ukuran;
139
140 if (info && info.sampul) {
141 const murni = info.sampul.replace("-t500x500", "-original");
142 const wajah = berkas.replace(/\.mp3$/i, ".jpg");
143 try {
144 const u = await sedot(murni, wajah);
145 hasil.sampul = { file: wajah, ukuran: u };
146 } catch {
147 try {
148 const u = await sedot(info.sampul, wajah);
149 hasil.sampul = { file: wajah, ukuran: u };
150 } catch {}
151 }
152 }
153
154 hasil.status = true;
155 console.log(JSON.stringify(hasil, null, 2));
156 } catch (e) {
157 console.error(JSON.stringify({ status: false, galat: e.message }, null, 2));
158 }
159};
160
161export { sikat };
162
163if (argumen.length > 0) {
164 sikat(target);
165}
166
167//node namafile.js "https://soundcloud.com/themarias/no-one-noticed"