Fast Sub v0 is a local-first CLI for generating source-language .srt subtitles from a local video or audio file.
The recommended command is:
fast-sub auto input.mp4Compatibility aliases:
fast-sub input.mp4
fast-sub run input.mp4All three routes use the same v0 local pipeline. They do not silently upload audio, call OpenAI-compatible APIs, or use WhisperX.
ffmpeg/ffprobe
-> probe
-> extract/analyze
-> provider/model resolution
-> local-faster-whisper worker
-> transcribe
-> refine
-> final .srt
The lower-level fast-sub transcribe input.mp4 command runs source transcription only and is used by bench.
Base CLI:
pip install fast-subLocal ASR support:
pip install "fast-sub[local-asr]"For source checkouts:
uv sync --extra local-asrWeb translation support is not declared as a packaged optional extra. The
previous GPL-3.0 translators dependency chain pulled in vulnerable js2py
releases, so packaged builds should prefer local NLLB or explicit API providers
until that upstream chain is safe.
Local NLLB translation support:
uv sync --extra local-translate
fast-sub models install nllb-200-distilled-600m-ct2-int8ffmpeg and ffprobe must be available on PATH in v0 packaging.
Inspect local readiness:
fast-sub doctor
fast-sub models list
fast-sub providers listInstall a model explicitly:
fast-sub models install whisper-smallOr allow the local model install during auto planning:
fast-sub auto input.mp4 --yes--yes only authorizes local model download/install. It does not enable API upload.
It also does not silently install translation models.
Round 7 adds real SRT translation:
fast-sub translate input.srt --provider web-bing --from en --to zh
fast-sub translate input.srt --provider web-google --from en --to zh
fast-sub translate input.srt --provider api-openai-chat --api-key $OPENAI_API_KEY --model <model> --to zh
fast-sub translate input.srt --provider local-nllb-ct2 --from en --to zh--provider and --to are required unless a provider is explicitly configured.
Remote providers are never selected silently. replace mode writes translated text;
bilingual writes original and translated text while preserving cue order, timing,
and count. Partial failures keep the original cue text and write .errors.json.
All-cue failure exits non-zero and does not write a misleading final SRT.
Checkpoint/resume is enabled by default with:
<output>.translate-progress.json
Pass --no-resume to force retranslation.
Commands with --json keep stdout parseable with json.loads(stdout). Progress, warnings, and human diagnostics go to stderr.
Fast Sub also reads a .env file from the current working directory at CLI startup.
Values from the real shell environment win; .env only fills variables that are not
already set. This is useful for API translation settings:
OPENAI_API_KEY=replace-with-your-api-key
OPENAI_MODEL=gpt-4.1-mini
OPENAI_BASE_URL=https://api.openai.com/v1.env loading is silent and does not print secrets.
Common v0 exit codes:
0 success
1 command failed
2 invalid input or CLI usage
3 missing local dependency
4 missing model
5 download, checksum, or cache failure
Missing local ASR dependencies point to:
uv sync --extra local-asr
pip install fast-sub[local-asr]
Missing models point to:
fast-sub models install <id>
fast-sub auto --yes
API keys and tokens must not be printed to stdout, stderr, JSON payloads, or reports.
Stable v0:
fast-sub auto input.mp4fast-sub input.mp4fast-sub run input.mp4fast-sub transcribe input.mp4fast-sub probe input.mp4fast-sub extract input.mp4fast-sub analyze input.mp4fast-sub refine input.srtfast-sub burn input.mp4 input.srtfast-sub translate input.srt --provider <id> --to <lang>fast-sub models list/install/verifyfast-sub providers list/testfast-sub bench input.mp4fast-sub bench-translate input.srt --reference ref.zh.srt --from en --to zh --provider <id>fast-sub bench-translate-manifest
The v0 default provider is local-faster-whisper. Audio remains local.
Translation providers have explicit privacy classes:
local-nllb-ct2: local; subtitle text is not uploaded.web-bing/web-google: remote web; subtitle text is sent to third-party web translation services, which may rate-limit, change behavior, or fail by region. Google may fail in mainland China; tryweb-bing.api-openai-chat: remote API; subtitle text is sent to the configured OpenAI-compatible API and requires an explicit API key plus explicit model.
API upload behavior must be explicit opt-in.
fast-sub bench measures transcribe_media_v1:
input media -> probe -> prepare_audio -> local-faster-whisper worker -> source SRT
Round 7.5 adds the standalone fast-sub bench-translate command for translation quality checks:
fast-sub bench-translate input.srt --reference ref.zh.srt --from en --to zh --provider local-nllb-ct2The translation benchmark uses reference SRT/TXT files to report BLEU, chrF, exact match, elapsed time, throughput, and failed cue counts. It is a reproducible rough signal, not a human-quality guarantee. JSON canonical scores use 0-1. When sacreBLEU is installed, the report records sacreBLEU signature and raw 0-100 scores; otherwise it records metric_implementation=fast_sub_lightweight_v1, which is not equivalent to sacreBLEU. Repeat summaries include avg/min/max/stddev. The existing fast-sub bench command remains focused on media transcription benchmarks.
fast-sub bench-translate-manifest prints the local-only manifest schema/example for provider matrices over light/standard translation samples. Real datasets are manually downloaded into local_tests/bench_translate/raw/; generated samples cover en/ja/ko -> zh and zh/ja/ko -> en when available and remain ignored.
Benchmark media, reference files, generated model caches, and reports belong under ignored local_tests/ paths. The helper scripts/bench_assets.py is a developer/manual asset preparation tool, not a public product CLI. Do not commit real models, real media, real reference corpora, or local benchmark reports.
autostill generates source-language subtitles by default; translation is a separate explicit command.local-nllb-ct2 --from autofirst uses lightweight subtitle language detection. If Fast Sub cannot reliably inferen|zh|ja|ko, pass--from en|zh|ja|ko. Internally NLLB uses FLORES-200 codes:eng_Latn,zho_Hans,jpn_Jpan,kor_Hang.- Provider unification and legacy API/WhisperX cleanup are post-v0.
- Electron UI and Web UI are post-v0.
- New STT backends such as whisper.cpp, SenseVoice, Paraformer, Parakeet, ONNX, and TensorRT are post-v0.
- v0 does not bundle real models, benchmark media, benchmark reference corpora, or local reports.
- Real-model smoke tests are manual because they can require network, large downloads, and local hardware.
Default automated tests stay offline and do not download real models or media.
Manual real-model smoke:
uv run fast-sub --version
uv run fast-sub doctor
uv run fast-sub models list
uv run fast-sub providers list
uv run fast-sub auto tests/fixtures/sample.wav --dry-run --json
uv run fast-sub transcribe <real-local-sample> --model whisper-small --device auto
uv run fast-sub auto <real-local-sample> --yes
uv run fast-sub <real-local-sample> --yes
uv run fast-sub run <real-local-sample> --yes
uv run fast-sub bench <real-local-sample> --repeat 1 --profile auto --jsonGenerated model caches, media, benchmark outputs, and local reports should not be committed.