apps.header.allAppsCount
Babel
apps.detail.types.app from shadoh's Repository
apps.detail.sections.overview
Readme
View on GitHub
Babel
Media Dub Detection & Upgrade Tool for Sonarr and Plex
Babel monitors your media library, detects sub-only episodes, and automatically searches for English dubbed versions through Sonarr. Named after the Tower of Babel — bridging the language gap in your media library.
Features
Core
- Automatic dub detection via Plex audio track analysis and ffprobe
- Smart upgrade searches with rate limiting, cooldowns, and max attempt caps
- Upgrade tracking — monitors downloads from search through import, auto-retries failures
- Stuck import resolution — detects and force-imports stuck Sonarr queue items (including ID mismatches)
Intelligence
- Dub availability lookup via MyAnimeList/Jikan — knows if a dub even exists before searching
- Dub status change notifications — alerts when a previously unlicensed show gets a dub
- Auto-overrides MAL when actual dubbed audio is detected in files
Integrations
- Sonarr: custom format creation, tag syncing, webhook support for instant upgrade detection
- Plex: audio indexing, collection management (Dubbed Anime, Sub-Only, etc.)
- Discord: webhook notifications for scan results and dub upgrades
- Sonarr webhook endpoint for real-time import awareness
Dashboard
- Polished dark-themed web UI with poster art and live scan progress
- Series browser with filter pills, search, sort, and pagination
- Activity feed with real-time download monitoring
- Dub Intelligence page with Recently Dubbed / Dub Expected / No Dub tabs
- Scan history with drilldown detail views
- Log viewer with level filtering
- All settings configurable via web UI
Quick Start
services:
babel:
image: therealshadoh/babel:latest
container_name: babel
ports:
- "8686:8686"
volumes:
- babel-data:/app/data
environment:
- SONARR_URL=http://your-server:8989
- SONARR_API_KEY=your-api-key
- PLEX_URL=http://your-server:32400
- PLEX_TOKEN=your-plex-token
restart: unless-stopped
volumes:
babel-data:
docker compose up -d
Open http://localhost:8686 to access the dashboard.
Configuration
All settings can be configured via environment variables or the web UI Settings page.
| Variable | Default | Description |
|---|---|---|
SONARR_URL |
Sonarr server URL (optional — Babel can run Plex-only) | |
SONARR_API_KEY |
Sonarr API key (Settings > General) | |
PLEX_URL |
Plex server URL | |
PLEX_TOKEN |
Plex authentication token | |
SCAN_INTERVAL_HOURS |
6 |
Hours between automatic scans |
TARGET_LANGUAGE |
eng |
ISO 639-2 language code to search for |
SEARCH_COOLDOWN_DAYS |
7 |
Days before re-searching an episode |
SEARCH_RATE_LIMIT |
5 |
Max Sonarr searches per minute |
DISCORD_WEBHOOK_URL |
Discord webhook for notifications | |
WEBHOOK_SECRET |
If set, the Sonarr webhook requires ?apikey= (or X-Api-Key header) to match |
|
AUTH_USERNAME / AUTH_PASSWORD |
If both are set, the whole dashboard requires HTTP Basic Auth | |
PUID / PGID |
1000 / 1000 |
UID/GID the container runs as — match your host's media/data ownership |
Security
Babel has no built-in accounts and, by default, no authentication — anyone who can reach the port can view and change settings (including your Sonarr API key and Plex token). For anything beyond a trusted home LAN, do one of:
- Set
AUTH_USERNAME+AUTH_PASSWORDto put the dashboard behind HTTP Basic Auth, or - Put Babel behind a reverse proxy (Caddy, Traefik, Nginx Proxy Manager, etc.) that handles authentication.
GET /api/health and POST /api/webhook/sonarr are always reachable without
Basic Auth credentials (health checks and Sonarr can't complete an interactive
login) — set WEBHOOK_SECRET to authenticate the webhook instead.
Sonarr Webhook (Recommended)
For instant upgrade detection instead of waiting for scan cycles:
- In Sonarr, go to Settings > Connect > + > Webhook
- Name: Babel
- URL:
http://your-babel-container:8686/api/webhook/sonarr(append?apikey=your-secretifWEBHOOK_SECRETis set) - Events: Enable On Import and On Upgrade
- Click Save
Unraid Installation
- In the Unraid web UI, go to Docker > Add Container
- Set Repository to
therealshadoh/babel:latest - Configure ports (8686), appdata path, and environment variables
- Click Apply
- Access the web UI at
http://your-server:8686
How It Works
Scan Cycle:
Sonarr ──> Fetch anime series + episodes
│
For each episode:
├── Check DB cache — unchanged files skip straight to their known status
├── Otherwise check audio tracks (Plex → ffprobe fallback; Plex's
│ library index is only built the first time a scan actually needs
│ it, so a cycle where nothing changed never touches Plex at all)
├── Classify: DUBBED / SUB_ONLY / MISSING
└── If SUB_ONLY → trigger Sonarr search
│
Post-scan:
├── Check download queue status
├── Resolve stuck imports
├── Sync Sonarr tags + Plex collections
└── Send Discord notifications
Webhook (real-time):
Sonarr import event → re-check audio via ffprobe → resolve upgrade
Note: Sonarr is optional — with only Plex configured, Babel runs in a
read-only "Plex-only" mode (detection and collections, no searches).
API
| Endpoint | Description |
|---|---|
GET /api/health |
System status, version, stats |
GET /api/activity |
Live download queue + recent upgrades |
POST /api/scan |
Trigger manual scan |
POST /api/scan/stop |
Cancel the running scan after the current series |
POST /api/webhook/sonarr |
Sonarr webhook receiver (?apikey= if WEBHOOK_SECRET is set) |
POST /api/check-downloads |
Check pending upgrade status |
POST /api/resolve-imports |
Fix stuck Sonarr imports |
POST /api/lookup-dubs |
Run MAL dub availability check |
POST /api/setup-sonarr-dub |
Create/assign a Sonarr custom format that prefers dual-audio releases |
Data & Backups
Everything Babel needs to keep is under /app/data (the babel-data volume
in the Quick Start example): the SQLite database (babel.db) and rotating
application logs (babel.log*). Back up that volume to preserve scan
history, upgrade tracking, and settings saved via the web UI — the container
itself is stateless otherwise.
Links
apps.marketingCta.appInstallTitle
apps.marketingCta.appInstallDescription
apps.detail.sections.categories
apps.downloadStats.title
apps.detail.sections.related
apps.detail.related.exploreCategories
apps.detail.related.exploreAllapps.detail.sections.links
apps.detail.sections.details
therealshadoh/babelapps.detail.sections.runtime
- apps.detail.details.webui
http://[IP]:[PORT:8686]- apps.detail.details.network
bridge- apps.detail.details.privileged
- false
apps.detail.sections.configuration
Web interface port
- apps.detail.config.target
- 8686
- apps.detail.config.default
- 8686
- apps.detail.config.value
- 8686
Application data (database)
- apps.detail.config.target
- /app/data
- apps.detail.config.default
- /mnt/user/appdata/babel
- apps.detail.config.value
- /mnt/user/appdata/babel
Media files (optional, for ffprobe fallback)
- apps.detail.config.target
- /media
- apps.detail.config.default
- /mnt/user/media
- apps.detail.config.value
- /mnt/user/media
Sonarr server URL
- apps.detail.config.target
- SONARR_URL
- apps.detail.config.default
- http://localhost:8989
- apps.detail.config.value
- http://localhost:8989
Sonarr API key (Settings > General)
- apps.detail.config.target
- SONARR_API_KEY
Plex server URL
- apps.detail.config.target
- PLEX_URL
- apps.detail.config.default
- http://localhost:32400
- apps.detail.config.value
- http://localhost:32400
Plex authentication token
- apps.detail.config.target
- PLEX_TOKEN
Hours between scans
- apps.detail.config.target
- SCAN_INTERVAL_HOURS
- apps.detail.config.default
- 6
- apps.detail.config.value
- 6
ISO 639-2 language code to search for
- apps.detail.config.target
- TARGET_LANGUAGE
- apps.detail.config.default
- eng
- apps.detail.config.value
- eng
Discord webhook URL for notifications (optional)
- apps.detail.config.target
- DISCORD_WEBHOOK_URL