Skip to main content

Boomarr

Boomarr

PyPI - Version GitHub License GitHub Sponsors

Code Quality Publish Coverage Bugs Vulnerabilities

🔊 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, de and de-DE are the same language; aliases (e.g. und for untagged tracks); any / all modes.
  • 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/PGID or 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]     last scan, cache, languages, triggers, links + filters per output
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

MIT

Release files for boomarr 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for boomarr 1.2.0
File Size Uploaded
boomarr-1.2.0.tar.gz 201.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for boomarr 1.2.0
File Interpreter ABI Platform
boomarr-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 278.6 kB

Release files / boomarr-1.2.0.tar.gz

Download URL boomarr-1.2.0.tar.gz
Size 201.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7d62d0cf792cb2f22a20e7ba5ce19e2bc4e8218c6bb8fc811e52c1591fe20633
BLAKE2b-256 checksum
How to use checksums
ce44829366d56c65e83631793e75bf81e9fc460eb0478e58ea6f84c94b409de8
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

Release files / boomarr-1.2.0-py3-none-any.whl

Download URL boomarr-1.2.0-py3-none-any.whl
Size 77.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
88c45bc82be764fa8c2606dfd0cfc55de96cb7d85ec85f6bfd3ed8293279d298
BLAKE2b-256 checksum
How to use checksums
49f5d4188e8600335f76819ec2a55063ac40cc70dc33f2122979c404832375e0
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
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page