CLI tool for AI voiceover translation from subtitles
Project description
rusa — AI Voiceover for Movies
rusa is a CLI tool that creates a translated voiceover track from subtitles and mixes it into a video or exports audio-only output.
Project status
- Primary interface: CLI only
- Current focus: core pipeline, CLI UX, tests, docs, packaging
- Best-tested environment: Linux/macOS with
ffmpegandffprobeinPATH - Windows: best-effort support; use
py -m pip install rusaand make sureffmpeg.exeis inPATH
Quick start
Install
# Linux / macOS
pip install rusa
sudo apt install ffmpeg # or: brew install ffmpeg
# Windows
py -m pip install rusa
# Download ffmpeg.exe from https://ffmpeg.org and add it to PATH
Run
rusa movie.mkv
By default, rusa writes the result next to the source file, for example:
movie_edge-tts_ru.mkv
Quick health check
rusa --doctor
This prints a short report about:
- Python interpreter
- platform and console encoding
ffmpeg/ffprobeedge-tts- available TTS engines
- cache directory
Common examples
# Basic run
rusa movie.mkv
# Use an external subtitle file
rusa -s subs.srt movie.mkv
# Choose subtitle language explicitly
rusa --lang he movie.mkv
# Use a specific voice
rusa --voice ru-RU-DmitryNeural movie.mkv
# Audio only
rusa --mp3 128 --audio-only movie.mkv
# Preview only the first 10 subtitle lines
rusa --preview 10 --dry-run movie.mkv
# Higher quality output for YouTube-style upload
rusa --preset youtube movie.mkv
How it works
- Load subtitles from the video or an external
.srtfile - Optionally synchronize them with
alass - Generate TTS audio per subtitle line
- Convert TTS output to WAV and trim silence
- Assemble all subtitle segments into one voiceover track
- Mix the voiceover with the original audio
- Encode the final output
CLI options
| Flag | Meaning | Default |
|---|---|---|
video |
Input video file | required |
-o, --output FILE |
Output file path | auto-generated |
-s, --srt FILE |
External subtitle file | auto-detect / extract |
--voice [VOICE] |
TTS voice; without value, list voices | auto |
--lang LANG |
Subtitle language code | auto |
--speed SPEED |
TTS speech speed | 1.5 |
--orig-vol VOL |
Original audio volume | 0.65 |
--tts-vol VOL |
Voiceover volume | 0.93 |
--sync |
Synchronize subtitles with alass |
off |
--keep-temp |
Keep temporary files | off |
--threads N |
TTS worker count | 6 |
--cache-stats |
Show cache statistics and exit | off |
--cache-clear |
Clear cache and exit | off |
--no-cache |
Disable cache for this run | off |
--dry-run |
Print plan only | off |
--preview N |
Process only first N subtitle lines |
off |
--overwrite |
Overwrite existing output file | off |
--aac [BITRATE] |
Encode as AAC | off |
--mp3 [BITRATE] |
Encode as MP3 | off |
--opus [BITRATE] |
Encode as Opus | default codec |
--ac3 [BITRATE] |
Encode as AC3 | off |
--from N |
First subtitle index | all |
--to N |
Last subtitle index | all |
--audio-only |
Write audio output only | off |
--engine ENGINE |
TTS engine | edge |
--tts-cmd TEMPLATE |
Custom TTS command template | off |
--subs-mode MODE |
Subtitle handling: auto, copy, convert, drop |
auto |
--normalize [fast|fine] |
Normalize output loudness | off |
--preset NAME |
Quality preset: youtube, tiktok, podcast, cinema |
off |
--doctor |
Check local runtime dependencies and environment, then exit | off |
--version |
Show version and exit | — |
Docker
docker build -t rusa .
docker run --rm rusa --help
For real processing, mount a directory with your media files:
docker run --rm -v $(pwd):/data rusa movie.mkv
Built-in TTS engines
| Engine | Online | Typical quality | Notes |
|---|---|---|---|
edge |
yes | good | default engine |
piper |
no | good | local neural TTS |
rhvoice |
no | average | local voices |
espeak |
no | basic | very fast |
gtts |
yes | good | simple cloud TTS |
festival |
no | basic | legacy local TTS |
You can also use any custom engine with --tts-cmd.
More details:
Output modes
| Mode | Result |
|---|---|
| default | video + original audio + voiceover |
--audio-only |
audio file only |
--subs-mode auto |
try copy, then convert, then drop subtitles if needed |
--subs-mode copy |
keep subtitles as-is or fail |
--subs-mode convert |
convert subtitles to a compatible text format |
--subs-mode drop |
write output without subtitles |
Cache
rusa uses two caches:
- TTS cache: generated speech files
- WAV cache: converted WAV files after speed change and silence trim
Defaults:
- cache root:
~/.cache/rusa - max size:
2 GiB
Environment variables:
| Variable | Meaning | Default |
|---|---|---|
RUSA_CACHE_DIR |
Cache root directory | ~/.cache/rusa |
RUSA_CACHE_MAX_SIZE |
Max cache size in bytes | 2147483648 |
Commands:
rusa --cache-stats
rusa --cache-clear
rusa --no-cache movie.mkv
Exit codes
| Code | Meaning |
|---|---|
0 |
success |
1 |
runtime error |
2 |
usage error |
3 |
missing dependency |
4 |
subtitle error |
5 |
codec / encoder error |
Tests
# Offline tests
pytest -q -m 'not slow and not live_tts'
# Fast CLI smoke tests
pytest -q tests/test_cli_smoke.py
# Live tests (network access required for edge-tts)
pytest -q -m 'live_tts and not slow'
# Full suite
pytest -q
# Force local fixture generation (requires ffmpeg)
pytest -q --generate-fixtures
If generated fixtures are missing and ffmpeg is unavailable, unit and smoke tests still run. Only fixture-dependent integration tests are affected.
Diagnostics
Missing dependencies
If you see one of these errors:
ffmpeg was not found in PATHffprobe was not found in PATHedge-tts is not installed
check that:
ffmpegandffprobeare installed and available inPATHedge-ttsis installed in the same Python environment asrusa- on Windows,
ffmpeg.exeis inPATH
Subtitle codec error
If you see something like:
Subtitle codec mov_text ... is not supported
then:
--subs-mode autowill try fallback modes automatically--subs-mode copyfails early--subs-mode convertwrites a compatible text subtitle format directly--subs-mode dropwrites the file without subtitles
Development and release docs
License
MIT
README contract
This README is the behavioral contract for the project.
If code and documentation diverge, update the README together with the code change.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rusa-0.1.0.tar.gz.
File metadata
- Download URL: rusa-0.1.0.tar.gz
- Upload date:
- Size: 57.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76d5d3aea0d2a7e74f026782e1fd855c39cf9b694186fdf1dc02ca79f8b7dac4
|
|
| MD5 |
dd85915fbe382ca73e90e325dae1a30f
|
|
| BLAKE2b-256 |
1c99ba946defda3eea5ebf1423bb884ce8a22d81165357847b13500d5a1a37e3
|
File details
Details for the file rusa-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rusa-0.1.0-py3-none-any.whl
- Upload date:
- Size: 36.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c1367629487715a4d34c2b673f57d8f830efc5853c118257dbda9e00a522f94
|
|
| MD5 |
de31895742ba91d57fa4d870fd2575a8
|
|
| BLAKE2b-256 |
9cfbe625406ab995dae4e381a0791b55fc43538880a146c8dc480bff76e46d83
|