Multi-language audio enforcement for the *arr media stack.
Media files are messy. Audio language metadata is unreliable — mislabeled tracks, missing tags, inconsistent naming across indexers. Radarr and Sonarr do a great job managing downloads, but they have no concept of per-language media libraries.
If you want separate Jellyfin/Plex libraries for each language (e.g. French movies, English movies), you're on your own. Manual sorting doesn't scale, and metadata-based smart playlists break the moment a file has the wrong tag.
multilinguarr solves this by sitting between your *arr instances and your media player. It intercepts download webhooks, detects actual audio languages via ffprobe, and creates symlinks (or hardlinks) into language-specific library directories. Your media player sees clean, per-language libraries. Your *arr instances keep managing the real files. Nothing gets moved or modified.
services:
multilinguarr:
image: ghcr.io/dlepaux/multilinguarr:latest
environment:
- MULTILINGUARR_API_KEY=your-secret
- MULTILINGUARR_MEDIA_BASE_PATH=/srv/media
volumes:
- ./data:/data # SQLite database
- /srv/media:/srv/media # media tree (same mount as arr instances)
ports:
- "3100:3100"Configure languages, instances, and webhooks via the REST API — see the documentation for the full setup guide.
Full documentation is available at dlepaux.github.io/multilinguarr:
- Introduction — how it works, architecture overview
- Installation — Docker setup, configuration
- Directory structure — required media layout
- API reference — interactive OpenAPI docs
| Service | Version |
|---|---|
| Radarr | v3+ |
| Sonarr | v3+ |
| Jellyfin | any |
| Plex | any |