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              (video / audio / both)
  [3] Destination
  [4] Numbering           (toggle on/off)
  [5] On Duplicate        (skip / overwrite / keep)
  [6] Archive Action      (skip / ask / redownload)
  [7] Dry Run             (toggle on/off)
  [8] 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 (duplicate_action)

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

Archive Handling (archive_action)

Check is per-item, after duplicate check. Only applies when file is missing from disk but its ID is in archive.txt (e.g. user deleted the file but archive still has the record).

Setting Behavior
skip Auto-skip after archive_timeout seconds (default 10). Press r to redownload
ask Always prompt — no timeout, waits for Yes/No
redownload Ignore archive, always download

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", "both"
clear_temp true true / false
numbering false true / false
duplicate_action "skip" "skip" / "overwrite" / "keep"
archive_action "skip" "skip" (auto-skip after timeout) / "ask" (always prompt) / "redownload" (ignore archive)
archive_timeout 10 Seconds before auto-skip archived videos (positive integer)
sponsorblock true true / false
exit_on_complete false true / false
default_reuse true true / false
reverse_playlist false true / false
format_preview false true / false
merge_mode false true / false
rate_limit "" e.g. "5M", empty = unlimited
cookies_file "" Path to cookies.txt
cookies_from_browser "" Browser name: "chrome", "firefox", "edge", etc.
proxy "" "http://host:port", "socks5://host:port", or "auto" (scans system + local ports)
timeout_seconds 5 Auto-confirm timeout (-1 = no timeout, positive int = seconds)
enable_sounds true true / false
extract_flat.inspect true true / false
extract_flat.search false true / false

Video

Key Default Available values
preferred_format "mp4" "mp4", "mkv", "webm"
quality_priority ["480","360","720"] Any resolution numbers, ordered by preference
preferred_codec "h264" "h264", "h265", "vp9", "av1", "any"

Audio

Key Default Available values
preferred_format "m4a" "m4a", "mp3", "opus"
quality_priority ["128","192","264"] Any bitrate numbers, ordered by preference
default_quality 128 Fallback bitrate (integer)

Subtitle

Key Default Available values
prefer_human true true / false
language "en" Single code or comma-separated: "en,ja,es". Available codes: ar, da, de, el, en, es, fi, fr, he, hi, hu, id, it, ja, ko, nl, no, pl, pt, ro, ru, sv, th, tr, uk, vi, zh-Hans, zh-Hant
preferred_format "srt" "srt", "vtt", "ass"
transliterate "" "" (keep original) / "romaji" (convert non-Latin scripts to romanized form)

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 Available values
filter_type "all" "all", "video", "playlist"
default_sort "relevance" "relevance", "views", "date", "duration"
default_results 30 Number of search results per page

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.3.0.tar.gz (190.7 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.3.0-py3-none-any.whl (185.8 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for meltdl-1.3.0.tar.gz
Algorithm Hash digest
SHA256 951a6f82357d9fd5f4ad51365809fc9e9ca50d40cfabf090492d4450da0397d6
MD5 82b6b58e9c166936c776e4c768de24d5
BLAKE2b-256 df19f79fc473135ca4df0261e2c0cc06bc2d0da8090175aee1d45f7dad8ba202

See more details on using hashes here.

File details

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

File metadata

  • Download URL: meltdl-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 185.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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dc678dc074b4d7dd6dd079605de10b0fa6b849545aa0753f899801ac10033c75
MD5 93d180c7ca2a9b372c2d2310c87f3de6
BLAKE2b-256 33755929e4c4fcd2955a8ddaa7c0c8a0464278f9a36ed01d1d664e263b7a558d

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