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]     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

MIT

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)

Source distribution for boomarr 1.1.0
File Size Uploaded
boomarr-1.1.0.tar.gz 197.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for boomarr 1.1.0
File Interpreter ABI Platform
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 log

Release 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
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