NarratoAI makes commentary videos, the format where a narrator walks you through a film, series or short drama over cut-down footage. You give it the source video; a vision model works out what happens, a language model writes the narration script, and the app cuts matching clips, generates the voice-over with a text-to-speech engine, adds subtitles and renders the edit. It can also export a draft for the CapCut (Jianying) editor if you want to finish by hand.
It is worth a look because it chains the whole pipeline in one local web app instead of five tools. It works with OpenAI-compatible APIs as well as Chinese providers such as SiliconFlow, DeepSeek, Qwen and Doubao, supports several TTS engines including local voice cloning with IndexTTS, and runs on a normal laptop: the README suggests 4 CPU cores and 8 GB of RAM, with no GPU required.
Two honest limits. The main README and community are Chinese first (there is an English README), and the results depend on the models you pay for. And because the format is built on other people's footage, check that you have the rights to what you narrate before you publish it.
- Repository: github.com/linyqh/NarratoAI
- Licence: MIT (MIT License)
- Language: Python. Stars: 11.5K. Forks: 1,592. Last push: Oct 24, 2026.
- Scan: safe, Oct 26, 2026, commit 29a11b6
Who it is for
Video creators who make recap or commentary content and want a first cut done for them, and people curious how far an LLM-driven editing pipeline can go.
Getting started
1. Clone the project
git clone https://github.com/linyqh/NarratoAI.git && cd NarratoAI2. Install dependencies with uv and copy the config (then add your API keys to config.toml)
uv sync && cp config.example.toml config.toml3. Start the web app, then open http://localhost:8501
uv run streamlit run webui.py --server.maxUploadSize=2048On macOS the README also offers docker compose up -d from the cloned folder, and there are bundled Windows and Apple Silicon packages linked from the README.
Safety scan
We cloned linyqh/NarratoAI at commit 29a11b6 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 pattern hits, no install hooks, no committed binaries and no bare-IP URLs.
- The network list is the model and speech providers it can call: OpenAI, SiliconFlow, Alibaba DashScope, DeepSeek, Moonshot, OpenRouter, Baidu and Sonilo for music. Frames, transcripts and scripts are sent to the ones you configure; nothing goes out until you add a key.
- Voice cloning (IndexTTS, OmniVoice) is built in. It is meant for your own narrator voice; cloning someone else's voice without consent is your responsibility and often illegal.
- 114 known advisories in uv.lock, 7 critical, including Pillow image-decoding bugs and certifi. They matter most if you open untrusted files, so keep the dependencies updated with uv sync.
- Three workflows, none using pull_request_target; the two third-party actions are not pinned to a commit. MIT licence present; no security policy, Dependabot or CodeQL.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | None found. |
| Suspicious code | None found. |
| Install-time code | None: nothing runs at install beyond the package manager itself. |
| Committed binaries | None. |
| CI workflows | 3 workflows. None use pull_request_target. 2 of 2 third-party actions pinned to a tag rather than a commit. |
| Network hosts | 40 distinct hosts referenced from source; most often example.test, bailian.console.aliyun.com, github.com, api.siliconflow.cn. No URLs to bare IP addresses. |
| Known vulnerabilities | 114 advisories across 145 pinned packages: 7 critical, 68 high, 32 moderate, 7 low. requirements.txt: 6 packages, 0 advisories; uv.lock: 145 packages, 114 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.
Worst known vulnerabilities (24 of 114)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-82r6-8w77-94w6 | critical | anyio@4.14.1 | AnyIO: TLSStream IDNA 2003 host name encoding enables potential TLS certificate spoofing |
| GHSA-6q48-6c7w-9gw2 | critical | certifi@2026.6.17 | certifi bundles emSign root CAs with compromised intermediate CA keys |
| GHSA-284h-m62q-gf8w | critical | gitpython@3.1.50 | GitPython: Dormant multi-line git-config values are corrupted into live injected directives (e.g. core.hooksPath) on any… |
| GHSA-332p-7hrc-92wf | critical | pillow@10.4.0 | Pillow: Heap buffer overflow in _tiffWriteProc when saving TIFF to BytesIO |
| GHSA-5x8w-8jj5-q52h | critical | pillow@10.4.0 | Pillow: Heap buffer overflow in FlashPix (FPX) JPEG decoding leads to code execution |
| GHSA-8g5g-8vmr-9782 | critical | pillow@10.4.0 | Pillow: Heap buffer overflow in ImagingJpegDecode |
| GHSA-w889-685w-c8fh | critical | pillow@10.4.0 | Pillow: Argument Injection in Ghostscript call, potentially leading into RCE |
| GHSA-2g87-pp6c-29x5 | high | aiohttp@3.14.1 | aiohttp: Multiple instances of excessive or unbounded memory/CPU use |
| GHSA-5wr8-gcqf-gqf3 | high | aiohttp@3.14.1 | aiohttp server lacks an initial request/header timeout |
| GHSA-9xw5-w5jj-pvcg | high | aiohttp@3.14.1 | AIOHTTP: File descriptor exhaustion in multipart requests |
| GHSA-cq5v-8q36-5273 | high | aiohttp@3.14.1 | AIOHTTP: Out-of-bounds heap read in C HTTP response parser error path (malformed chunked response) |
| GHSA-3w57-8xmc-8v26 | high | anyio@4.14.1 | AnyIO run_process/open_process ignores extra_groups and can retain parent supplementary groups |
| GHSA-g6cj-pr64-35w5 | high | cryptography@49.0.0 | cryptography: PKCS#7 EnvelopedData decryption exposes a Bleichenbacher oracle through distinguishable errors and timing |
| GHSA-v4x8-3wr5-3wq8 | high | filelock@3.29.4 | filelock ReadWriteLock: SQLite reopens the lock database by name, so a planted symlink or journal file makes the lock us… |
| GHSA-239g-whfq-7xj9 | high | gitpython@3.1.50 | GitPython: Repository content can impersonate the git directory, leading to arbitrary code execution |
| GHSA-2f96-g7mh-g2hx | high | gitpython@3.1.50 | GitPython: Command Injection via git long-option prefix abbreviation bypass of CVE-2026-42215 blocklist |
| GHSA-3f7w-8rr8-f37f | high | gitpython@3.1.50 | GitPython: Unguarded git option forwarding in IndexFile.checkout() and TagReference.create() enables arbitrary file over… |
| GHSA-3rp5-jjmw-4wv2 | high | gitpython@3.1.50 | GitPython: git-config section-name injection enables arbitrary config directives (core.sshCommand RCE) |
| GHSA-4gmw-gg2m-w46p | high | gitpython@3.1.50 | GitPython: Unguarded git read-tree option forwarding in IndexFile.from_tree/reset/merge_tree enables arbitrary file over… |
| GHSA-6p8h-3wgx-97gf | high | gitpython@3.1.50 | GitPython: Incomplete unsafe_git_clone_options denylist omits --template enabling arbitrary command execution via clone … |
| GHSA-7833-fr7j-v32q | high | gitpython@3.1.50 | GitPython: Arbitrary local file content disclosure via [include] directive in untrusted .gitmodules (SubmoduleConfigPars… |
| GHSA-83vg-56qc-22m7 | high | gitpython@3.1.50 | GitPython validates a submodule's ".git" path only after cloning into it (RCE) |
| GHSA-8mcc-hrx5-hvxc | high | gitpython@3.1.50 | GitPython: clone_from()/clone() omit --separate-git-dir from unsafe_git_clone_options, enabling arbitrary git-directory … |
| GHSA-94p4-4cq8-9g67 | high | gitpython@3.1.50 | GitPython: Environment-variable exfiltration via Repo.create_remote() / Remote.add() URL (incomplete fix of GHSA-rwj8-pg… |
By the numbers
| Stars | 11.5K |
|---|---|
| Forks | 1,592 |
| Contributors | 16 |
| Commits | 440 |
| Open issues | 3 |
| Open pull requests | 5 |
| Releases | 31 |
| Latest release | v0.8.7 |
| Licence | MIT |
| Main language | Python |
| Project age | 2 years |
| Last push | Oct 24, 2026 |
| Tracked files | 187 |
| Lines of code | 50.2K |
| Checkout size | 5 MB |
Lines by language: Python 47K, JSON 1,566, YAML 456, TOML 410, Markdown 393, Shell 330.
Questions
Is NarratoAI free?
Yes. NarratoAI is MIT-licensed and free; the README warns that people have been reselling renamed copies. You pay only for the model and voice APIs you use, and a separate hosted version exists at narratoai.cn.
Does NarratoAI need a GPU?
No. The heavy lifting is done by cloud models, so a 4-core CPU with 8 GB of RAM is the stated minimum. Local voice cloning engines are optional extras that benefit from better hardware.
Is NarratoAI in English?
There is an English README, and the app works with English-language models and voices, but the documentation, updates and community are mainly in Chinese.
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.
