Skip to main content

Subtitle Translator

AI-powered subtitle translation for SRT files, supporting OpenAI and Google Gemini.


Status: Version 0.9.0 will be the first public release; PyPI publication is still pending. Install from a local checkout or built wheel until it is published. See Installation.


Key capabilities

  • Translates SRT subtitle files between any language pair supported by your provider
  • Preserves subtitle indices, timestamps, formatting, and line breaks
  • Supports OpenAI and Google Gemini (provider-neutral core)
  • Optional glossary for approved terminology
  • Optional rolling context for consistent terminology within a file
  • Optional consistency report — advisory AI review highlighting possible inconsistencies
  • Standalone review command for reviewing existing translated files without retranslating
  • Cross-provider review — translate with one provider, review with another
  • Resumes after interruption; atomic output writes; never overwrites existing files

Requirements

  • Python 3.11, 3.12, or 3.13
  • At least one provider SDK installed (see Installation):
    • OpenAI: pip install "subtranslate-ai[openai]"
    • Gemini: pip install "subtranslate-ai[gemini]"
  • A valid API key for each provider you use

Installation

Version 0.9.0 is the upcoming first public release and has not been published to PyPI yet. Install from a local checkout or a built wheel until then.

Clone and create a virtual environment:

git clone https://github.com/dhofverberg/subtitle-translator.git
cd subtitle-translator
python -m venv .venv

Activate on macOS or Linux:

source .venv/bin/activate

Activate on Windows PowerShell:

.venv\Scripts\Activate.ps1

Install the provider you need:

# OpenAI only
pip install -e ".[openai]"

# Gemini only
pip install -e ".[gemini]"

# Both providers
pip install -e ".[all]"

# Both providers plus development tools
pip install -e ".[all,dev]"

After the first public release (not yet available):

# These commands will work once the package is published to PyPI:
# pip install "subtranslate-ai[openai]"
# pip install "subtranslate-ai[gemini]"
# pip install "subtranslate-ai[all]"

Quick start

OpenAI

# Set your API key
export OPENAI_API_KEY="your_api_key_here"   # macOS / Linux
# $env:OPENAI_API_KEY = "your_api_key_here"  # Windows PowerShell

# Translate a subtitle file (default: English → Swedish)
subtitle-translator translate movie.srt \
  --source-language English \
  --target-language French

Output is written to movie.translated.srt in the same directory.

Gemini

# Set your API key
export GEMINI_API_KEY="your_api_key_here"   # macOS / Linux
# $env:GEMINI_API_KEY = "your_api_key_here"  # Windows PowerShell

# Translate using Gemini
subtitle-translator translate movie.srt \
  --provider gemini \
  --source-language English \
  --target-language French

Provider configuration

Selecting a provider

Use --provider to choose the translation provider. The default is openai. Provider names are case-insensitive.

subtitle-translator translate movie.srt --provider gemini ...

Environment variables

Variable Provider Purpose
OPENAI_API_KEY OpenAI API authentication (required)
OPENAI_MODEL OpenAI Default translation model
OPENAI_REVIEW_MODEL OpenAI Default consistency-review model
GEMINI_API_KEY Gemini API authentication (required)
GEMINI_MODEL Gemini Default translation model
GEMINI_REVIEW_MODEL Gemini Default consistency-review model

Default models

The default models are defined in the application configuration. They may change between releases. Check subtitle-translator translate --help for the current defaults. Use --model or the environment variables above to override them.

Note: Model availability, cost, token limits, and translation quality vary by provider and account type. Choose models supported by your account. The tool does not fall back between providers automatically.

Overriding models

Use --model to override the translation model for a single command:

subtitle-translator translate movie.srt --provider openai --model gpt-4o ...

Use --review-model to override only the consistency-review model:

subtitle-translator translate movie.srt \
  --provider openai --model gpt-4o \
  --review-provider gemini --review-model gemini-2.5-pro \
  --consistency-report movie.consistency.md

Cross-provider review

Translate with one provider and review with another using --review-provider. Cross-provider workflows require credentials and installed extras for both providers.

subtitle-translator translate movie.srt \
  --provider gemini \
  --review-provider openai \
  --source-language English \
  --target-language Swedish \
  --consistency-report movie.consistency.md

Common workflows

All examples assume the subtitle file exists and no output file exists yet.

Basic OpenAI translation

subtitle-translator translate movie.srt \
  --source-language English \
  --target-language French

Basic Gemini translation

subtitle-translator translate movie.srt \
  --provider gemini \
  --source-language English \
  --target-language French

Explicit output path

subtitle-translator translate movie.en.srt \
  --output movie.fr.srt \
  --source-language English \
  --target-language French

Custom batch size

subtitle-translator translate movie.srt \
  --batch-size 10 \
  --source-language English \
  --target-language German

Disable rolling context

subtitle-translator translate movie.srt \
  --context-size 0 \
  --source-language English \
  --target-language Swedish

Using a glossary

subtitle-translator translate movie.srt \
  --glossary glossary.en-sv.json \
  --source-language English \
  --target-language Swedish

Translation plus consistency report

