Skip to content

rromanv/srtforge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

srtforge

Generate, translate, and burn .srt subtitles locally on Apple Silicon.

srtforge extracts audio with ffmpeg, transcribes it with local MLX Whisper, optionally re-cues the captions for readability, and can translate subtitles with a local MLX language model. No cloud APIs or keys are required.

Features

  • Local Whisper transcription through mlx-whisper
  • Sentence-aware subtitle cueing from word timestamps
  • Standard SRT output
  • Optional local LLM translation with timestamp preservation
  • Optional hard-subtitle burn-in through ffmpeg/libass
  • Installable Python CLI: srtforge

Requirements

  • macOS on Apple Silicon
  • Python 3.10, 3.11, or 3.12
  • ffmpeg on your PATH
  • Enough disk/RAM for the models you choose

The default transcription model is mlx-community/whisper-large-v3-turbo. The default translation model is mlx-community/gemma-4-26b-a4b-it-4bit.

First use downloads models from Hugging Face into the local cache. Later runs can use the cached models.

By default, Hugging Face model files are stored outside this project in your user cache, normally under:

~/.cache/huggingface/hub

You can move that cache by setting Hugging Face cache environment variables such as HF_HOME or HUGGINGFACE_HUB_CACHE. srtforge does not store downloaded models in the repository or next to your videos. Temporary extracted WAV files are created in the system temp directory and deleted after each run.

Install

From GitHub:

pipx install --python python3.11 git+https://github.com/rromanv/srtforge.git

srtforge currently supports Python 3.10-3.12. If your default Python is newer than that, such as Python 3.14, pass a supported interpreter explicitly with --python.

Or into a virtual environment:

python3.11 -m venv .venv
source .venv/bin/activate
pip install git+https://github.com/rromanv/srtforge.git

For local development:

git clone https://github.com/rromanv/srtforge.git
cd srtforge
python3.11 -m venv .venv
source .venv/bin/activate
pip install -e .

After a PyPI release:

pipx install --python python3.11 srtforge

Troubleshooting

pipx uses Python 3.13 or newer

If installation fails because your default Python is outside the supported range, install a supported Python and tell pipx to use it:

python3.11 --version
pipx install --python python3.11 git+https://github.com/rromanv/srtforge.git

If python3.11 is not installed, install Python 3.11 or 3.12 first, then rerun the pipx install --python ... command.

Usage

Generate subtitles next to a video:

srtforge video.mp4

Write to a custom path:

srtforge video.mp4 -o captions.srt

Force the source language:

srtforge video.mp4 -l en

Use another Whisper model:

srtforge video.mp4 -m mlx-community/whisper-small

Disable sentence-aware re-cueing:

srtforge video.mp4 --no-resegment

Tune subtitle readability:

srtforge video.mp4 --max-line-length 37 --max-lines 2 --reading-speed 15

Translate subtitles:

srtforge video.mp4 -t Spanish
srtforge video.mp4 -t "Brazilian Portuguese"
srtforge video.mp4 -t ja --translate-model mlx-community/Qwen3.5-9B-OptiQ-4bit

Burn subtitles into a video:

srtforge merge video.mp4 video.srt -o final.mp4
srtforge merge video.mp4 video.es.srt --crf 16 --font-size 26

Run:

srtforge --help
srtforge merge --help

Readability

By default, srtforge asks Whisper for word-level timestamps and rebuilds cues so they are easier to read:

  • cues prefer sentence boundaries
  • lines are wrapped to two lines of 42 characters by default
  • long sentences are split across cue boundaries
  • cues are paced around 17 characters per second
  • cues are adjusted to avoid overlap

Translated subtitles are re-fitted after translation because translated text can be longer or shorter than the source.

ffmpeg Notes

Audio extraction requires ffmpeg.

Burn-in uses ffmpeg's subtitles filter, which requires libass. If your ffmpeg does not include it, install a full build such as:

nb install ffmpeg-full

Project Layout

src/srtforge/
  audio.py       # ffmpeg audio extraction
  transcribe.py  # MLX Whisper transcription
  segment.py     # sentence-aware re-cueing, wrapping, pacing
  translate.py   # context-aware local-LLM translation
  merge.py       # burn subtitles into video with ffmpeg/libass
  srt.py         # SRT rendering
  cli.py         # argparse CLI
tests/
  test_cli.py
  test_merge.py
  test_segment.py
  test_srt.py

Development

Run the test suite:

python -m unittest discover -s tests

Build release artifacts:

python -m build
python -m twine check dist/*

Publish to PyPI manually:

python -m twine upload dist/*

The repository also includes a GitHub Actions workflow for publishing to PyPI when a release is created. It uses PyPI Trusted Publishing, so no PyPI API token is needed in GitHub.

Before creating a release that should publish to PyPI, configure a pending publisher in your PyPI account:

PyPI project name: srtforge
Owner: rromanv
Repository name: srtforge
Workflow filename: publish.yml
Environment name: pypi

PyPI docs:

License

MIT

About

Generate, translate, and burn SRT subtitles locally with MLX Whisper.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages