Skip to main content

CLI tool for AI voiceover translation from subtitles

Project description

rusa — AI Voiceover for Movies & Videos

PyPI version Python versions License CI status Code style: Ruff

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 ffmpeg and ffprobe in PATH
  • Windows: best-effort support; use py -m pip install rusa and make sure ffmpeg.exe is in PATH

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 / ffprobe
  • edge-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

# Auto-speed — each subtitle is accelerated just enough to fit its timeslot
rusa --speed auto movie.mkv

# Auto-speed with a custom upper limit
rusa --speed auto:max=2.0 movie.mkv

How it works

  1. Load subtitles from the video or an external .srt file
  2. Optionally synchronize them with alass
  3. Generate TTS audio per subtitle line
  4. Convert TTS output to WAV and trim silence
  5. Assemble all subtitle segments into one voiceover track
  6. Mix the voiceover with the original audio
  7. 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; auto for per-segment tuning 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 PATH
  • ffprobe was not found in PATH
  • edge-tts is not installed

check that:

  1. ffmpeg and ffprobe are installed and available in PATH
  2. edge-tts is installed in the same Python environment as rusa
  3. on Windows, ffmpeg.exe is in PATH

Subtitle codec error

If you see something like:

Subtitle codec mov_text ... is not supported

then:

  • --subs-mode auto will try fallback modes automatically
  • --subs-mode copy fails early
  • --subs-mode convert writes a compatible text subtitle format directly
  • --subs-mode drop writes 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rusa-0.2.0.tar.gz (58.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rusa-0.2.0-py3-none-any.whl (38.3 kB view details)

Uploaded Python 3

File details

Details for the file rusa-0.2.0.tar.gz.

File metadata

  • Download URL: rusa-0.2.0.tar.gz
  • Upload date:
  • Size: 58.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for rusa-0.2.0.tar.gz
Algorithm Hash digest
SHA256 49c8d6e5a89712d5112064cdb12720486fae90aa47adfd20fb2de011b8aa445b
MD5 c3849af0420f31ac5774868626fcd65e
BLAKE2b-256 4a1c46db8cc848ea0fe9504916501063e7329f1a3bf419b4e76db00df3acdf70

See more details on using hashes here.

File details

Details for the file rusa-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: rusa-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 38.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for rusa-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9e64eb52c86626cc625d92ce6662fa0882fee6fe2c8acf4b422b952032ba9dad
MD5 173bc406d81febdb8422eabaedebf1fb
BLAKE2b-256 ad3fcb29ed7709f393df1dc9bec28eca16e3e7e9f39635eebe8b02f977d57737

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page