Convert video audio to subtitles using AI transcription models.
ParoleSub is a self-hosted web application that automates video transcription for media libraries. It integrates with Bazarr to detect missing subtitles, queues transcription jobs, and processes them using Mistral's Voxtral Mini model. The system includes a web UI for monitoring progress, viewing history, and managing settings.
The original CLI functionality is preserved - you can still run one-off transcriptions from the command line while the web application handles automated workflows.
One-off conversion of a single file, no persistent web app:
-
Set API key:
echo -n "your_api_key" | podman secret create mistral_api_key -
-
Run:
podman run --rm --userns=keep-id \ --secret mistral_api_key,type=env,target=MISTRAL_API_KEY \ -v ./videos:/input:ro,Z -v ./subs:/output:Z \ parolesub:latest -i /input/video.mp4 -o /output/video.srt
For the full web application with Bazarr integration.
Podman, using native Podman secrets:
-
Set required secrets:
echo -n "yourStrongPass!" | podman secret create admin_password - echo -n "your-mistral-key" | podman secret create mistral_api_key -
-
(Optional) Copy
.env.exampleto.envto override defaults such asADMIN_USERNAME— compose loads it automatically, noexportneeded. -
Bring up the stack:
podman compose up -d
-
Visit http://localhost:8080, log in as admin, then set the Bazarr URL and API key under Settings.
Docker is also supported, via docker-compose.docker.yml, a standalone variant that reads ADMIN_PASSWORD/MISTRAL_API_KEY from a plaintext .env file instead of Podman secrets:
cp .env.example .env # set ADMIN_PASSWORD and MISTRAL_API_KEY
docker compose -f docker-compose.docker.yml up -d --buildDo not merge it with docker-compose.yml — run one or the other.
git clone https://github.com/guiand888/parolesub.git
cd parolesub
nix develop # bootstraps a .venv (gitignored) and installs deps automatically
export MISTRAL_API_KEY=your_api_key
parolesub -i video.mp4 -o subtitles.srtParoleSub does not terminate TLS itself; it expects to sit behind a reverse
proxy for any exposure beyond localhost. A ready-to-use Caddyfile
is included for this — point Caddy at it for automatic Let's Encrypt HTTPS in
front of the frontend's port 8080. Set BEHIND_TLS=true in .env once a proxy
is in front, so the session cookie gets the Secure flag.
The admin password is set via the ADMIN_PASSWORD environment variable or the
ADMIN_PASSWORD_FILE secret (Podman secret / .env), never through a CLI
command. On first boot the admin user is created from these. On every
subsequent boot the stored hash is reconciled against the resolved secret —
so rotating the Podman secret or .env value and redeploying is the only
mechanism for changing the admin password.
The shipped docker-compose.yml uses ADMIN_PASSWORD=admin as a placeholder;
the bootstrap refuses to start with any known default (admin, changeme,
password, root, 123456, empty). Set a strong secret before the first
boot.
ParoleSub is primarily used through its web application. The CLI commands below are optional, for one-off or advanced transcriptions.
- Setup: Deploy using the Compose method above
- Configuration: Configure Bazarr URL and API key in Settings
- Detection: Bazarr integration automatically detects media missing subtitles
- Queue: Items appear in the Wanted list in the web UI
- Process: Click "Transcribe" to queue jobs for automatic processing
- Monitor: Watch progress in the Queue page with live updates
- Complete: Finished jobs appear in History with cost tracking
The Bazarr poller runs automatically and updates the Wanted list. When the "Track Items with No Subtitles" setting is enabled, it will also show items with no subtitles in any language.
# Basic (SRT)
podman run --rm --userns=keep-id \
--secret mistral_api_key,type=env,target=MISTRAL_API_KEY \
-v ./videos:/input:ro,Z -v ./subs:/output:Z \
parolesub:latest -i /input/video.mp4 -o /output/video.srt
# VTT format
... --format vtt
# With language code
... -o /output/video.srt --language enCreate parolesub.yaml:
jobs:
- input: /input/video1.mp4
output: /output/video1.srt
- input: /input/video2.mp4
output: /output/video2.vtt
format: vttRun:
podman run --rm --userns=keep-id \
--secret mistral_api_key,type=env,target=MISTRAL_API_KEY \
-v $(pwd):/work:Z,rslave \
parolesub:latest --config /work/parolesub.yamlSRT (default), VTT, SBV
Output files follow: filename.language_code.format
Examples: movie.en.srt, show.s01e01.fr.vtt
Supported language codes: en, fr, es, de, it, pt, ru, zh, ja, ko (ISO 639-1/2)
See CONTRIBUTING.md for development setup, testing, and contribution guidelines.
AGPLv3 - see LICENSE file for details.
