ADR-0009: Multi-Format Output with a Flat Download Layout
Status
Accepted
Date
2026-08-12
Context
Two independent changes to download output were made in the rewrite.
Format. The pre-rewrite code produced MP3 only. The rewrite supports MP3,
M4A, OGG, FLAC, and Opus. The motivation was straightforward: users should be
able to choose between lossless (FLAC) and lossy (MP3/M4A/OGG/Opus) output
depending on whether they are archiving or saving space. Adding formats was
cheap because yt-dlp's FFmpegExtractAudio postprocessor performs the
conversion and mutagen handles tagging of each container.
Layout. The pre-rewrite code wrote each playlist into its own sanitised
subdirectory (output_dir/{playlist-name}/...). The rewrite writes every track
flat into output_dir as {title}.{ext}.
The flat layout is a direct consequence of the dedup goal (ADRs 0005 and 0006):
a track that appears in several playlists must exist on disk exactly once.
Per-playlist directories would force either duplicated files or a
directory-to-track mapping to reconcile the same song across playlists. A flat
directory is just a set of files whose identity lives in their tags, not in
their location. This is also why the playlist name field was dropped from the
config — there is no directory name to derive from it.
Decision
- Output format is configurable (
mp3,m4a,ogg,flac, oropus), converted by yt-dlp'sFFmpegExtractAudiopostprocessor in the same pipeline that downloads and applies metadata. - All tracks are written directly into
output_diras{title}.{ext}; there are no per-playlist subdirectories. - Tagging is dispatched by container: ID3 for MP3, MP4 tags for M4A, and Vorbis
comments for OGG/FLAC/Opus, behind a single
AsyncAudioFileinterface that reads a file into memory, tags it, and writes it back. Each tagger uses the format's native scheme, which matches the per-format Picard conventions of ADR-0006.
Consequences
Positive
- Lossless and lossy output options.
- Cross-playlist dedup falls out of the file model: one file per track, keyed by tags.
- Adding a format is cheap (new tagger + config value).
- Download, conversion and metadata happen in one yt-dlp pipeline with no separate conversion step, and FFmpeg remains the only system dependency (ADR-0001).
Negative
- Filenames are title-based, so two different tracks with the same title can collide in the same directory.
- No playlist organisation is preserved on disk.
Neutral
- The startup full scan (ADR-0005) is a flat iteration of
output_dir.
Alternatives Considered
Per-playlist subdirectories (the old approach)
Rejected: conflicts with the dedup goal — the same track in two playlists would need to be duplicated or mapped across directories.
Artist/album-based directory structure
Rejected: moves library organisation into the application and fights the
flat-files-with-tags model; user reorganisation would break the FilePath
tracking noted in ADR-0005.
Single format (MP3 only)
Rejected: does not serve the lossless-archive use case.