What I've Learned Along the Way
A practical guide for running a great Navidrome library with clean tags, sane codecs, and smooth mobile playback (for Clipper and other Subsonic-compatible clients).
Written from the journey of building Clipper (iOS) and self-hosting Navidrome. The goal: help you avoid the usual potholes and get a rock-solid personal music setup.
Why this guide exists
With Navidrome, the app experience directly reflects the quality of your files and tags. If metadata is messy, your library looks messy. If formats and bitrates are odd, your mobile playback suffers.
This guide distills what actually matters:
- sensible codecs & containers
- realistic bitrate "transparency" targets
- robust tagging that doesn't break by edition/compilation/multi-disc
- transcoding strategies that don't burn CPU or battery
- a few server and tooling tips that save time
Codecs & Containers
Container = the box (.m4a, .flac, .mp3)
Codec = how audio is encoded inside
the box (AAC, ALAC, MP3, FLAC, Opus).
One container can hold different codecs — for example,
.m4a can hold AAC or ALAC.
Lossless (archival / edit-safe)
- FLAC (.flac) — open, efficient, and widely supported. Ideal for your master library.
- ALAC (.m4a with ALAC codec) — Apple Lossless. Same quality as FLAC, slightly larger, plays natively across Apple devices.
- WAV / AIFF — uncompressed, very large. Great for production, less ideal for tagging or archiving.
Lossy (portable / streaming-friendly)
- AAC (.m4a with AAC codec) — modern, efficient, excellent on Apple devices.
- MP3 (.mp3) — universal compatibility; larger for the same quality as AAC or Opus.
- Opus (.opus) — extremely efficient, especially at low bitrates; stellar for streaming.
Takeaway: Keep a lossless master (FLAC or ALAC). Stream lossy (AAC, Opus, MP3) as needed.
Bitrate Targets & "Transparency"
"Transparency" means the point where most people can't tell the difference between a lossy file and its lossless source. Here are practical guidelines:
| Codec | Good Mobile | Transparent for Most | Notes |
|---|---|---|---|
| Opus | 96–128 kbps | 128–160 kbps | Excellent efficiency and low latency |
| AAC (LC) | 128–160 kbps | 160–192 kbps | Best choice for iOS; .m4a container |
| MP3 | 192–256 kbps | 256–320 kbps | Universal compatibility |
| FLAC / ALAC | lossless | lossless | Use for archive or local hi-fi playback |
Tips:
- Use VBR (Variable Bitrate) whenever possible — it spends bits where they matter most.
- If your masters are ALAC, transcoding to AAC is fast and native on Apple hardware.
- For podcasts or speech, Opus 64–96 kbps is usually excellent.
Tagging That Never Bites Back
Navidrome organizes by tags, not folders. A well-tagged library is essential.
Core Tags
- ALBUMARTIST – e.g. "Pink Floyd". Keeps albums together.
- ALBUM, TITLE, ARTIST – fill consistently.
- TRACKNUMBER, DISCNUMBER – proper ordering.
- DATE / YEAR – use release year; add edition info to album title if needed.
- COMPILATION – set to
1ortruefor "Various Artists" albums. - Cover Art – embed JPEG 500–1000 px, and keep a
cover.jpgfallback.
Nice-to-Have
- MusicBrainz IDs –
MUSICBRAINZ_ALBUMID,MUSICBRAINZ_ARTISTIDetc. - Genre – keep consistent casing and avoid long lists.
- ReplayGain – store track and album gain/peak in tags for normalized playback.
Recommended Tag Editors
- MusicBrainz Picard — automatic tagging with MBIDs
- Beets — command-line powerhouse for large libraries
- Kid3 or Mp3tag — efficient manual editing
Suggested Folder Layout
/Music
/Artist
/YYYY - Album [Edition]
01 - Track Title.flac
cover.jpg Navidrome uses tags (not filenames) for its database. More info: Navidrome Tagging Guidelines
Transcoding: On-the-Fly vs Pre-Encoded
On-the-fly: easiest, handled by
Navidrome via ffmpeg
Pre-encoded: faster to stream, better
for low-power servers
Example navidrome.toml
FFmpegPath = "/usr/bin/ffmpeg"
[Transcoding]
aac_160 = "ffmpeg -nostdin -v 0 -i {input} -map 0:a:0 -c:a aac -b:a 160k -f adts -"
mp3_192 = "ffmpeg -nostdin -v 0 -i {input} -map 0:a:0 -c:a libmp3lame -b:a 192k -f mp3 -"
opus_128 = "ffmpeg -nostdin -v 0 -i {input} -map 0:a:0 -c:a libopus -b:a 128k -vbr on -f opus -"
If transcoding fails on macOS with aac_at errors, switch to the built-in -c:a aac encoder or use a build with libfdk_aac.
Pre-Encoding Tips
-
Use
beets convertor plainffmpegto create AAC/Opus mirrors for mobile. - Keep your FLAC/ALAC masters intact and tag them first.
Tools I Recommend
| Tool | Purpose | Why It's Useful |
|---|---|---|
| Navidrome | Music server | Lightweight, fast, and tag-faithful |
| Beets | Library manager | Auto-tagging, ReplayGain, conversion |
| MusicBrainz Picard | Tag editor | Fetches verified metadata |
| FFmpeg | Transcoding | Swiss-army knife for audio/video |
| CopyParty | File server | Simple browser file upload |
| Docker / Compose | Deployment | Easy upgrades and reproducible stacks |
| rsync | Backups/uploads | Incremental, reliable syncs |
Artist & Album Info (Last.fm Integration)
Clipper (and other clients) display rich Artist and Album info only if your Navidrome server connects to Last.fm.
Add your API credentials in navidrome.toml:
LastFM.Enabled = true
LastFM.ApiKey = "YOUR_LASTFM_API_KEY"
LastFM.Secret = "YOUR_LASTFM_API_SECRET"
You can get your API key and secret here:
https://www.last.fm/api/account/create
See official docs:
• Navidrome – External Integrations
• Navidrome Configuration Options
If artist info is missing in Clipper, double-check that your Navidrome instance has Last.fm enabled and valid keys, and that the server can reach the internet.
Server Tips That Help
- Hardware: a Raspberry Pi 4 or any modest laptop is plenty for a few concurrent users.
- Docker: mount your
/musicfolder read-only and a small/datafor DB/cache. - Rescans: schedule hourly or daily instead of watching constantly.
- Permissions: use a dedicated user with consistent UID/GID across mounts.
- Backups:
rsync -a --delete /music /backup/music+ snapshot/data. - Upload:
rsync -av --progress --exclude='.DS_Store*' /Volumes/MUSIC/Converted/ user@musicserver:/media/music/. - Monitoring: Navidrome exposes Prometheus metrics for dashboards if desired.
Troubleshooting Quick Wins
Compilation split into many albums?
Ensure ALBUMARTIST="Various Artists" and COMPILATION=1 on each track.
Missing artwork?
Embed cover images and include cover.jpg in each album folder.
Weird sorting or duplicates?
Check for mismatched DATE, DISCNUMBER, or inconsistent casing.
Playback volumes vary?
Add ReplayGain tags with beet replaygain or ffmpeg -af volume=... tools.
Transcoding errors?
Verify the ffmpeg path and test the command manually on a file.
Suggested Setup (Practical Defaults)
- Library master: FLAC or ALAC
- Mobile stream/cache: AAC 160 kbps or Opus 128 kbps (VBR)
- Tag workflow: Clean in Picard first, then import and manage with Beets
- Navidrome: Docker, read-only music, hourly scan, Last.fm configured
-
Backups: nightly
rsync, weekly off-site copy