VideoLingo takes a video, or a YouTube link it downloads with yt-dlp, and turns it into translated subtitles and, if you want, a dubbed version. It transcribes the speech locally with Qwen3-ASR and aligns it word by word, splits the text into subtitle-sized lines, translates with a glossary so names and terms stay consistent, and burns single or dual-language subtitles into the video. Dubbing goes through a text-to-speech service you choose: OpenAI, Edge TTS, Fish Audio, GPT-SoVITS, CosyVoice, F5-TTS and others.
Everything runs from a Streamlit page in your browser, with pause, resume and progress that survives a restart, and a local HTTP API covers batch jobs. Translation needs an OpenAI-compatible LLM endpoint and key that can return structured JSON; speech recognition runs on your own machine by default, using MLX on Apple Silicon.
It is Apache-2.0, with about 18,900 stars, at v3.1.1. The README is upfront about limits: noisy audio hurts timing, mixed-language speech is not handled reliably, and dubbing does not give each speaker a separate voice.
- Repository: github.com/Huanshere/VideoLingo
- Licence: Apache-2.0 (Apache License 2.0)
- Language: Python. Stars: 18.9K. Forks: 2,089. Last push: Sep 30, 2026.
- Scan: safe, Oct 26, 2026, commit 01f8434
Who it is for
Creators translating their own videos for other audiences, learners who want dual-language subtitles, and anyone producing subtitles who would rather review an AI draft than type from scratch.
Getting started
1. Clone and start it with uv (it installs the rest on first run)
git clone https://github.com/Huanshere/VideoLingo.git && cd VideoLingo && uv run start.py2. Windows: download the release's source zip, extract it and double-click
OneKeyStart.bat3. Or start the local HTTP API instead of the web page
uv run start.py --apiThen enter your LLM API URL, key and model in the sidebar. The Windows one-click start installs uv, Python 3.12, FFmpeg and the dependencies on first run, so keep its window open. Only translate and republish videos you have the rights to.
Safety scan
We cloned Huanshere/VideoLingo at commit 01f8434 on Oct 26, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.
- No secrets, no committed binaries and no install scripts across about 24,000 lines of Python. The one bare-IP URL is a test case for API address validation.
- The single pattern hit is setup_env.py, which runs Astral's official uv installer (curl -LsSf https://astral.sh/uv/install.sh | sh) when uv is missing. It is the standard way to install uv, but it is still a script run straight from the internet.
- requirements.txt carries 28 advisories, 2 critical, both for torch 2.2.2 (the torch.load code-execution bug). The other lockfile, docs/pnpm-lock.yaml with 123 advisories, belongs to the documentation website and is not part of the app.
- The outside hosts are the AI providers you can choose for translation, recognition and voice (OpenAI, DeepSeek, SiliconFlow, ElevenLabs, Fish Audio, Azure and others). The README's recommended LLM provider, OpenLux, is linked with a referral code; any OpenAI-compatible provider works.
- No GitHub workflows, security policy or contributing guide, which is common for a small project (24 contributors) but means no automated checks on changes.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | None found. |
| Suspicious code | 1 pattern hit found and read; every one is listed under the raw findings. |
| Install-time code | None: nothing runs at install beyond the package manager itself. |
| Committed binaries | None. |
| CI workflows | No GitHub Actions workflows. |
| Network hosts | 32 distinct hosts referenced from source; most often api.openai.com, download.pytorch.org, github.com, astral.sh. 1 URL to a bare IP address, listed under the raw findings. |
| Known vulnerabilities | 151 advisories across 538 pinned packages: 6 critical, 57 high, 66 moderate, 22 low. docs/pnpm-lock.yaml: 528 packages, 123 advisories; requirements.txt: 10 packages, 28 advisories. |
| Project hygiene | Has licence file. Missing security policy, automated dependency updates, CodeQL, contributing guide. |
| OpenSSF Scorecard | Not scored: the project is not in Scorecard's weekly index. |
The raw findings
Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.
Pattern hits (1)
| Where | Rule | Match |
|---|---|---|
| setup_env.py:49 | download-piped-to-shell | ["sh", "-c", "curl -LsSf https://astral.sh/uv/install.sh | sh"], |
URLs to bare IP addresses (1)
| Where | Rule | Match |
|---|---|---|
| tests/test_backlog_fixes.py:85 | ip-literal-url | ("https://8.8.8.8/v1", False), |
Worst known vulnerabilities (24 of 151)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-2464-fhr4-w9xw | critical | next@14.2.13 | Next.js: Unauthenticated Remote Code Execution in Image Optimization API when SVG files are used |
| GHSA-2xp9-vwfh-vxw4 | critical | next@14.2.13 | Next.js: Unauthenticated Remote Code Execution in Image Optimization API when AVIF files are used |
| GHSA-f82v-jwr5-mffw | critical | next@14.2.13 | Authorization Bypass in Next.js Middleware |
| GHSA-p293-qw3h-jr36 | critical | next@14.2.13 | Next.js: Unauthenticated Remote Code Execution on windows-hosted servers |
| GHSA-53q9-r3pm-6pq6 | critical | torch@2.2.2 | PyTorch: `torch.load` with `weights_only=True` leads to remote code execution |
| CVE-2024-48063 | critical | torch@2.2.2 | |
| GHSA-3jxr-9vmj-r5cp | high | brace-expansion@2.0.1 | brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups |
| GHSA-6j4f-fj2g-mc7p | high | brace-expansion@2.0.1 | brace-expansion: DoS via uncontrolled recursion in parseCommaParts causing stack exhaustion |
| GHSA-mh99-v99m-4gvg | high | brace-expansion@2.0.1 | brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash |
| GHSA-qhr7-859c-m2p7 | high | brace-expansion@2.0.1 | brace-expansion: DoS via uncontrolled recursion on nested brace groups causing stack exhaustion |
| GHSA-rgw5-rvv9-x895 | high | brace-expansion@2.0.1 | brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation |
| GHSA-73wf-gq98-2v4g | high | browserslist@4.24.0 | Browserslist: Uncaught crash / prototype write via untrusted browserslist-stats.json custom stats (normalizeStats) |
| GHSA-c83g-rgw3-j3cx | high | browserslist@4.24.0 | Browserslist: Unbounded memory growth (no cache eviction) via distinct query results, leading to eventual OOM |
| GHSA-3xgq-45jj-v275 | high | cross-spawn@5.1.0 | Regular Expression Denial of Service (ReDoS) in cross-spawn |
| GHSA-3xgq-45jj-v275 | high | cross-spawn@7.0.3 | Regular Expression Denial of Service (ReDoS) in cross-spawn |
| GHSA-mrv2-3pqr-j5jr | high | dompurify@3.1.6 | DOMPurify IN_PLACE: hook that removes a parent or sibling leaves the detached subtree's event handlers armed (incomplete… |
| GHSA-5j98-mcp5-4vw2 | high | glob@10.4.5 | glob CLI: Command injection via -c/--cmd executes matches with shell:true |
| GHSA-2883-xcg3-v3hh | high | js-yaml@3.14.1 | js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources |
| GHSA-52cp-r559-cp3m | high | js-yaml@3.14.1 | js-yaml: YAML merge-key chains can force quadratic CPU consumption |
| GHSA-5p4m-2wfm-xmqj | high | js-yaml@3.14.1 | JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) - CVE-2026-59870 fix not backported |
| GHSA-2883-xcg3-v3hh | high | js-yaml@4.1.0 | js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources |
| GHSA-52cp-r559-cp3m | high | js-yaml@4.1.0 | js-yaml: YAML merge-key chains can force quadratic CPU consumption |
| GHSA-5p4m-2wfm-xmqj | high | js-yaml@4.1.0 | JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) - CVE-2026-59870 fix not backported |
| GHSA-r5fr-rjxr-66jc | high | lodash-es@4.17.21 | lodash vulnerable to Code Injection via `_.template` imports key names |
By the numbers
| Stars | 18.9K |
|---|---|
| Forks | 2,089 |
| Contributors | 24 |
| Commits | 1,091 |
| Open issues | 17 |
| Open pull requests | 7 |
| Releases | 49 |
| Latest release | v3.1.1 |
| Licence | Apache-2.0 |
| Main language | Python |
| Project age | 2 years |
| Last push | Sep 30, 2026 |
| Tracked files | 191 |
| Lines of code | 23.8K |
| Checkout size | 4 MB |
Lines by language: Python 16.4K, Markdown 3,463, JSON 1,837, Jupyter 836, TypeScript 702, YAML 235.
Questions
Is VideoLingo free?
Yes. VideoLingo is free and open source under Apache-2.0. What can cost money is the LLM API it uses for translation and any paid voice service for dubbing; speech recognition runs locally for free by default.
Which languages does VideoLingo support?
It transcribes English, Russian, French, German, Italian, Spanish, Japanese and Chinese. Translation goes to whatever language your LLM handles well, and the languages available for dubbing depend on the voice service you pick.
Does VideoLingo need a GPU?
No. On Apple Silicon it uses MLX, Intel Macs and machines without a GPU fall back to CPU recognition, which is slower. For a Linux server with an NVIDIA card the project provides a Dockerfile.
This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.
