The Problem
Clients that need to repurpose video assets for new markets must run a manual chain: extract audio, run speech‑to‑text, translate the transcript, synthesize a new voice track, then re‑encode the video. Each step typically requires a separate tool, manual file handling and ad‑hoc scripting, which introduces errors and delays.
What This Does
pyvideotrans delivers an end‑to‑end pipeline that automates ASR → subtitle translation → multi‑role TTS → video muxing. The core CLI lives in cli.py (functions main, stt_fun, tts_fun, sts_fun). Configuration handling is centralized in videotrans/configure/config.py, which loads language lists, API keys and runtime options. UI components (videotrans/mainwin/*.py) expose the same workflow in a Qt front‑end, while the heavy‑lifting back‑ends are under videotrans/recognition/, videotrans/translator/ and videotrans/tts/, each providing a plug‑in style wrapper around dozens of online or local models.
How It Is Wired
Execution starts at cli.py:main (line 14). main parses command‑line arguments and then calls one of the three worker functions:
stt_fun→videotrans/process/stt_fun.py→videotrans/recognition/_base.py→ external ASR APIs (network) or local Whisper (subprocess).tts_fun→videotrans/process/tts_fun.py→videotrans/tts/_base.py→ selected TTS backend (network) or local model (subprocess).sts_fun→ orchestrates the full translate‑and‑dub flow: 1.videotrans/configure/config._set_env(initialises env, logs). 2.videotrans/task/trans_create.pybuilds aTaskobject that iterates over video segments. 3. For each segment the call chain is:runffmpeg(invideotrans/util/help_ffmpeg.py) → externalffmpegbinary,BaseRecogn→ ASR,BaseTrans→ translation,BaseTTS→ synthesis, finallyrunffmpegagain to merge audio/video.
The most‑connected module is videotrans/configure/config.py (266 inbound imports, 3 outbound), making it the primary blast‑radius: any change propagates to almost the whole codebase. A circular import involving videotrans/mainwin/main_win.py exists; breaking it would reduce import‑time side effects.
File I/O is performed in 93 places (e.g., Path(...).mkdir in cli.py:main, open in various helpers). Network calls appear in 18 locations (API wrappers in recognition/, translator/, tts/). External commands are invoked via subprocess.run in videotrans/util/help_ffmpeg.py (e.g., runffmpeg). Cryptographic use is limited to a MD5 helper in videotrans/util/help_misc.py.
How To Use It
# 1️⃣ Clone the repo
git clone https://github.com/moses-y/pyvideotrans
cd pyvideotrans
# 2️⃣ Install dependencies (uv is recommended)
uv sync # creates a virtual env and installs from pyproject.toml
# or, with pip
python -m venv .venv && . .venv/bin/activate
pip install -e . # editable install
# 3️⃣ Provide required config (API keys, model paths)
# Edit videotrans/configure/config.py or supply a JSON/YAML file referenced there.
# Example keys: OPENAI_API_KEY, AZURE_SPEECH_KEY, FASTER_WHISPER_MODEL_PATH
# 4️⃣ Run a full translation job
python cli.py sts_fun --src-lang en --tgt-lang zh --input path/to/video.mp4 --output out_dir
sts_fun runs the complete pipeline; use stt_fun or tts_fun for isolated speech‑to‑text or text‑to‑speech testing. The CLI options are defined in cli.py and surfaced via argparse.
Real‑World Use
A media agency can drop a raw interview (interview.mov) into a watched folder, call the CLI with the source and target language, and receive a fully dubbed MP4 ready for distribution, all without manual subtitle editing. The same code can be wrapped in a micro‑service that watches a queue and processes jobs asynchronously.
Code Health & Issues
- HIGH – Pin third‑party GitHub Actions to a commit SHA (
.github/workflows/main.yml). - HIGH – CI does not execute the test suite (
.github/workflows/main.yml). - MEDIUM – No least‑privilege
GITHUB_TOKENpermissions declared (.github/workflows/main.yml). - MEDIUM – Dependabot / Renovate not configured (no
dependabot.yml). - MEDIUM – No dependency‑vulnerability scan in CI.
- MEDIUM – Test coverage low (12 tests for 308 source files).
- LOW – Workflow jobs lack
timeout-minutes.
Additional static findings: deep nesting (max depth 10) in videotrans/configure/config.py and several modules contain duplicated 6‑line blocks, which inflates maintenance cost.
The Bottom Line
pyvideotrans assembles a full video‑translation workflow in a single Python package, with clear entry points and modular back‑ends for ASR, translation and TTS. Its biggest risk is the concentration of logic in a few hub modules and the current CI gaps; addressing those would make the codebase safer to extend. It is suitable for teams that need a customizable, on‑premise solution and are comfortable managing the dependency and configuration complexity.