Boomarr
🔊 Symlink-based audio language filter for Plex, Jellyfin & Emby — automatically mirrors your media library, keeping only files with your desired audio tracks.
What is this?
Your library has German, English and French releases mixed together, but some people in your household only want to see what they can actually watch in their language. Boomarr scans your library with ffprobe and builds separate folders that contain only (symlinks to) the files with the audio languages you choose. Point a Plex/Jellyfin/Emby library at such a folder and share it with whoever needs it.
/data/media/movies /data/filtered/movies-deu
├── Film A (2020)/Film A.mkv deu,eng ├── Film A (2020)/Film A.mkv -> …
├── Film B (2021)/Film B.mkv eng ├── Film C (2022)/Film C.mkv -> …
└── Film C (2022)/Film C.mkv ger └── Film C (2022)/Film C.de.srt -> …
└── Film C.de.srt
No files are copied, moved or modified, and no disk space is used.
Features
- Any number of filtered libraries per source, e.g. German-only, English-only and "German and English" side by side.
- Smart language matching:
ger,deu,deandde-DEare the same language; aliases (e.g.undfor untagged tracks);any/allmodes. - Fast: every file is probed only once (SQLite probe cache, parallel probing); later scans only look at new or changed files.
- Always correct: every scan reconciles the output with the current config, so config changes, new libraries and deleted links are handled automatically.
- Safe by design: sources must be read-only, only Boomarr's own symlinks are ever removed, and an unmounted share never empties your filtered library. Details.
- Subtitles included: external subtitles (
Film.de.srt) follow their media file. - More than languages: combine with resolution (4K only), video/audio codec, surround channels, or invert any filter.
- Sonarr/Radarr aware: optionally reuse the languages they already know instead of probing, and rescan instantly on their webhooks.
- Integrates with your stack: Prometheus
/metrics, Apprise notifications (Telegram, Discord, ntfy, …), automatic Plex/Jellyfin/Emby folder refresh after changes, and a removal guard against accidental mass deletions. - Homelab friendly: multi-arch Docker image (amd64/arm64) with
PUID/PGIDor rootless operation, healthcheck, Helm chart, Unraid template, systemd unit,--dry-run.
Quick start
# docker-compose.yml
services:
boomarr:
image: ghcr.io/eulemitkeule/boomarr:latest
container_name: boomarr
restart: unless-stopped
environment:
PUID: 1000
PGID: 1000
TZ: Europe/Berlin
volumes:
- ./config:/config
- /srv/data/media:/data/media:ro # read-only!
- /srv/data/filtered:/data/filtered
# config/boomarr.yml
output_path: /data/filtered
triggers:
- type: schedule
interval: 600
libraries:
- name: Movies
input_path: /data/media/movies
symlink_libraries:
- filters:
- type: audio_language
languages: [deu] # -> /data/filtered/movies-deu
- name: Shows
input_path: /data/media/shows
symlink_libraries:
- name: Serien (Deutsch) # -> /data/filtered/Serien (Deutsch)
filters:
- type: audio_language
languages: [deu]
docker compose run --rm boomarr boomarr scan --dry-run # preview
docker compose up -d
Documentation
| 📖 Documentation site | Everything below, nicely rendered |
| Installation | Docker, Compose, Unraid, Helm, pip/pipx, systemd |
| Configuration | All options, filters, triggers, environment variables |
| Media servers | Path mapping, Plex, Jellyfin/Emby, Sonarr/Radarr, automatic refresh |
| How it works | Scan pipeline, safety guarantees, commands |
| Troubleshooting | FAQ and common problems |
Commands
boomarr watch run continuously (Docker default)
boomarr scan [--dry-run] [--force] one full scan (--force: bypass removal guard)
boomarr clean remove broken symlinks only
boomarr status [--json] cache statistics, languages found, output folders
boomarr healthcheck liveness check for Docker/Kubernetes
boomarr paths print writable directories
boomarr version
Alternatives
| Boomarr | Polyglot | Custom script (blog) | |
|---|---|---|---|
| Media servers | Plex, Jellyfin, Emby | Jellyfin only | Jellyfin |
| Split by audio language | ✅ | ❌ (metadata language) | ✅ |
| Link type | symlink (any filesystem) | hardlink (same filesystem) | symlink |
| Incremental / cached | ✅ | ✅ | ❌ |
| Webhook trigger | ✅ | ❌ | ❌ |
| Resolution / codec filters | ✅ | ❌ | ❌ |
| Metrics & notifications | ✅ | ❌ | ❌ |
Development
uv sync --all-groups
uv run pytest # needs ffprobe for the integration test
uv run ruff check . && uv run ruff format --check . && uv run ty check
docker compose -f docker-compose.dev.yml up --build
See CONTRIBUTING.md. Test media can be regenerated with
uv run python tests/fixtures/generate.py.
Inspiration
Inspired by Filip Rojek's blog post on creating a language-specific Jellyfin library with a Bash script. Boomarr turns that idea into a configurable, safe and Docker-native tool.
License
Release files for boomarr 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| boomarr-1.1.0.tar.gz | 197.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| boomarr-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 272.3 kB
Release files / boomarr-1.1.0.tar.gz
| Download URL | boomarr-1.1.0.tar.gz |
|---|---|
| Size | 197.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2870179471512824cf0b1c40dc3ff7ad040c3131a799f625dc53cebb7e9471c8
|
|
BLAKE2b-256 checksum How to use checksums |
89600d779e21c11dd33d3eab290e05f70da9c4aa505174dd241665b140ce79d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / boomarr-1.1.0-py3-none-any.whl
| Download URL | boomarr-1.1.0-py3-none-any.whl |
|---|---|
| Size | 74.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
046590d1f63b842c7e3e258a1badd8e99202aa6f1edd8383469eb58153094bd4
|
|
BLAKE2b-256 checksum How to use checksums |
7b20e75469692f491abe7f7532b2833b306757b614bf6b492d4f3484a9aab59f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log