Advanced subtitle translator with LLM support for converting SRT to bilingual ASS files using OpenAI, Gemini, or DeepSeek APIs
Project description
AI Subtitle Translator
Advanced subtitle translator with AI support and web API. Converts SRT subtitle files to styled ASS format with bilingual or monolingual translations using OpenAI, Google Gemini, or DeepSeek APIs.
Features
- Bazarr Integration: Direct post-processing hook for automatic subtitle translation
- Web API: FastAPI-based REST API for subtitle translation
- CLI Tool: Command-line interface for batch processing
- Multiple AI Providers: OpenAI, Google Gemini, DeepSeek support
- Bilingual Mode: Displays original text on top and translated text below
- Monolingual Mode: Replaces original text with translation
- Monolingual Extraction: Convert existing bilingual files to monolingual without re-translating
- Smart Translation: Full text or selective difficulty translation modes
- Resumable: Automatically saves progress and can resume if interrupted
- Batch Processing: Processes subtitles in batches for efficient API usage
Quick Start - Bazarr Integration
1. Docker Compose Setup
-
Clone the repository:
git clone https://github.com/yanp/ai-subtitle-translator.git cd ai-subtitle-translator
-
Set up environment variables:
cp .env.example .env # Edit .env and add: DEEPSEEK_API_KEY=your_actual_api_key_here
-
Start the service:
docker-compose up -d
2. Bazarr Hook Configuration
In Bazarr Settings → Subtitles → Custom Post-Processing → Command:
curl -X POST "http://ai-subtitle-translator:8080/translate" -d input_path="{{subtitles}}";
3. Integration with Existing Bazarr
If you already have Bazarr running, add the translator to your existing docker-compose:
services:
subtitle-translator:
build: .
ports:
- "8000:8080"
environment:
- DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
volumes:
- /path/to/media:/media/subtitles # Same mount as Bazarr
restart: unless-stopped
networks:
- media-network
Alternative Setup Methods
Local Development
-
Install uv:
curl -LsSf https://astral.sh/uv/install.sh | sh
-
Install dependencies:
uv sync --all-extras
-
Set environment variables:
export DEEPSEEK_API_KEY=your_api_key_here
-
Run the API:
uv run fastapi dev src/ai_subtitle_translator/app.py
CLI Usage
Translation:
uv run ai-subtitle-translator input.srt [options]
Options:
-o, --output: Output file path--translation-mode:bilingualormonolingual--prompt-template:full_textorselective_difficulty-p, --provider: AI provider (openai,gemini,deepseek)
Translation Example:
uv run ai-subtitle-translator movie.srt \
--translation-mode bilingual \
--provider deepseek
Extraction from Bilingual Files:
# Extract monolingual subtitles from existing bilingual ASS files
uv run ai-subtitle-translator movie.en-zh.ass --extract-monolingual
This extracts only the translated text with proper monolingual styling and positioning, perfect when you want monolingual versions without re-translating.
API Usage
Translate Subtitle File
POST /translate
Supports two modes: file upload or file path processing.
Mode 1: File Upload (Web Interface)
Upload an SRT file and get back a translated ASS file.
Parameters:
file: SRT subtitle file to uploadprovider: AI provider (openai,gemini,deepseek) - default:deepseekmodel: Specific model name (optional)translation_mode:bilingualormonolingual- default:bilingualprompt_template:full_textorselective_difficulty- default:selective_difficultybatch_size: Number of lines per API call - default:50
Example:
curl -X POST "http://localhost:8080/translate" \
-F "file=@subtitle.srt" \
-F "provider=deepseek" \
-F "translation_mode=bilingual" \
-F "prompt_template=selective_difficulty" \
-o translated_subtitle.ass
Mode 2: File Path (For Bazarr Integration)
Process files on the server filesystem using file paths.
Parameters:
input_path: Path to SRT subtitle file on serveroutput_path: Output path for translated file (optional, defaults to same directory with .en-zh.ass extension)provider: AI provider (openai,gemini,deepseek) - default:deepseektranslation_mode:bilingualormonolingual- default:bilingualprompt_template:full_textorselective_difficulty- default:selective_difficulty
Example:
curl -X POST "http://localhost:8000/translate" \
-F "input_path=/media/subtitles/movie.srt" \
-F "provider=deepseek" \
-F "translation_mode=bilingual"
Response:
{
"success": true,
"message": "✅ Translation completed successfully",
"output_filename": "/media/subtitles/movie.en-zh.ass"
}
Get Available Providers
GET /providers
Returns available AI providers and their configuration status.
Configuration
Environment Variables
| Variable | Description | Required |
|---|---|---|
DEEPSEEK_API_KEY |
DeepSeek API key (recommended) | Yes |
OPENAI_API_KEY |
OpenAI API key | For OpenAI provider |
GEMINI_API_KEY |
Google Gemini API key | For Gemini provider |
PUID |
User ID for file permissions | Optional (default: 1000) |
PGID |
Group ID for file permissions | Optional (default: 1000) |
Note: Set PUID/PGID to match your host user to avoid permission issues:
# Find your user/group IDs
id
# Set in .env file
PUID=1001
PGID=1001
Translation Modes
- Bilingual: Shows original text on top, translation below
- Monolingual: Replaces original text with translation
Prompt Templates
- Full Text: Translates every subtitle line
- Selective Difficulty: Only translates complex phrases, slang, or cultural references
Development
Setup
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install dependencies
uv sync --all-extras --dev
Code Quality
# Format code
uv run black .
# Lint code
uv run ruff check .
# Type checking
uv run mypy .
Testing
# Run tests
uv run pytest
# Run with coverage
uv run pytest --cov=src
Health Monitoring
Check service health:
curl http://localhost:8080/health
Check available providers:
curl http://localhost:8080/providers
Performance
- Translation Speed: ~5-30 seconds per file (depends on length)
- API Costs: ~$0.001-0.01 per subtitle file with DeepSeek
- Batch Processing: Optimized for efficiency
Docker Build
Build locally
docker build -t ai-subtitle-translator .
License
MIT License - see LICENSE file for details.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
Support
- Open an issue on GitHub
- Check the API documentation at
/docswhen running the server - Review the example files in the repository
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ai_subtitle_translator-0.6.0.tar.gz.
File metadata
- Download URL: ai_subtitle_translator-0.6.0.tar.gz
- Upload date:
- Size: 86.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15ad9f656a818925917955cda13a6b0212f3929827a688625b2c9e56051c15c4
|
|
| MD5 |
eb4a96bc9697f94a7e388c7e11ef62e3
|
|
| BLAKE2b-256 |
df481098c66872b1e4ea547351ab541551aca37170dc047115620de2bfd6b834
|
Provenance
The following attestation bundles were made for ai_subtitle_translator-0.6.0.tar.gz:
Publisher:
build-and-publish.yaml on yanp/ai-subtitle-translator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ai_subtitle_translator-0.6.0.tar.gz -
Subject digest:
15ad9f656a818925917955cda13a6b0212f3929827a688625b2c9e56051c15c4 - Sigstore transparency entry: 359360840
- Sigstore integration time:
-
Permalink:
yanp/ai-subtitle-translator@e1a0339cd5f95d068826ea23155447d8a20f7b17 -
Branch / Tag:
refs/tags/0.6.0 - Owner: https://github.com/yanp
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build-and-publish.yaml@e1a0339cd5f95d068826ea23155447d8a20f7b17 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ai_subtitle_translator-0.6.0-py3-none-any.whl.
File metadata
- Download URL: ai_subtitle_translator-0.6.0-py3-none-any.whl
- Upload date:
- Size: 35.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cdd870ec1f5280146e88dabb62de50612dcda16e76a235329ecefeb459aab57e
|
|
| MD5 |
960787892a6ffb6f22f58bd5f8209c16
|
|
| BLAKE2b-256 |
c5c0ff7d3b93b32b61c45fd14eac61121408de5566016a75b143930144a2a3e1
|
Provenance
The following attestation bundles were made for ai_subtitle_translator-0.6.0-py3-none-any.whl:
Publisher:
build-and-publish.yaml on yanp/ai-subtitle-translator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ai_subtitle_translator-0.6.0-py3-none-any.whl -
Subject digest:
cdd870ec1f5280146e88dabb62de50612dcda16e76a235329ecefeb459aab57e - Sigstore transparency entry: 359360876
- Sigstore integration time:
-
Permalink:
yanp/ai-subtitle-translator@e1a0339cd5f95d068826ea23155447d8a20f7b17 -
Branch / Tag:
refs/tags/0.6.0 - Owner: https://github.com/yanp
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build-and-publish.yaml@e1a0339cd5f95d068826ea23155447d8a20f7b17 -
Trigger Event:
push
-
Statement type: