LLM-powered subtitle translation microservice by LavX
A standalone microservice for translating subtitles using AI/LLM via OpenRouter API. Originally created for LavX's Bazarr fork but designed as a flexible API that can be integrated with any subtitle management system.
- 🤖 AI-Powered Translation: Leverage state-of-the-art LLMs for high-quality subtitle translations
- 🌍 Multi-language Support: Translate between any language pairs supported by modern LLMs
- 🚀 OpenRouter Integration: Access multiple AI providers (Google Gemini, Claude, GPT, Llama, etc.) through a single API
- 📁 SRT File Support: Full SRT subtitle file parsing and generation
- 🔄 Smart Batch Processing: Efficient batch processing for large subtitle files with retry logic
↔️ RTL Language Support: Automatic directional markers for right-to-left languages (Arabic, Hebrew, Persian, etc.)- 🔌 Universal API: RESTful API that integrates with any application - Bazarr, custom tools, or scripts
- 🐳 Docker Ready: Easy deployment with Docker and Docker Compose
- Clone the repository:
git clone https://github.com/LavX/ai-subtitle-translator.git
cd ai-subtitle-translator- Create a
.envfile from the example:
cp .env.example .env- Add your OpenRouter API key to
.env:
OPENROUTER_API_KEY=your_api_key_here- Start the service:
docker-compose up -dThe service will be available at http://localhost:8765
- Install Python 3.11+ and create a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate- Install dependencies:
pip install -r requirements.txt- Set environment variables:
export OPENROUTER_API_KEY=your_api_key_here- Run the service:
cd src && uvicorn subtitle_translator.main:app --host 0.0.0.0 --port 8765Once running, access the interactive API documentation at:
- Swagger UI:
http://localhost:8765/docs - ReDoc:
http://localhost:8765/redoc
| Method | Endpoint | Description |
|---|---|---|
GET |
/health |
Health check |
GET |
/api/v1/models |
List available AI models |
POST |
/api/v1/translate/content |
Translate subtitle lines |
POST |
/api/v1/translate/file |
Translate entire SRT file |
POST /api/v1/translate/content
Content-Type: application/json
{
"sourceLanguage": "en",
"targetLanguage": "es",
"title": "Breaking Bad",
"mediaType": "Episode",
"lines": [
{"position": 1, "line": "Hello, world!"},
{"position": 2, "line": "How are you?"}
]
}Response:
{
"lines": [
{"position": 1, "line": "¡Hola, mundo!"},
{"position": 2, "line": "¿Cómo estás?"}
],
"model_used": "google/gemini-2.5-flash-preview-09-2025",
"tokens_used": 150
}POST /api/v1/translate/file
Content-Type: application/json
{
"content": "1\n00:00:01,000 --> 00:00:04,000\nHello world\n\n2\n00:00:05,000 --> 00:00:08,000\nHow are you?\n",
"sourceLanguage": "en",
"targetLanguage": "es"
}Response:
{
"content": "1\n00:00:01,000 --> 00:00:04,000\nHola mundo\n\n2\n00:00:05,000 --> 00:00:08,000\n¿Cómo estás?\n",
"model_used": "google/gemini-2.5-flash-preview-09-2025",
"tokens_used": 200,
"subtitle_count": 2
}All configuration is done via environment variables:
| Variable | Description | Default |
|---|---|---|
OPENROUTER_API_KEY |
Your OpenRouter API key (required) | - |
OPENROUTER_DEFAULT_MODEL |
Default AI model for translation | amazon/nova-2-lite-v1:free |
OPENROUTER_TEMPERATURE |
Temperature for AI responses (0.0-2.0) | 0.3 |
OPENROUTER_MAX_TOKENS |
Maximum tokens per response | 8000 |
HOST |
Server host | 0.0.0.0 |
PORT |
Server port | 8765 |
BATCH_SIZE |
Lines per translation batch | 100 |
MAX_RETRIES |
Maximum retry attempts on failure | 3 |
RETRY_DELAY |
Initial delay between retries (seconds) | 1.0 |
REQUEST_TIMEOUT |
Request timeout (seconds) | 120.0 |
The service supports any model available on OpenRouter. Models have been extensively tested through a Battle Royale elimination process (5→10→20→30→40→50 lines at 80% translation threshold).
These models consistently delivered high-quality translations across all test rounds:
| Model | Avg Speed | Success Rate | Notes |
|---|---|---|---|
meta-llama/llama-4-maverick |
3s | 92% | 🥇 Fastest overall (1-4s) |
google/gemini-2.5-flash-lite-preview-09-2025 |
3.2s | 90% | 🥈 Very fast, reasoning support |
moonshotai/kimi-k2-0905:exacto |
4s | 92% | 🥉 Balanced speed & quality |
| Model | Avg Speed | Success Rate | Notes |
|---|---|---|---|
google/gemini-2.5-flash-preview-09-2025 |
8.5s | 92% | Default model, reasoning support |
anthropic/claude-haiku-4.5 |
13s | 93% | Highest quality, premium |
anthropic/claude-sonnet-4.5 |
18s | 92% | Premium, nuanced translations |
These free models survived ALL Battle Royale rounds:
| Model | Avg Speed | Success Rate | Notes |
|---|---|---|---|
amazon/nova-2-lite-v1:free |
17s | 95% | 🏆 Best free model! |
nex-agi/deepseek-v3.1-nex-n1:free |
35s | 90% | Reliable backup, slower |
These models failed Battle Royale Round 1 (0% translation or timeout):
| Model | Reason |
|---|---|
tngtech/deepseek-r1t-chimera:free |
0% translation output |
cognitivecomputations/dolphin-mistral-24b-venice-edition:free |
0% translation output |
nvidia/nemotron-3-nano-30b-a3b:free |
0% translation output |
allenai/olmo-3-32b-think:free |
Timeout |
openai/gpt-oss-120b:exacto |
Timeout |
x-ai/grok-4.1-fast |
Poor translation quality |
Need SPEED? → meta-llama/llama-4-maverick
Need QUALITY? → anthropic/claude-haiku-4.5
Need FREE? → amazon/nova-2-lite-v1:free (default)
Balanced? → google/gemini-2.5-flash-preview-09-2025
This service was designed for seamless integration with LavX's Bazarr fork:
- Deploy the AI Subtitle Translator service
- Configure Bazarr to use this service as a translation provider
- Enjoy AI-powered subtitle translations!
The REST API makes it easy to integrate with any application:
import httpx
async def translate_subtitles(lines, source_lang, target_lang):
async with httpx.AsyncClient() as client:
response = await client.post(
"http://localhost:8765/api/v1/translate/content",
json={
"sourceLanguage": source_lang,
"targetLanguage": target_lang,
"lines": [{"position": i, "line": line} for i, line in enumerate(lines)]
}
)
return response.json()# Create virtual environment
python -m venv venv
source venv/bin/activate
# Install development dependencies
pip install -e ".[dev]"pytest tests/ -v# Format code
black src/ tests/
ruff check src/ tests/ --fix
# Type checking
mypy src/ai-subtitle-translator/
├── Dockerfile
├── docker-compose.yml
├── pyproject.toml
├── requirements.txt
├── README.md
├── .env.example
├── src/
│ └── subtitle_translator/
│ ├── main.py # FastAPI application
│ ├── config.py # Configuration management
│ ├── api/
│ │ ├── routes.py # API endpoints
│ │ └── models.py # Pydantic models
│ ├── core/
│ │ ├── translator.py # Translation orchestration
│ │ ├── srt_parser.py # SRT file handling
│ │ └── batch_processor.py # Batch processing
│ └── providers/
│ ├── base.py # Abstract provider
│ └── openrouter.py # OpenRouter implementation
└── tests/
├── test_api.py
└── test_translator.py
MIT License - see LICENSE file for details.
This translator is maintained by LavX. Explore more of my projects and services:
- LavX Managed Systems – Enterprise AI solutions, RAG systems, and LLMOps.
- LavX News – Latest insights on AI, Open Source, and emerging tech.
- LMS Tools – 140+ free, privacy-focused online tools for developers and researchers.
- AI Subtitle Translator – LLM-powered subtitle translator using OpenRouter API.
- OpenSubtitles Scraper – Web scraper for OpenSubtitles.org (no VIP required).
- Bazarr (LavX Fork) – Automated subtitle management with OpenSubtitles.org scraper & AI translation.
- JFrog to Nexus OSS – Automated migration tool for repository managers.
- WeatherFlow – Multi-platform weather data forwarding (WU to Windy/Idokep).
- Like4Like Suite – Social media automation and engagement toolkit.
Created by LavX
- Originally developed for Bazarr
- Powered by OpenRouter for AI model access
- Built with FastAPI
Contributions are welcome! Feel free to:
- Report bugs
- Suggest features
- Submit pull requests
Made with ❤️ by LavX