A native macOS video and audio downloader with a deliberately gaudy, classic-Winamp UI and a built-in AI assistant.
Powered by yt-dlp, a static ffmpeg,
and any OpenAI-compatible chat model you point it at.
- Paste a video or audio URL → pick format & quality → hit DOWNLOAD.
- Single-line playlist queue with an inline progress fill, up to 5 parallel downloads.
- AI ASSIST sidebar — chat-driven downloads. Ask "anti-hero by taylor swift as mp3" or "top 5 radiohead songs" and the model finds the right URL, format, and quality, then asks you to approve before queuing.
- Auto ID3 / iTunes tagging for every audio download — title, artist, album, album_artist, composer, year, genre, track number, copyright, full lyrics (USLT), and a 1200×1200 cover, sourced from Apple's iTunes Search API and LRCLib.
- SITES window — searchable list of every site
yt-dlpsupports (1900+), bundled offline so it works without a network round trip. - Bundle ships with yt-dlp and a static ffmpeg matching your Mac's architecture, so end users do not need to install anything from the terminal.
- Custom Winamp-style chrome: beveled panels, green LCD readouts, dark grey gradients, classic monospaced bitmap-feel typography.
- Video — MP4 / WEBM / MKV at BEST / 2160p / 1440p / 1080p / 720p / 480p / 360p.
- Audio — MP3 / M4A / OPUS / WAV at BEST / 320 / 256 / 192 / 128 kbps.
The right sidebar runs an OpenAI-compatible chat completions session. Configure once with your API key, base URL, and model, and it becomes a music-download front-end for the rest of the app:
- The model is allowed to call two tools —
search_youtube(query, limit)andpropose_downloads(items[]). search_youtuberuns the bundledyt-dlp ytsearch:and returns up to 10 candidates. The model picks the official version (skipping covers and reactions).propose_downloadssurfaces an inline approval card. You tick or un-tick individual items and click APPROVE before anything is queued — nothing downloads automatically.
Works with anything that exposes /chat/completions — OpenAI, OpenRouter,
Groq, Together, Anthropic via gateway, local Ollama in OpenAI mode, etc.
Every audio download (mp3 / m4a / opus / wav) automatically goes through a post-download tagging pass so files land in your library already labelled and ready for Music.app, Plex, Doppler, etc. Video downloads are skipped.
| Field | Source | ID3 / iTunes mapping |
|---|---|---|
| Title | iTunes Search · trackName |
TIT2 / ©nam |
| Artist | iTunes Search · artistName |
TPE1 / ©ART |
| Album | iTunes Search · collectionName |
TALB / ©alb |
| Album artist | = artist | TPE2 / aART |
| Composer | falls back to performing artist | TCOM / ©wrt |
| Year | iTunes Search · releaseDate (year prefix) |
TYER / ©day |
| Genre | iTunes Search · primaryGenreName |
TCON / ©gen |
| Track number | iTunes Search · trackNumber/trackCount |
TRCK / trkn |
| Disc number | iTunes Search · discNumber/discCount |
TPOS / disk |
| Copyright | iTunes album lookup · copyright |
TCOP / cprt |
| Cover art | iTunes (1200×1200 upscale of artworkUrl100) |
APIC / covr |
| Lyrics | LRCLib · plainLyrics |
USLT (lang=eng) / ©lyr |
| Bitrate / sample rate / duration / channels / codec | embedded by ffmpeg from the audio stream itself | container-intrinsic |
Implementation:
- The lookups (album-copyright, lyrics, cover download) run in parallel via
Swift
async let, so total wall time is dominated by whichever is slowest — typically ~1s. - The matched track and a 1200×1200 cover are passed to the bundled
ffmpeg, which rewrites the file in place with-id3v2_version 3 -write_id3v1 1for mp3 and the equivalent atom-based metadata for m4a / opus / wav. - The post-download status badge in each playlist row goes from
TAG…(amber) to♪(green) when tagging succeeds, orTAG✗(red) on failure. Hover the row for the full match summary or error message. - Toggle the whole feature with the iTunes TAG switch in PREFS.
iTunes Search and LRCLib are both free, public, no-auth APIs.
./build.sh
open Mindown.appThe build script:
- Downloads
yt-dlp_macosfrom the official yt-dlp release. - Downloads a static
ffmpegmatching your Mac's architecture (darwin-arm64on Apple Silicon,darwin-x64on Intel). - Downloads the latest
supportedsites.mdso the SITES window works offline. - Caches all three under
.bin-cache/so subsequent builds skip the downloads. - Compiles the Swift app, assembles
Mindown.app, copies the binaries intoContents/Resources/bin/, and ad-hoc-signs everything.
The resulting .app is fully self-contained — drop it anywhere, no
terminal install needed for end users.
swift build # debug
swift run Mindown # run from the terminal (no .app bundle)
swift build -c releaseStandard SwiftUI macOS app, single executable target, no third-party Swift dependencies.
Sources/Mindown/
├── App.swift // @main entry, window styling
├── ContentView.swift // Main UI — input row, queue, footer, sidebar
├── SettingsView.swift // PREFS sheet (download dir, binary paths)
├── SupportedSitesView.swift // SITES window (offline list + filter)
├── WinampStyle.swift // Palette, beveled panels, LCD text, etc.
├── DownloadModels.swift // MediaFormat / Quality / DownloadItem
├── DownloadManager.swift // yt-dlp Process orchestration + progress
├── MetadataEnricher.swift // iTunes Search + LRCLib → ID3 / iTunes tags
├── AppSettings.swift // UserDefaults-backed preferences
├── AISettings.swift // API key / base URL / model / sidebar
├── ChatModels.swift // ChatMessage / Proposal / ProposedDownload
├── AIClient.swift // OpenAI-compatible chat completions client
├── AITools.swift // Tool definitions + host-side runners
├── AIChatView.swift // Sidebar UI (form + chat + approval cards)
└── ChatViewModel.swift // @MainActor orchestrator + tool-call loop
- PREFS sheet (footer button): override download directory, yt-dlp path, ffmpeg path, and toggle the iTunes TAG metadata enrichment pass. Bundled binaries are picked up automatically on fresh installs.
- AI ASSIST sidebar: API key, base URL, model. Defaults to OpenAI's
gpt-4o-miniagainsthttps://api.openai.com/v1. - All values persist via
UserDefaults.
- This is not sandboxed or notarised — it is a personal-use tool. On first launch on another Mac, right-click → Open if Gatekeeper grumbles.
- The app uses
yt-dlp --progress-templateto parse percent / speed / ETA / total size from a structured pipe-delimited line, which is more reliable than scraping[download]console output. - Output files are named
%(title).200B [%(id)s].%(ext)sso duplicate titles do not clobber each other.
Personal-use utility, no warranty. yt-dlp and ffmpeg are redistributed under their respective licenses (Unlicense and LGPL/GPL respectively).
