Skip to main content

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

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

srtforge-0.1.0.tar.gz (19.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

srtforge-0.1.0-py3-none-any.whl (19.0 kB view details)

Uploaded Python 3

File details

Details for the file srtforge-0.1.0.tar.gz.

File metadata

  • Download URL: srtforge-0.1.0.tar.gz
  • Upload date:
  • Size: 19.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for srtforge-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b441e23df6293a8c530479dcb5019f695658c7f44a5f09c451c7e854e3b4e111
MD5 5c08c14ab7fdbb6b11214e90861d6d19
BLAKE2b-256 5d4012f7d0ad99cd3be742756bf953881c896af29b91ed9009ba09f1dc0861bd

See more details on using hashes here.

Provenance

The following attestation bundles were made for srtforge-0.1.0.tar.gz:

Publisher: publish.yml on rromanv/srtforge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file srtforge-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: srtforge-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 19.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for srtforge-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2d2334bb17de0178d57ae26c0bece53e5460eb07a13dbb916009ad3f3471aeda
MD5 9e7bf946a5b8bff16882224a12baf92e
BLAKE2b-256 9cf6316dc3624b121be4ff67917a11abb8ff8dc2abbcbce86ab180a003d12a1e

See more details on using hashes here.

Provenance

The following attestation bundles were made for srtforge-0.1.0-py3-none-any.whl:

Publisher: publish.yml on rromanv/srtforge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page