🌟 Overview (Try VL Now!)
VideoLingo is an all-in-one video translation, localization, and dubbing tool aimed at generating Netflix-quality subtitles. It eliminates stiff machine translations and multi-line subtitles while adding high-quality dubbing, enabling global knowledge sharing across language barriers.
Key features:
-
🎥 YouTube video download via yt-dlp
-
🎙️ Word-level and Low-illusion subtitle recognition with WhisperX
-
📝 NLP and AI-powered subtitle segmentation
-
📚 Custom + AI-generated terminology for coherent translation
-
🔄 3-step Translate-Reflect-Adaptation for cinematic quality
-
✅ Netflix-standard, Single-line subtitles Only
-
🗣️ Local MLX voice-cloning dubbing with nine selectable backends
-
🚀 One-click startup and processing in Streamlit
-
🌍 Multi-language support in Streamlit UI
-
📝 Detailed logging with progress resumption
Difference from similar projects: Single-line subtitles only, superior translation quality, seamless dubbing experience
trans.mp4 |
dubbing.mp4 |
sovits.mp4 |
Input Language Support(more to come):
🇺🇸 English 🤩 | 🇷🇺 Russian 😊 | 🇫🇷 French 🤩 | 🇩🇪 German 🤩 | 🇮🇹 Italian 🤩 | 🇪🇸 Spanish 🤩 | 🇯🇵 Japanese 😐 | 🇨🇳 Chinese* 😊
*Chinese uses a separate punctuation-enhanced whisper model, for now...
Translation supports all languages, while dubbing language depends on the chosen TTS method.
You don't have to read the whole docs, here is an online AI agent to help you.
Note: For Windows users with NVIDIA GPU, follow these steps before installation:
- Install CUDA Toolkit 12.6
- Install CUDNN 9.3.0
- Add
C:\Program Files\NVIDIA\CUDNN\v9.3\bin\12.6to your system PATH- Restart your computer
Note: FFmpeg is required. Please install it via package managers:
- Windows:
choco install ffmpeg(via Chocolatey)- macOS:
brew install ffmpeg(via Homebrew)- Linux:
sudo apt install ffmpeg(Debian/Ubuntu)
- Clone the repository
git clone https://github.com/Huanshere/VideoLingo.git
cd VideoLingo- Install dependencies(requires
python=3.10)
conda create -n videolingo python=3.10.0 -y
conda activate videolingo
python install.py- Start the application
streamlit run st.pyAlternatively, you can use Docker (requires CUDA 12.4 and NVIDIA Driver version >550), see Docker docs:
docker build -t videolingo .
docker run -d -p 8501:8501 --gpus all videolingoVideoLingo supports OpenAI-compatible LLM APIs and local MLX speech backends:
- LLM:
claude-3-5-sonnet-20240620,deepseek-chat(v3),gemini-2.0-flash-exp,gpt-4o, ... (sorted by performance) - WhisperX: Run whisperX locally or use 302.ai API
- TTS: the local MLX router with IndexTTS2, OmniVoice, Qwen3-TTS, VoxCPM2, Higgs Audio, dots.tts, ZONOS2, and MOSS-TTS.
Note: Translation can still use an OpenAI-compatible API; dubbing in this fork is local MLX only.
This fork keeps the original workflow but adds provider-based configuration and environment checks:
- Secrets are no longer expected in
config.yaml. Set keys through.env/ shell variables based on.env.example. - Run
conda run -n videolingo python -m core.doctorbefore long jobs to check FFmpeg, Python packages, services, secrets, and recoverable step status. - LLM routing is provider-based. The default is local oMLX with
Qwen3.6-35B-A3B-Qwable-Holo3-Qwopus-oQ6-mtp; the originalopenai_compatibleAPI block and cloud presets remain explicitly selectable. - Source text and word timing are restricted to WhisperX and stable-ts. MOSS-Transcribe-Diarize runs as a local MLX speaker sidecar: it labels validated native words without replacing their timestamps, and the pipeline fails closed below 98% speaker coverage.
- TTS routes are registry-based.
--tts auto/tts_method: mlx_routerauto-routes through proven defaults and exposes eight local voice-cloning adapters: IndexTTS2, OmniVoice, Qwen3-TTS, VoxCPM2, Higgs Audio, dots.tts, ZONOS2, and MOSS-TTS. Experimental additions must be explicitly selected. - High-sync dubbing now uses duration budgets, optional LLM shortening/retry, IndexTTS2
target_durationpassthrough, absolute-timeline audio overlay, ASR/leak score fields when available, andoutput/audio/dubbing_eval.json/.xlsxmetrics. - Shared CLI entrypoint:
conda run -n videolingo python -m core.cli doctor,python -m core.cli models list,python -m core.cli run --input <video-or-srt> --source zh --target vi --profile cinematic --tts auto, andpython -m core.cli eval dubbing. - Local video smoke runs can be trimmed directly with
python -m core.cli run --input <local-video> --source zh --target en --profile cinematic --llm omlx --tts mlx_indextts2 --smoke-seconds 60 --no-resume; omit--llmto use the same configured oMLX default. - ASR readback defaults to
dubbing_quality.asr_readback_backend: moss-mlx; runpython -m core.cli eval dubbing --readback.builtinkeeps stable-whisper available, whilecommandaccepts{audio},{language}, and{output_dir}placeholders. - Dubbing repair loop:
python -m core.cli repair dubbing --limit 20writesoutput/audio/dubbing_repair_plan.json; add--reasons missing_audio,over_durationto target specific failure classes,--applyto mutate selected rows,--batches 3to repeat several plan/apply batches, and--full-remaponly when chunk timing should be recomputed globally. Applied repairs rebuildoutput/dub.mp3andoutput/AI配音.mp4by default; use--no-rebuild-outputonly for intermediate tuning. Batch runs append summaries tooutput/audio/dubbing_repair_history.jsonl, and over-duration triage writesoutput/audio/dubbing_over_duration_report.json. - For English smoke runs, ASR-low rows can switch to
qwen3_ttsviadubbing_repair.low_content_fallback_backend. Repeated ASR-quality failures become explicitmanual_reviewwarnings. - Repair/rewrite/readback/TTS use the current
output/pipeline_state.jsontarget language beforeconfig.yaml, so a resumed English smoke is not rewritten or scored as Vietnamese when config defaults drift. - ASR readback stores a fingerprint of target text, source reference, language, backend/model, and segment audio signatures. Cached scores are reused only when the fingerprint still matches.
- Audio merge fails fast on missing or corrupt segment audio unless silence fallback is explicitly enabled, preventing a broken repair run from producing a silent dubbed video.
- Timeline rescue loop:
python -m core.cli rescue timelinewritesoutput/audio/timeline_rescue_report.json/.xlsx; add--write-candidate-tasksto create non-destructiveoutput/audio/tts_tasks_timeline_rescue.xlsxbefore deciding whether to regenerate all dubbing audio. - Translation provenance check:
python -m core.cli translation statusreports whether LLM-generated translation artifacts match the current configured model. Usetranslation adopt-current --applyto write a manifest for trusted existing artifacts.translation archiveis dry-run by default; add--applyto move translation-derived artifacts and GPT logs intooutput/history/translation_*before a clean retranslation. CLIrun/resumeblocks stale translation artifacts unless--auto-archive-stale-translationis explicit. - Repair-time LLM rewrite uses
dubbing_repair.llm_timeout_secondsanddubbing_repair.llm_retry_attempts, separate from the longer global translation retry settings.
Common modes:
- Subtitle-only: download/import video -> ASR or SRT/subtitle extraction -> translation -> SRT/video subtitle output.
- Subtitle + dubbing: run subtitle pipeline, then TTS task generation -> reference extraction -> TTS -> audio/video merge.
- Existing SRT / embedded subtitles: skip ASR with Mode 2 or Mode 3, then continue from segmentation/translation.
For quick tuning, enable smoke_test.enabled in config.yaml or the Streamlit sidebar to trim newly downloaded videos to a short sample before running the full dubbing chain.
For detailed installation, API configuration, and batch mode instructions, please refer to the documentation: English | 中文
-
WhisperX transcription performance may be affected by video background noise, as it uses wav2vac model for alignment. For videos with loud background music, please enable Voice Separation Enhancement. Additionally, subtitles ending with numbers or special characters may be truncated early due to wav2vac's inability to map numeric characters (e.g., "1") to their spoken form ("one").
-
Using weaker models can lead to errors during intermediate processes due to strict JSON format requirements for responses. If this error occurs, please delete the
outputfolder and retry with a different LLM, otherwise repeated execution will read the previous erroneous response causing the same error. -
The dubbing feature may not be 100% perfect due to differences in speech rates and intonation between languages, as well as the impact of the translation step. However, this project has implemented extensive engineering processing for speech rates to ensure the best possible dubbing results.
-
Multilingual video transcription recognition will only retain the main language. This is because whisperX uses a specialized model for a single language when forcibly aligning word-level subtitles, and will delete unrecognized languages.
-
Speaker identity is diarization-based rather than character-name recognition; MOSS separates voices as
S01,S02, etc., but mapping those IDs to named characters still requires user metadata.
This project is licensed under the Apache 2.0 License. Special thanks to the following open source projects for their contributions:
whisperX, yt-dlp, json_repair, BELLE
- Submit Issues or Pull Requests on GitHub
- DM me on Twitter: @Huanshere
- Email me at: team@videolingo.io
If you find VideoLingo helpful, please give me a ⭐️!