subtitle-translator translate movie.srt \
  --source-language English \
  --target-language Swedish \
  --consistency-report movie.consistency.md

Standalone consistency review

subtitle-translator review movie.en.srt movie.sv.srt \
  --source-language English \
  --target-language Swedish \
  --consistency-report movie.consistency.md

Gemini translation with OpenAI review

subtitle-translator translate movie.srt \
  --provider gemini \
  --review-provider openai \
  --source-language English \
  --target-language Swedish \
  --consistency-report movie.consistency.md

OpenAI translation with Gemini review

subtitle-translator translate movie.srt \
  --provider openai \
  --review-provider gemini \
  --source-language English \
  --target-language Swedish \
  --consistency-report movie.consistency.md

Explicit translation and review models

subtitle-translator translate movie.srt \
  --provider openai --model gpt-4o \
  --review-provider gemini --review-model gemini-2.5-pro \
  --source-language English \
  --target-language Swedish \
  --consistency-report movie.consistency.md

Legacy positional syntax

The original command style (without a translate subcommand) is preserved for backward compatibility:

subtitle-translator movie.srt --source-language English --target-language Swedish

Glossary

A glossary supplies approved source-to-target terminology as a UTF-8 JSON file.

JSON shape

{
  "source_language": "English",
  "target_language": "Swedish",
  "terms": [
    { "source": "warp drive", "target": "warpdrift" },
    { "source": "First Officer", "target": "sekond" }
  ]
}

The source_language and target_language fields must match the --source-language and --target-language values you pass on the command line. The comparison is case-insensitive and trims whitespace.

Behavior

  • Glossary terms guide the model toward consistent terminology. They are not literal search-and-replace rules.
  • Normal grammar and inflection apply: "warp drive" → "warpdrift" may still appear inflected as appropriate.
  • Glossary priority is higher than rolling context: when the same concept appears in both, the glossary term takes precedence.
  • Ambiguous proper nouns or relationship terms may not be resolved consistently if the glossary does not explicitly cover them.

Failure behavior

If the glossary file cannot be read, is not valid JSON, or has mismatched language fields, the command fails immediately before making any API calls.

Example

subtitle-translator translate samples/openai_smoke_test.srt \
  --source-language English \
  --target-language Swedish \
  --glossary samples/glossary.en-sv.json

Rolling context

