media-dl 2.3.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +64 -23
- package/package.json +28 -11
- package/readme.md +54 -58
- package/.gppignore +0 -12
package/bin/cli.js
CHANGED
|
@@ -217,6 +217,28 @@ function runSpawn(command, args) {
|
|
|
217
217
|
});
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
+
async function getEstimate(url, format) {
|
|
221
|
+
try {
|
|
222
|
+
const sizeStr = execSync(
|
|
223
|
+
`"${YTDLP_PATH}" --print "%(filesize_approx,filesize)s" -f "${format}" --no-warnings "${url}"`,
|
|
224
|
+
{
|
|
225
|
+
encoding: 'utf-8',
|
|
226
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
227
|
+
timeout: 10000,
|
|
228
|
+
},
|
|
229
|
+
).trim();
|
|
230
|
+
|
|
231
|
+
if (sizeStr && sizeStr !== 'NA') {
|
|
232
|
+
const bytes = parseInt(sizeStr);
|
|
233
|
+
if (isNaN(bytes)) return 'N/A';
|
|
234
|
+
if (bytes > 1024 * 1024 * 1024)
|
|
235
|
+
return (bytes / 1024 ** 3).toFixed(2) + ' GB';
|
|
236
|
+
return (bytes / 1024 ** 2).toFixed(2) + ' MB';
|
|
237
|
+
}
|
|
238
|
+
} catch (e) {}
|
|
239
|
+
return 'Estimasi tidak tersedia';
|
|
240
|
+
}
|
|
241
|
+
|
|
220
242
|
// --- DOWNLOAD ENGINE ---
|
|
221
243
|
async function startDownload(videoURLFromArgs = null) {
|
|
222
244
|
let { ytExists, ffExists } = checkTools();
|
|
@@ -260,7 +282,6 @@ async function startDownload(videoURLFromArgs = null) {
|
|
|
260
282
|
}
|
|
261
283
|
} catch (e) {
|
|
262
284
|
console.log(`\n${C.red}❌ Gagal menganalisa tautan.${C.reset}`);
|
|
263
|
-
|
|
264
285
|
if (e.message.includes('ETIMEDOUT')) {
|
|
265
286
|
console.log(
|
|
266
287
|
`${C.yellow}⚠️ Waktu analisa habis. Periksa koneksi internet Anda.${C.reset}`,
|
|
@@ -270,13 +291,14 @@ async function startDownload(videoURLFromArgs = null) {
|
|
|
270
291
|
`${C.yellow}⚠️ Pastikan link valid atau tidak diprivat/dihapus.${C.reset}`,
|
|
271
292
|
);
|
|
272
293
|
}
|
|
273
|
-
|
|
274
294
|
await askQuestion('\nTekan Enter untuk kembali ke menu...');
|
|
275
|
-
return mainMenu();
|
|
295
|
+
return mainMenu();
|
|
276
296
|
}
|
|
277
297
|
|
|
298
|
+
// --- PEMILIHAN PLAYLIST (Tetap Sama) ---
|
|
278
299
|
let playlistSelection = null;
|
|
279
300
|
if (playlistInfo.isPlaylist) {
|
|
301
|
+
// ... (Logika tampilan playlist sama seperti sebelumnya)
|
|
280
302
|
console.log(
|
|
281
303
|
`\n${C.bgBlue}${C.bright} 📂 PLAYLIST TERDETEKSI: ${playlistInfo.title} ${C.reset}`,
|
|
282
304
|
);
|
|
@@ -288,10 +310,9 @@ async function startDownload(videoURLFromArgs = null) {
|
|
|
288
310
|
console.log(
|
|
289
311
|
`\n${C.dim}Contoh pilih nomor: 1,3,5-10 atau biarkan kosong untuk semua.${C.reset}`,
|
|
290
312
|
);
|
|
291
|
-
const selectionInput = await askQuestion('
|
|
292
|
-
|
|
293
|
-
// Parsing nomor playlist
|
|
313
|
+
const selectionInput = await askQuestion('\nPilih nomor: ');
|
|
294
314
|
if (selectionInput) {
|
|
315
|
+
// ... (Logika parsing nomor playlist)
|
|
295
316
|
const selected = new Set();
|
|
296
317
|
selectionInput.split(',').forEach((p) => {
|
|
297
318
|
if (p.includes('-')) {
|
|
@@ -307,15 +328,42 @@ async function startDownload(videoURLFromArgs = null) {
|
|
|
307
328
|
}
|
|
308
329
|
}
|
|
309
330
|
|
|
331
|
+
// --- MENU FORMAT UTAMA ---
|
|
310
332
|
console.log(`\n${C.bright} [ PILIH FORMAT ]${C.reset}`);
|
|
311
|
-
console.log(` ${C.green}1.${C.reset} Video (
|
|
312
|
-
console.log(
|
|
313
|
-
` ${C.green}2.${C.reset} Audio Only (MP3) ${
|
|
314
|
-
ffExists ? C.green + '✅' : C.red + '❌ (Butuh FFmpeg)'
|
|
315
|
-
}`,
|
|
316
|
-
);
|
|
333
|
+
console.log(` ${C.green}1.${C.reset} Video (MP4)`);
|
|
334
|
+
console.log(` ${C.green}2.${C.reset} Audio Only (MP3)`);
|
|
317
335
|
const mode = await askQuestion('Pilihan: ');
|
|
318
336
|
|
|
337
|
+
// --- LOGIKA RESOLUSI OPTIMAL ---
|
|
338
|
+
let formatArg = '';
|
|
339
|
+
if (mode === '1') {
|
|
340
|
+
console.log(`\n${C.bright} [ PILIH RESOLUSI ]${C.reset}`);
|
|
341
|
+
console.log(` ${C.cyan}1.${C.reset} Best Quality (Up to 4K)`);
|
|
342
|
+
console.log(` ${C.cyan}2.${C.reset} Tablet Optimal (720p)`);
|
|
343
|
+
console.log(` ${C.cyan}3.${C.reset} Mobile Optimal (480p)`);
|
|
344
|
+
const resChoice = await askQuestion('Pilihan Resolusi (1-3): ');
|
|
345
|
+
|
|
346
|
+
if (resChoice === '2') {
|
|
347
|
+
formatArg =
|
|
348
|
+
'bestvideo[height<=720][vcodec^=avc1]+bestaudio[acodec^=mp4a]/best[height<=720]';
|
|
349
|
+
} else if (resChoice === '3') {
|
|
350
|
+
formatArg =
|
|
351
|
+
'bestvideo[height<=480][vcodec^=avc1]+bestaudio[acodec^=mp4a]/best[height<=480]';
|
|
352
|
+
} else {
|
|
353
|
+
formatArg =
|
|
354
|
+
'bestvideo[vcodec^=avc1]+bestaudio[acodec^=mp4a]/best[vcodec^=avc1]/best';
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// --- TAMPILKAN ESTIMASI ---
|
|
358
|
+
if (!playlistInfo.isPlaylist && mode === '1') {
|
|
359
|
+
console.log(`${C.dim}⏳ Menghitung estimasi ukuran file...${C.reset}`);
|
|
360
|
+
const size = await getEstimate(videoURL, formatArg);
|
|
361
|
+
console.log(`${C.yellow}📊 Estimasi Ukuran: ${C.bright}${size}${C.reset}`);
|
|
362
|
+
|
|
363
|
+
const confirm = await askQuestion('Lanjutkan unduhan? (Y/n): ');
|
|
364
|
+
if (confirm.toLowerCase() === 'n') return mainMenu();
|
|
365
|
+
}
|
|
366
|
+
|
|
319
367
|
const baseDir = path.join(os.homedir(), 'Downloads', 'media-dl');
|
|
320
368
|
const subFolder = mode === '2' ? 'audio' : 'video';
|
|
321
369
|
let outputDir = path.join(baseDir, subFolder);
|
|
@@ -334,7 +382,7 @@ async function startDownload(videoURLFromArgs = null) {
|
|
|
334
382
|
videoURL,
|
|
335
383
|
];
|
|
336
384
|
|
|
337
|
-
// Integrasi Safe Mode
|
|
385
|
+
// Integrasi Safe Mode (cite: cli.js)
|
|
338
386
|
if (safeMode) {
|
|
339
387
|
args.push(
|
|
340
388
|
'--rate-limit',
|
|
@@ -356,27 +404,20 @@ async function startDownload(videoURLFromArgs = null) {
|
|
|
356
404
|
console.log(
|
|
357
405
|
`${C.red}❌ Error: Anda wajib menginstal FFmpeg untuk mengunduh audio.${C.reset}`,
|
|
358
406
|
);
|
|
359
|
-
|
|
360
|
-
mainMenu();
|
|
407
|
+
return mainMenu();
|
|
361
408
|
}
|
|
362
409
|
args.unshift('-x', '--audio-format', 'mp3');
|
|
363
410
|
} else {
|
|
364
|
-
args.unshift(
|
|
365
|
-
'-f',
|
|
366
|
-
'bestvideo[vcodec^=avc1]+bestaudio[acodec^=mp4a]/best[vcodec^=avc1]/best',
|
|
367
|
-
);
|
|
411
|
+
args.unshift('-f', formatArg);
|
|
368
412
|
if (ffExists) args.unshift('--recode-video', 'mp4');
|
|
369
413
|
}
|
|
370
414
|
|
|
371
415
|
args.push('--no-mtime');
|
|
372
|
-
|
|
373
416
|
console.log(`\n${C.bgBlue}${C.bright} 🚀 MEMULAI PROSES... ${C.reset}\n`);
|
|
374
417
|
|
|
375
|
-
const code = await runSpawn(YTDLP_PATH, args);
|
|
376
|
-
|
|
418
|
+
const code = await runSpawn(YTDLP_PATH, args);
|
|
377
419
|
if (code === 0) {
|
|
378
420
|
console.log(`\n${C.green}✨ SELESAI! Cek folder: ${outputDir}${C.reset}`);
|
|
379
|
-
// Auto-open folder
|
|
380
421
|
try {
|
|
381
422
|
execSync(
|
|
382
423
|
isWindows
|
package/package.json
CHANGED
|
@@ -1,30 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "media-dl",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "CLI Downloader video/audio lintas platform menggunakan yt-dlp.",
|
|
5
5
|
"main": "bin/cli.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"media-dl": "bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"README.md",
|
|
12
|
+
"license"
|
|
13
|
+
],
|
|
6
14
|
"scripts": {
|
|
7
15
|
"dev": "npm un -g media-dl && npm i -g . && media-dl",
|
|
8
|
-
"
|
|
16
|
+
"prod": "npm un -g media-dl && npm i -g media-dl@latest && media-dl",
|
|
17
|
+
"start": "node bin/cli.js",
|
|
9
18
|
"release": "npm version patch && npm publish",
|
|
10
19
|
"release:minor": "npm version minor && npm publish",
|
|
11
20
|
"release:major": "npm version major && npm publish"
|
|
12
21
|
},
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
"publishConfig": {
|
|
17
|
-
"access": "public"
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/Ariska138/media-dl.git"
|
|
18
25
|
},
|
|
19
26
|
"keywords": [
|
|
20
27
|
"downloader",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
28
|
+
"video-downloader",
|
|
29
|
+
"youtube-dl",
|
|
30
|
+
"yt-dlp",
|
|
31
|
+
"tiktok-downloader",
|
|
32
|
+
"instagram-downloader",
|
|
33
|
+
"cli",
|
|
34
|
+
"cross-platform"
|
|
24
35
|
],
|
|
25
36
|
"author": "Ariska Hidayat",
|
|
26
37
|
"license": "MIT",
|
|
27
|
-
"
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/Ariska138/media-dl/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/Ariska138/media-dl#readme",
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
28
45
|
"engines": {
|
|
29
46
|
"node": ">=14.0.0"
|
|
30
47
|
}
|
package/readme.md
CHANGED
|
@@ -2,106 +2,102 @@
|
|
|
2
2
|
|
|
3
3
|
**The Ultimate Cross-Platform Media Engine Manager**
|
|
4
4
|
|
|
5
|
-
Media-DL Pro adalah *CLI wrapper* canggih berbasis `yt-dlp` yang dirancang untuk
|
|
5
|
+
Media-DL Pro adalah *CLI wrapper* canggih berbasis `yt-dlp` yang dirancang untuk kecepatan, keteraturan, dan keamanan. Bukan sekadar pengunduh, ini adalah manajer media lokal yang cerdas dengan sistem instalasi otomatis.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## ✨ Fitur Unggulan Baru
|
|
10
10
|
|
|
11
|
-
### 1.
|
|
11
|
+
### 1. ⚡ Direct Download & Menu Mode
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Sekarang kamu bisa memilih dua cara penggunaan:
|
|
14
14
|
|
|
15
|
-
* **
|
|
16
|
-
|
|
15
|
+
* **Interactive Mode**: Cukup ketik `media-dl` untuk masuk ke menu utama yang cantik.
|
|
16
|
+
* **Fast Mode**: Ketik `media-dl <url>` untuk langsung masuk ke proses download tanpa basa-basi.
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
Interval jeda otomatis 3–10 detik antar unduhan.
|
|
18
|
+
### 2. 📱 Android (Termux) Ready
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
Menggunakan identitas browser modern untuk menghindari deteksi bot.
|
|
20
|
+
Dukungan penuh untuk pengguna mobile via Termux dengan script instalasi otomatis yang menyesuaikan lingkungan Linux Android.
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
### 3. 🛡️ Safe Mode Guard™ (Updated)
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
Menghindari deteksi bot dengan:
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
* **Rate Limiting**: Dibatasi hingga 5 MB/s.
|
|
27
|
+
* **Smart Sleep**: Jeda acak 3–10 detik.
|
|
28
|
+
* **Modern User-Agent**: Identitas browser terbaru agar tetap aman.
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
## 🎞️ Platform yang Didukung
|
|
33
|
+
|
|
34
|
+
Berkat engine `yt-dlp` yang selalu diperbarui, kamu bisa mengunduh dari:
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
* **YouTube**: Video, Shorts, & Playlist.
|
|
37
|
+
* **Social Media**: TikTok, Instagram Reels, Twitter (X).
|
|
38
|
+
* **VOD Services**: Dan ratusan platform video lainnya.
|
|
36
39
|
|
|
37
40
|
---
|
|
38
41
|
|
|
39
|
-
|
|
42
|
+
## 📦 Instalasi
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
Konversi cerdas ke kontainer MP4 dengan codec `AVC1` agar kompatibel dengan perangkat seluler dan editor profesional.
|
|
44
|
+
### Prasyarat
|
|
43
45
|
|
|
44
|
-
* **
|
|
45
|
-
Ekstraksi MP3 kualitas tinggi (320 kbps) langsung ke folder musik Anda.
|
|
46
|
+
* **Node.js**: Versi 14.0.0 atau lebih tinggi.
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
## 📦 Instalasi Cepat
|
|
48
|
+
### Cara Install
|
|
50
49
|
|
|
51
50
|
```bash
|
|
52
|
-
# Pastikan Node.js sudah terinstal
|
|
53
51
|
npm install -g media-dl
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Cukup ketik `media-dl` di terminal Anda untuk memulai.
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## 🛠️ Navigasi Sistem
|
|
61
52
|
|
|
62
|
-
|
|
53
|
+
```
|
|
63
54
|
|
|
64
|
-
|
|
65
|
-
Layanan unduh media tunggal atau playlist.
|
|
55
|
+
### Penggunaan
|
|
66
56
|
|
|
67
|
-
|
|
68
|
-
|
|
57
|
+
```bash
|
|
58
|
+
# Buka menu utama
|
|
59
|
+
media-dl
|
|
69
60
|
|
|
70
|
-
|
|
71
|
-
|
|
61
|
+
# Download langsung tanpa menu
|
|
62
|
+
media-dl https://www.youtube.com/watch?v=example
|
|
72
63
|
|
|
73
|
-
|
|
74
|
-
Informasi pengembang dan daftar fitur lengkap.
|
|
64
|
+
```
|
|
75
65
|
|
|
76
66
|
---
|
|
77
67
|
|
|
78
|
-
##
|
|
68
|
+
## 🛠️ Navigasi Sistem
|
|
79
69
|
|
|
80
|
-
|
|
70
|
+
1. **📥 Download Media**: Mendukung pemilihan kualitas (Video/Audio MP3) dan seleksi playlist (misal: `1,3,5-10`).
|
|
71
|
+
2. **🛡️ Toggle Safe Mode**: Aktifkan perlindungan tambahan secara *on-the-fly*.
|
|
72
|
+
3. **⚙️ Maintenance**: Update otomatis `yt-dlp` dan `FFmpeg` langsung dari aplikasi tanpa perlu download manual.
|
|
73
|
+
4. **🗑️ Reset System**: Hapus semua engine untuk instalasi ulang yang bersih.
|
|
81
74
|
|
|
82
|
-
|
|
83
|
-
`~/Downloads/media-dl/video/`
|
|
75
|
+
---
|
|
84
76
|
|
|
85
|
-
|
|
86
|
-
`~/Downloads/media-dl/audio/`
|
|
77
|
+
## 💻 Kompatibilitas Sistem
|
|
87
78
|
|
|
88
|
-
|
|
89
|
-
|
|
79
|
+
| Sistem Operasi | Status | Cara Kerja |
|
|
80
|
+
| --- | --- | --- |
|
|
81
|
+
| **Windows** | ✅ Supported | Auto-download `.exe` ke folder `~/.media-dl` |
|
|
82
|
+
| **macOS** | ✅ Supported | Auto-download via `curl` |
|
|
83
|
+
| **Linux** | ✅ Supported | Integrasi via `apt` (Debian/Ubuntu) |
|
|
84
|
+
| **Termux** | ✅ Supported | Integrasi via `pkg` & `pip` |
|
|
90
85
|
|
|
91
86
|
---
|
|
92
87
|
|
|
93
|
-
##
|
|
88
|
+
## 📂 Struktur Penyimpanan
|
|
94
89
|
|
|
95
|
-
|
|
90
|
+
Unduhan kamu akan tersimpan rapi di:
|
|
96
91
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
| **🍕 Beli Pizza** | [Donasi via Midtrans](https://app.midtrans.com/pizza) |
|
|
92
|
+
* **Video**: `~/Downloads/media-dl/video/`
|
|
93
|
+
* **Audio**: `~/Downloads/media-dl/audio/`
|
|
94
|
+
* **Playlist**: Sub-folder otomatis berdasarkan nama playlist.
|
|
101
95
|
|
|
102
96
|
---
|
|
103
97
|
|
|
104
|
-
##
|
|
98
|
+
## ❤️ Dukungan
|
|
99
|
+
|
|
100
|
+
Aplikasi ini dikembangkan oleh **Ariska Hidayat**. Jika bermanfaat, kamu bisa memberikan dukungan untuk biaya pemeliharaan server/engine:
|
|
105
101
|
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
* **☕ Traktir Kopi**: [Midtrans Coffee](https://app.midtrans.com/coffee)
|
|
103
|
+
* **🍕 Beli Pizza**: [Midtrans Pizza](https://app.midtrans.com/pizza)
|