2026-07-07 09:23:45 +03:00
2026-07-07 09:23:45 +03:00
2026-07-07 09:23:45 +03:00
2026-07-07 09:23:45 +03:00
2026-07-07 09:23:45 +03:00
2026-07-07 09:23:45 +03:00
2026-07-07 09:23:45 +03:00
2026-07-07 09:23:45 +03:00
2026-07-07 09:23:45 +03:00
2026-07-07 09:23:45 +03:00
2026-07-07 09:23:45 +03:00
2026-07-06 14:29:40 +00:00
2026-07-07 09:23:45 +03:00
2026-07-07 09:23:45 +03:00

mdcor

A small CLI that cleans up messy media metadata using an LLM. It walks a folder of audio/video files, asks an LLM (OpenAI / DeepSeek / Claude compatible) to re-derive correct tags from the filename and any existing (often wrong) tags, writes them back in place via ffmpeg, and groups related files into .m3u8 playlists.

Designed to make structure out of chaos — e.g. a file named AI Lil Peep - BeamerToy [x123].mp3 with tags pointing at the wrong artist gets corrected to artist Lil Peep, title BeamerToy, and grouped into a playlist with its siblings.

How it works

folder ─► walk (recursive) ─► ffprobe read every file ─► build Library
       ─► LLM correction (fed library context as a prior)
       ─► snap spelling variants to canonical forms
       ─► ffmpeg rewrite (stream copy, no re-encode)
       ─► group by artist/album/show ─► .m3u8 playlists

The engine runs in two phases so it can be library-aware:

  1. Read everything, then build a Library of the existing artists, albums, genres, and pre-existing .m3u8 playlists under the folder.
  2. Correct each file: feed the LLM the established spellings as a prior ("you already have Lil Peep, Chief Kelly, ... — prefer these exact spellings"), then snap variants to a single canonical form so they group together. Finally write tags and emit playlists.

Unifying messy spellings (the headline feature)

Files scraped from YouTube often have the uploader tagged as the artist while the real artist is buried in the filename, with arbitrary casing/punctuation. mdcor collapses all of these onto one identity for grouping:

On disk / in tags Canonical key Final artist Playlist
AI Lil Peep - Song A.mp3 lil peep Lil Peep Lil Peep - Singles
Lil Peep - Song B.mp3 lil peep Lil Peep (same playlist)
lil peep - Song C.mp3 lil peep Lil Peep (same playlist)
Lil Peep feat. Lil Tracy - D.mp3 lil peep Lil Peep (same playlist)

Canonicalization is deterministic and conservative: lowercase, strip parenthetical/junk tokens ((Official), [HD], lyrics, amv, ...), drop AI / The prefixes, take the primary artist before x / & / feat. separators, and remove punctuation. The display spelling is the most frequent original form, tie-broken toward the shorter/cleaner one.

The same idea applies to video shows: Some Show S01E01 and SomesHow s01e02 both land in Some Show S01.m3u8.

Package layout

  • audio and video are root-level packages; each format (mp3, flac, mp4, mkv, ...) is a subpackage that registers itself at init time.
  • ffmpeg is the universal backend: ffprobe reads tags, ffmpeg -codec copy rewrites them. One metadata schema, every format.
  • engine is the core: it depends only on the llm, audio, and video interfaces plus a small FS walker, so it's fully testable with no network and no real media.
  • llm has an OpenAI-compatible client (covers OpenAI + DeepSeek) and a native Anthropic Claude client.

Install / build

make build            # → bin/mdcor

Requires ffmpeg and ffprobe on PATH.

Usage

./bin/mdcor \
  --provider deepseek \
  --model deepseek-chat \
  --api-key $DEEPSEEK_API_KEY

Flags

Flag Description
--provider openai, deepseek, or claude (default openai)
--url Base URL override (otherwise provider default)
--model Model name (required)
--api-key API key, or set MDCOR_API_KEY
--folder Target folder. If omitted, processes ~/Music and ~/Videos recursively

No other flags. Recursive walking is always on.

Examples

# Claude, native Messages API
./bin/mdcor --provider claude --model claude-3-5-sonnet-20241022 --api-key $ANTHROPIC_API_KEY

# OpenAI-compatible custom gateway
./bin/mdcor --provider openai --url https://gateway.local/v1 --model gpt-4o-mini --folder ~/Music

Supported formats

  • Audio: mp3, mp2, flac, ogg, oga, m4a, m4b, m4r, alac, opus, wav, wave
  • Video: mp4, m4v, mov, mkv, mka, webm, avi

Development

make test     # go test -cover ./...
make lint     # gofumpt + golangci-lint

Integration tests use small (~12-16KB) real media clips checked into testdata/media/ (2-second excerpts of representative messy filenames). Unit tests use a fake LLM and a fake ffmpeg runner, so they never touch the network or the real ffmpeg binary.

S
Description
Little CLI tool for LLM-based media metadata correction. (~raw)
Readme GPL-3.0
150 KiB
0 Stars 1 Watchers 0 Forks
Languages
Go 99.8%
Makefile 0.2%