Each translation batch optionally receives recently accepted translations from the current file as read-only reference material.

  • Context contains previously accepted subtitle pairs from the current run only. It is not persistent translation memory.
  • It is read-only: the model uses it as guidance, not as a mandatory rule.
  • It is local to the current file and run. Different runs start fresh.
  • Context can help resolve pronouns, recurring names, and ambiguous relationship terms. For example, if an earlier subtitle establishes "grandmother" as Swedish mormor (mother's mother), a later batch may consistently use the same term.
  • --context-size 0 disables rolling context entirely.
  • Larger context values may increase provider input usage and cost.
  • Context does not replace an explicit glossary.
# Use a context window of 20 recently translated entries
subtitle-translator translate movie.srt --context-size 20

# Disable context
subtitle-translator translate movie.srt --context-size 0

Consistency reports

Combined translation + review

Add --consistency-report to generate an advisory review after translation:

subtitle-translator translate movie.srt \
  --source-language English \
  --target-language Swedish \
  --consistency-report movie.consistency.md
  • The review runs after the translated SRT has been saved.
  • The report is a Markdown file listing possible inconsistencies for human inspection.
  • The review never modifies the translated SRT.
  • All findings are advisory. Film context may be needed to interpret them. False positives are possible.
  • Review incurs separate paid API calls.

Example finding

A report might note that the English word "grandmother" appears in subtitles 10, 20, and 30, translated as Swedish farmor (father's mother) in some places and mormor (mother's mother) in others, and ask whether the references all concern the same person. This is not a claim that an error was made — it is a prompt for the user to verify.

Review failure

If the review fails after translation, the translated SRT is preserved. The review failure is reported as an error. Use the standalone review command to retry the review later.


Standalone review

Review existing SRT files without retranslating:

subtitle-translator review movie.en.srt movie.sv.srt \
  --source-language English \
  --target-language Swedish \
  --consistency-report movie.consistency.md

Use --provider to select the review provider (default: openai).

Requirements

Both files must have:

  • The same number of subtitles
  • Matching subtitle indices (IDs)
  • Identical start and end timestamps for each pair

If the files do not match, the command fails before making any API calls.

Difference: translate with report vs. standalone review

translate --consistency-report review
Input Source SRT Source + translated SRT
Translation Yes No
Output files Translated SRT + report Report only
Use case Full workflow Retry review, external files

Output safety

  • Existing output files are not overwritten by default. Use --output to specify a new path.
  • Existing consistency report files are not overwritten. Specify a new path.
  • Output writes use atomic rename where the OS supports it.
  • Source SRT files are never modified.
  • If a review fails after translation, the translated SRT is preserved.
  • Keep your originals and backups regardless.

Cost, privacy, and API considerations

Important: Subtitle text is sent to external API providers. Review these considerations before translating sensitive content.

  • Subtitle text is transmitted to the selected provider (OpenAI or Google).
  • Glossary terms and rolling context data are also sent as part of each translation request.
  • Standalone review sends both source and translated subtitle text.
  • Cross-provider workflows may send content to two providers.
  • You are responsible for reviewing each provider's terms of service, data retention policies, data-control settings, regional requirements, and billing.
  • The tool cannot guarantee a specific cost. Batch size, context size, review chunking, model choice, and subtitle length all influence token usage.
  • Transport encryption (HTTPS) does not mean your content is private. Consult your provider's data-processing agreements for details.
  • The application does not log API keys. You are responsible for protecting your local environment and configuration files.

Troubleshooting

command not found: subtitle-translator

Ensure the virtual environment is activated and the package is installed:

pip show subtranslate-ai
subtitle-translator --help

Missing provider SDK

Error: OpenAI support is not installed. Install subtranslate-ai[openai].
Error: Gemini support is not installed. Install subtranslate-ai[gemini].

Install the required extra:

pip install -e ".[openai]"   # or [gemini] or [all]

Missing API key

OpenAI requires OPENAI_API_KEY. Gemini requires GEMINI_API_KEY.

# macOS / Linux
export OPENAI_API_KEY="your_key_here"
export GEMINI_API_KEY="your_key_here"

# Windows PowerShell
$env:OPENAI_API_KEY = "your_key_here"
$env:GEMINI_API_KEY = "your_key_here"

Invalid or unavailable model

Check that the model name is correct and available on your account. Use --model to override the default.

Output file already exists

Error: Output file already exists: movie.translated.srt

Delete the existing file or specify a different output path with --output.

Consistency report already exists

Error: Consistency report already exists: movie.consistency.md

Delete the existing report or specify a new path.

Glossary language mismatch

Ensure source_language and target_language in your glossary JSON match the --source-language and --target-language values exactly (case-insensitive).

Incompatible source and translated files in standalone review

Both files must have the same subtitle count, matching IDs, and identical timestamps for each entry.

Provider returned an invalid or blocked response

Try a smaller batch size (--batch-size) or check your provider's content moderation settings.

Translation succeeded but review failed

The translated SRT is preserved. Retry the review with the review command:

subtitle-translator review movie.en.srt movie.translated.srt \
  --source-language English \
  --target-language Swedish \
  --consistency-report movie.consistency.md

Unicode display in the terminal

If translated text looks garbled in the terminal but the SRT file opens correctly in a text editor, this is a terminal encoding issue. Files are written as UTF-8 regardless of terminal display.

Getting help

subtitle-translator --help
subtitle-translator translate --help
subtitle-translator review --help
subtitle-translator --version

Development

See CONTRIBUTING.md for full setup instructions.

git clone https://github.com/dhofverberg/subtitle-translator.git
cd subtitle-translator
python -m venv .venv
source .venv/bin/activate          # or .venv\Scripts\Activate.ps1 on Windows
pip install -e ".[all,dev]"
pytest
ruff check .
python -m build
python -m twine check dist/*

See docs/architecture.md for the internal design.


Contributing

See CONTRIBUTING.md.

Bug reports and feature requests: GitHub Issues


Security

See SECURITY.md for the supported-version policy and instructions for reporting vulnerabilities privately.


License

MIT

Download files

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

Source Distribution

subtranslate_ai-0.9.0.tar.gz (66.8 kB view details)

Uploaded Source

Built Distribution

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

subtranslate_ai-0.9.0-py3-none-any.whl (40.0 kB view details)

Uploaded Python 3

File details

Details for the file subtranslate_ai-0.9.0.tar.gz.

File metadata

  • Download URL: subtranslate_ai-0.9.0.tar.gz
  • Upload date:
  • Size: 66.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for subtranslate_ai-0.9.0.tar.gz
Algorithm Hash digest
SHA256 c9bc7ca5cf0e93cdf44d8606835d9d1c33c55a8c844b36daabc2901905e4ce99
MD5 139b3d3bc60be4990fcded1f7fdfb474
BLAKE2b-256 be18f05e45ec967a29725442cf5a632b3594d757a61a9884354fd5d9322252fb

See more details on using hashes here.

Provenance

The following attestation bundles were made for subtranslate_ai-0.9.0.tar.gz:

Publisher: release.yml on dhofverberg/subtitle-translator

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

File details

Details for the file subtranslate_ai-0.9.0-py3-none-any.whl.

File metadata

File hashes

Hashes for subtranslate_ai-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ac43bfe2e341025d5701f7c1a42946ff585a773cc34f01905ee7cfbf7cb00f2f
MD5 5d6113422a07d662d242ff8027837373
BLAKE2b-256 3c8a1c931871b263184c4bf1ecc9ff0ecbd2926abbef921b7dd06ebe5162eed0

See more details on using hashes here.

Provenance

The following attestation bundles were made for subtranslate_ai-0.9.0-py3-none-any.whl:

Publisher: release.yml on dhofverberg/subtitle-translator

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

Release history Release notifications | RSS feed

This release

0.9.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page