docs.rs failed to build psyche-subtitle-toolkit-0.3.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build:
psyche-subtitle-toolkit-0.2.0
psyche-subtitle-toolkit
Extract, translate, and mux ASS, SRT, WebVTT, and PGS (bitmap) subtitles in MKV files. Built for Psyche but usable as a standalone CLI or Rust library.
No cloud required. No telemetry. Every translation provider is opt-in.
Features
- Extract ASS, SRT, WebVTT, and PGS subtitle tracks from MKV files via mkvmerge/mkvextract
- Translate subtitle dialogue through 7 pluggable providers
- Protect ASS override tags (
{\pos(...)},{\an7}, etc.) during translation - Automatic chunking (200 lines per request) for LLM context limits
- Concurrent chunk translation with configurable parallelism
- Retry with exponential backoff on HTTP, provider, and malformed output errors
- Mux translated subtitles back into the MKV, replacing the original track
- Process single files or entire directories
- Translate standalone
.ass,.srt, and.vttfiles without MKV (viatranslate-asssubcommand) - OCR PGS bitmap subtitles via PaddleOCR PP-OCRv5 (auto-downloads models on first run)
- Resume interrupted translations with
--resume
Supported Providers
| Provider | Flag | Auth | --parallel |
Notes |
|---|---|---|---|---|
| Ollama | --provider ollama |
None | 3 | Default. Any Ollama model. |
| Anthropic | --provider anthropic |
--api-key |
2 | Messages API. Custom endpoint via --anthropic-url. |
| OpenAI | --provider openai |
--api-key |
2 | Compatible with any OpenAI-compatible API. |
| OpenRouter | --provider openrouter |
--api-key |
2 | 400+ models, including free models. |
| DeepL | --provider deepl |
--api-key |
5 | Free tier (500K chars/month) or pro tier. |
| Google Translate | --provider google |
--api-key |
10 | v2 API. First 500K chars/month free. |
| Gemini | --provider gemini |
--api-key |
2 | LLM-based. 1,500 req/day free on Flash models. |
The --parallel column shows recommended concurrency for each provider.
Installation
Or build from source:
Requirements
mkvmergeandmkvextractfrom MKVToolNix must be in yourPATH.
CLI Usage
Inspect MKV tracks
Output shows all tracks with a * marking the selected ASS subtitle track:
* track 2: type=subtitles codec=SubStationAlpha language=eng name=HIDIVE_English
track 3: type=subtitles codec=SubStationAlpha language=jpn name=
Translate subtitles
# Ollama (default, local)
# OpenAI
# DeepL (free tier)
# Google Translate
# Gemini
# OpenRouter (free model)
Translate standalone subtitle files
# ASS file
# SRT file (auto-detected by extension or content)
# WebVTT file (auto-detected by extension or WEBVTT header)
Resume interrupted translations
If a batch run is interrupted (crash, network failure), restart with --resume to skip already-translated files:
# First run — interrupted at file 15/20
# Restart — skips files 1-14, continues from 15
Progress is saved to .psyche-subtitle-toolkit-progress.json in the input directory and auto-deleted when all files complete.
Full options
-i, --input <INPUT> MKV file or directory containing MKV files
--to <TO> Target language code (e.g. pt-BR, en, ja)
--provider <PROVIDER> Translation backend [default: ollama]
--track <TRACK> Specific subtitle track ID to translate
--model <MODEL> Model name [default: llama3.1]
--ollama-url <URL> Ollama base URL [default: http://localhost:11434]
--openai-url <URL> OpenAI base URL [default: https://api.openai.com]
--anthropic-url <URL> Anthropic base URL [default: https://api.anthropic.com]
--api-key <KEY> API key (required for openai, openrouter, anthropic, deepl, google, gemini)
--deepl-url <URL> DeepL base URL [default: https://api-free.deepl.com]
--keep-temp Preserve extracted/translated ASS files
--dry-run Show what would be translated without modifying files
--source-lang <LANG> Source language code (e.g. en, ja)
--resume Save progress and skip already-translated files on restart
--parallel <N> Max concurrent chunk translations [default: 1]
Library Usage
Add to your Cargo.toml:
[]
= { = "../psyche-subtitle-toolkit" }
Translate an MKV file
use Arc;
use ;
# async
Translate ASS content directly
use Arc;
use ;
# async
Implement a custom provider
use async_trait;
use ;
How It Works
- Inspect --
mkvmerge -Jidentifies tracks and selects the ASS, SRT, or VTT subtitle - Extract --
mkvextract trackspulls the ASS file to a temp directory - Parse -- The ASS parser reads dialogue lines, preserving headers and styles
- Strip tags -- ASS override tags (
{\pos(...)},{\an7}) are removed and stored - Chunk -- Cues are split into 200-line batches
- Translate -- Each chunk is sent to the provider as
<N> textnumbered lines (concurrent if--parallel > 1) - Retry -- Failed chunks (HTTP errors, malformed output) are retried up to 3 times with exponential backoff
- Apply -- Translated text is mapped back to cues by ID
- Reinject tags -- Original override tags are prepended back
- Mux --
mkvmergereplaces the original subtitle track in-place
Testing
Provider tests use wiremock to mock HTTP endpoints -- no real API calls.
Release Notes
v0.3.0
- PGS OCR — bitmap subtitle recognition via PaddleOCR PP-OCRv5 (auto-downloads models)
- PGS track auto-detection in MKV files
- New dependencies:
pgs-rs,ocr-rs,image,imageproc
v0.2.0
- SRT support — parse, translate, and render SubRip subtitles
- WebVTT support — parse, translate, and render WebVTT subtitles
- Anthropic provider — Messages API (
/v1/messages) with custom endpoint support - Remove
--source-lang— all providers auto-detect source language, making the flag redundant - Format auto-detection —
translate-assCLI auto-detects ASS/SRT/VTT by extension or content - MKV format priority — ASS > SRT > VTT when multiple subtitle tracks exist
- Refactored pipeline —
translate_document()helper shared by ASS, SRT, and VTT pipelines
v0.1.0
Initial release:
- 7 translation providers (Ollama, OpenAI, OpenRouter, DeepL, Google, Gemini)
--parallel Nfor concurrent chunk translation--resumefor interrupted batch recovery--dry-runto preview without modifying files- Retry with exponential backoff on HTTP and malformed output errors
- DeepL/Google batch mode (per-line array elements)
- 200 lines per chunk
- Progress output to stderr
translate-asssubcommand for standalone subtitle files