Skip to main content

Modern downloader CLI with parallel processing, subtitle cleaning, SponsorBlock, chapter splitting, scheduled jobs, and more

Project description

MelT — YouTube Downloader CLI

Download video, audio, and subtitles from YouTube with parallel processing, subtitle cleaning, SponsorBlock, chapter splitting, scheduled downloads, and more. Built on yt-dlp with a polished Rich interface.

pip install meltdl
python -c "import melt"  # or just: melt

Source mode requires ffmpeg in PATH (scoop install ffmpeg / brew install ffmpeg / sudo apt install ffmpeg).


Quick Start

python main.py                        # Interactive mode
python main.py --help                 # Full help reference
python main.py --version              # Show version
python main.py --resume               # Resume interrupted queue
python main.py --profile <name>       # Load a saved profile

Batch commands

Command Description
melt search <query> Search YouTube and download
melt analytics Show download statistics
melt schedule <add/list/remove/daemon> Scheduled downloads
melt rule <add/list/remove> Auto-rules by channel/keyword/URL
melt watch Watch folder for URL files
melt profile <save/list/delete/show> Config profiles
melt export/import <file> Collaborative queues
melt sync <init/push/pull/status> Cloud sync config via git

Interactive Workflow

Entering URLs

Enter YouTube URL or URLs: https://youtu.be/abc123 https://youtube.com/playlist?list=XYZ
  • Multi-URL — space-separated
  • Batch files@file.txt (one per line, # comments)
  • Type help for inline reference

Format selection

Choice What happens
1 (Video) Best video+audio + subtitles + thumbnail → downloads/videos/
2 (Audio) Best audio + lyrics metadata → downloads/audio/
3 (Both) Video AND audio downloaded simultaneously
Download format (1: video, 2: audio, 3: both) (default: video): 3

Session persistence

After the first download, MelT remembers your settings so you don't re-enter them:

Reuse these settings? (Y=yes / n=no / m=modify / s=show / q=quit):
  • Y / Enter — reuse
  • n — enter fresh options
  • m — modify specific options
  • q — quit

Modify menu

Press m at the start prompt to change any option before downloading:

Select option to modify:
  [1] Items
  [2] Format
  [3] Destination
  [4] Numbering
  [5] On Duplicate
  [6] Dry Run
  [7] Start download

Dry Run

Toggle on via the modify menu (m then select Dry Run). Previews what would download without actually downloading — shows files, sizes, and destinations.

Format Preview

When enabled in config, shows all available formats before download:

Available formats for "Video Title":
┌─────┬──────┬───────┬────────┬────────┬──────────┐
│ ID  │ Ext  │ Type  │ Quality│ Codec  │ Size     │
├─────┼──────┼───────┼────────┼────────┼──────────┤
│ 137 │ mp4  │ video │ 1080p  │ avc1   │ 450.2 MB │
│ 136 │ mp4  │ video │ 720p   │ avc1   │ 180.5 MB │
│ 140 │ m4a  │ audio │ 128k   │ mp4a   │ 5.2 MB   │
└─────┴──────┴───────┴────────┴────────┴──────────┘
Enter format ID to use (or press Enter for auto):

Set "format_preview": true in config/config.json. Zero cost when disabled.


Features

Parallel Downloads

Configure max_threads in config. Multiple downloads run simultaneously.

Duplicate Handling

Setting Behavior
skip Skip if file exists, log to logs/skipped.txt
overwrite Overwrite existing file
keep Append counter (file_1.mp4, file_2.mp4)

Subtitle Cleaning

Auto-removes roll-up captions (cumulative on-screen text) from downloaded subtitles. Non-fatal on failure.

SponsorBlock

Skip sponsored segments, intros, and outros automatically. Toggle via "sponsorblock": true in config.

Merge Mode

When yt-dlp's internal merge fails, set "merge_mode": true. MelT downloads video + audio streams separately and merges with its own ffmpeg call.

Chapter Splitter

Auto-split videos by chapter:

"chapter_splitter": {
    "enabled": true,
    "output_template": "%(title)s - %(chapter)s.%(ext)s"
}

Creates: Video Title - Introduction.mp4, Video Title - Main Content.mp4, etc. Original file kept. Non-fatal on failure.

Playlists

Auto-detects playlists and prompts for a range:

Fetching playlist: "My Playlist"...
Playlist range for "My Playlist" (e.g. 1-5, 1,3,5 or 'all') (default: all): 1-5

Playlist Diff — First download saves a snapshot. Next time, shows what changed:

Playlist changes: My Playlist
  + 3 new
    New Video Title 1
    New Video Title 2
  - 1 removed
    Removed Video Title

Settings: "reverse_playlist": true (newest first), "playlist_folder_template": "%(playlist_title)s".

Sound Notifications

6 built-in WAV sounds. Each overrideable in config:

"sounds": {
    "batch_start": "C:/sounds/my-start.wav",
    "completion": ""
}

Empty string = bundled default. Disable all sounds with "enable_sounds": false.

YouTube Search

Search and download directly from the CLI:

Choose an option: 2
Search YouTube: lofi hip hop beats

Search results: lofi hip hop beats
┌──────┬──────────────────────────────────┬──────────────────┬──────────┬──────────┬──────────┐
│ #    │ Type │ Title                      │ Channel          │ Date     │ Duration │ Views    │
├──────┼──────────────────────────────────┼──────────────────┼──────────┼──────────┼──────────┤
│ 1    │ [V]  │ lofi hip hop radio         │ Lofi Girl        │ 2w ago   │ 0:00     │ 50,000   │
│ 2    │ [V]  │ chill beats to relax       │ Chillhop         │ 5d ago   │ 3:45     │ 1,200    │
│ 3    │ [P]  │ Lo-Fi Beats Compilation    │ Chill Beats      │ 1mo ago  │ 1:30:00  │ 8,900    │
└──────┴──────────────────────────────────┴──────────────────┴──────────┴──────────┴──────────┘

Enter numbers to download (e.g. 1,3,5-8), 'all' for all, 'more' for next 30, or Enter to cancel:

Filter by type (video / playlist / all) and sort by (relevance / views / date / duration) in search config section. Type more to fetch the next 30 results.


Config Profiles

Save named config presets and switch between them:

melt profile save gaming      # Save current config as 'gaming'
melt profile list             # List saved profiles
melt profile show gaming      # View a profile
melt profile delete gaming    # Delete a profile
melt --profile gaming         # Start with 'gaming' profile

Profiles stored at config/profiles/<name>.json.


Auto-Rules

Define rules that auto-match and override format/destination:

melt rule add --keyword "tutorial" --fmt audio --dest podcasts
melt rule add --channel "MyChannel" --fmt video --dest "my-channel-downloads"
melt rule add --url "live" --fmt both
melt rule list
melt rule remove <id>

Rules match against title, channel/uploader, or URL pattern (regex). Stored in config/rules.json.


Scheduled Downloads

Schedule recurring downloads with the built-in daemon:

melt schedule add https://youtube.com/playlist?list=XYZ --interval 24
melt schedule list
melt schedule remove <id>
melt schedule daemon
  • --interval N — run every N hours
  • --fmt FMT — format override
  • --dest PATH — destination override
  • Single-run jobs (interval 0) auto-disable after execution

Daemon checks every 60 seconds. Jobs stored in config/schedule.json.


Watch Folder

Drop URL files into a folder and MelT auto-downloads them:

melt watch

Config:

"watch_folder": {
    "enabled": false,
    "path": "watch",
    "interval_seconds": 60,
    "auto_delete": true,
    "default_format": "video",
    "default_dest": "downloads"
}
  • Stop: press T or Ctrl+T
  • Any .txt file with URLs is auto-processed
  • Trigger file deleted after processing (configurable)

Download Analytics

Choose an option: 3

MelT Analytics
──────────────

┌──────────────────────────────────────┐
│ Overview                             │
├──────────────────────────────────────┤
│ Total downloads    42                │
│ Total size         2.3 GB            │
│ Average size       57.4 MB           │
│ Last download      2026-06-04 14:30  │
│ First download     2026-05-01 09:15  │
└──────────────────────────────────────┘

┌──────────────────────────────────────┐
│ By Month                             │
├────────┬───────────┬─────────────────┤
│ Month  │ Downloads │                  │
│ 2026-05│ 25        │ ████████████████ │
│ 2026-06│ 17        │ ███████████      │
└────────┴───────────┴─────────────────┘

Data tracked automatically at logs/stats.json.


Collaborative Queue

Share download queues as .meltqueue JSON files:

melt export playlist.melt     # Export URLs + format + dest
melt import playlist.melt     # Import and start download

Cloud Sync

Sync config, rules, schedules, profiles, and stats across machines via git:

melt sync init https://github.com/user/repo.git
melt sync push "updated rules"
melt sync pull
melt sync status

Uses a dedicated git repo at config/sync/.git. Requires git in PATH.


Configuration Reference

Full reference for config/config.json:

General

Dry Run is a runtime toggle via the modify menu (m at start prompt) — not a config key.

Key Default Description
max_threads 3 Parallel download threads
default_format "video" "video", "audio", or "both"
clear_temp true Delete temp files after download
numbering false Prepend index to filenames
duplicate_action "skip" "skip", "overwrite", "keep"
sponsorblock true Skip sponsored segments
exit_on_complete false Exit after download or loop back
default_reuse true Default to reuse previous settings
reverse_playlist false Process newest-first
rate_limit "" e.g. "5M", empty = unlimited
cookies_file "" Path to cookies.txt for private videos
timeout_seconds 5 Auto-confirm timeout (-1 = no timeout)
enable_sounds true Play notification sounds
format_preview false Show format table before download
merge_mode false Separate v/a + own ffmpeg merge
extract_flat.inspect true Lightweight URL inspection
extract_flat.search false Full metadata in search results

Video

Key Default Description
preferred_format "mp4" "mp4", "mkv", "webm"
quality_priority ["480","360","720"] Preferred resolutions (ordered)
preferred_codec "h264" "h264", "h265", "vp9"

Audio

Key Default Description
preferred_format "m4a" "m4a", "mp3", "opus"
quality_priority ["128","192","264"] Preferred bitrates
default_quality 128 Fallback bitrate

Subtitle

Key Default Description
prefer_human true Prefer human subs over auto
language "en" Language code
preferred_format "srt" "srt", "vtt", "ass"

Watch Folder

Key Default Description
enabled false Enable watch folder
path "watch" Folder to monitor
interval_seconds 60 Scan interval
auto_delete true Delete trigger files after processing
default_format "video" Format for watch downloads
default_dest "downloads" Destination for watch downloads

Chapter Splitter

Key Default Description
enabled false Auto-split videos by chapter
output_template "%(title)s - %(chapter)s.%(ext)s" Naming template

Search

Key Default Description
filter_type "all" "all", "video", or "playlist"
default_sort "relevance" "relevance", "views", "date", "duration"

Sounds

Key Default Description
(6 event keys) "" WAV path or empty for bundled default

Requirements

  • Python 3.8+
  • ffmpeg (bundled in standalone builds, system install for source)
  • Node.js (optional — enables 2x yt-dlp speed)
  • git (optional — for cloud sync)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

meltdl-1.1.0.tar.gz (180.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

meltdl-1.1.0-py3-none-any.whl (175.8 kB view details)

Uploaded Python 3

File details

Details for the file meltdl-1.1.0.tar.gz.

File metadata

  • Download URL: meltdl-1.1.0.tar.gz
  • Upload date:
  • Size: 180.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for meltdl-1.1.0.tar.gz
Algorithm Hash digest
SHA256 59ce6ef0c0d6b9c1e831590251f059da76d65b00263bee324323366863dfd935
MD5 130bc9e9a9c77e7fe29608de0ab4cded
BLAKE2b-256 3b172e2b654996829d457d237594183bc25b91caa082aa9d687624633cb5a0c8

See more details on using hashes here.

File details

Details for the file meltdl-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: meltdl-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 175.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for meltdl-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5943018a1f3c33e2b9ea0d9465230e328bd1512703067b582eaa4db4186551c7
MD5 3f123db766ebf8f535a7c5981ec78225
BLAKE2b-256 6fd5a9adb99ca3a3771e0a71ba5db4e598249de74c06b4ebea45ab869130f4bc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page