AI-Powered Subtitle Generation with Translation
Project description
AI Sub: AI-Powered Subtitle Generation with Translation
Overview
AI Sub is a command-line tool that leverages Google's Gemini models to generate high-quality, audio-synchronized subtitles. It is designed to produce precise English and Japanese subtitles by analyzing both audio and visual cues.
Key Features:
- Multimodal Understanding: Utilizes video frames for context (e.g., identifying speakers, reading on-screen text) and audio for precise timing.
- Dual-Language Support: Generates verbatim transcriptions and translations for English and Japanese.
- Automatic Segmentation: Automatically splits long videos into smaller segments for efficient processing.
Showcase
Here's an example of subtitles generated by AI Sub:
For more examples, please visit ai-sub-showcase.
How It Works
- Preprocessing: The input video is segmented into smaller chunks to fit within API context windows and file size limits.
- AI Processing: Each segment is sent to Google Gemini. The AI analyzes the audio for speech and the video for context, following strict prompting rules to generate subtitles.
- Compilation: Generated subtitles from all segments are merged into a final, chronologically sorted SRT file.
Installation
Prerequisites: Python 3.10 or higher.
-
Set up a Python virtual environment:
python -m venv venv source venv/bin/activate # On Windows, use `venv\Scripts\activate.bat`
-
Install AI Sub:
pip install --upgrade ai-sub
Usage
You can use AI Sub with either a Google AI Studio API Key or the Gemini CLI.
Option 1: Using Google AI Studio API Key
-
Obtain your API Key:
- Sign in to Google AI Studio.
- Click "Create API Key".
- Copy and securely store your key. Never disclose your API key publicly.
-
Run the application:
ai-sub --ai.google.key YOUR_API_KEY --ai.model=google-gla:gemini-3-flash-preview "path/to/your/video.mp4"
Note: Replace
YOUR_API_KEYwith your actual key and"path/to/your/video.mp4"with the video file path.
Option 2: Using Gemini CLI
-
Install and Authenticate Gemini CLI:
- Install:
npm install -g @google/gemini-cli - Authenticate: Follow instructions at gemini-cli.
- Install:
-
Run the application:
ai-sub --ai.model=gemini-cli:gemini-3-flash-preview --split.re-encode.enabled=True "path/to/your/video.mp4"
Important Notes for CLI Mode:
- No API key is required; the tool uses your authenticated Gemini CLI instance.
- Additional arguments are required to split and re-encode the video because the Gemini CLI has a 20MB upload limit per chunk. The default re-encoding settings are aggressive and should work for most inputs.
- Re-encoding is resource-intensive and will increase processing time.
Configuration
All settings can be configured via command-line arguments (e.g., --ai.rpm 10) or environment variables with the AISUB_ prefix (e.g., AISUB_AI_RPM=10).
AI Settings (--ai.*)
| Argument | Description | Default |
|---|---|---|
--ai.model <model> |
A shorthand to set both pass1_model and pass2_model to the same value. |
None |
--ai.pass1-model <model> |
The AI model for the first pass of subtitle generation. Use 'google-gla:<model>' for Google models, 'openai:<model>' for OpenAI, or 'custom:<url>' for a custom endpoint. | google-gla:gemini-3-flash-preview |
--ai.pass2-model <model> |
The AI model for the second pass of subtitle generation (QA & Refinement). | google-gla:gemini-3-flash-preview |
--ai.rpm <int> |
Maximum requests per minute for the AI model. | 4 |
--ai.tpm <int> |
Maximum tokens per minute for the AI model. | 250000 |
Google AI Settings (--ai.google.*)
| Argument | Description | Default |
|---|---|---|
--ai.google.key <key> |
The API key for Google's generative language models. | None (loads from GOOGLE_API_KEY or GEMINI_API_KEY) |
--ai.google.file-cache-ttl <seconds> |
The time-to-live (TTL) in seconds for the Gemini file list cache. | 10 |
--ai.google.use-files-api <bool> |
Whether to use the Gemini Files API. | True |
--ai.google.base-url <url> |
The base URL for the Google AI API. | None |
Gemini CLI Settings (--ai.gemini-cli.*)
| Argument | Description | Default |
|---|---|---|
--ai.gemini-cli.timeout <seconds> |
The timeout in seconds for Gemini CLI operations. | 600 |
--ai.gemini-cli.overwrite-system-prompt <bool> |
Whether to overwrite the system prompt using GEMINI_SYSTEM_MD. |
False |
Splitting Settings (--split.*)
| Argument | Description | Default |
|---|---|---|
--split.max-seconds <seconds> |
The maximum duration in seconds for each video chunk. | 300 |
--split.start-offset-min <minutes> |
The number of minutes to skip from the beginning of the video. | 0 |
Re-Encode Settings (--split.re-encode.*)
| Argument | Description | Default |
|---|---|---|
--split.re-encode.enabled <bool> |
Re-encode the video chunks to save bandwidth. | False |
--split.re-encode.fps <int> |
The framerate to re-encode the video to. | 1 |
--split.re-encode.height <int> |
The height (resolution) to re-encode the video to. | 360 |
--split.re-encode.bitrate-kb <int> |
The bitrate in KB/s to re-encode the video to. | 35 |
--split.re-encode.threshold-mb <int> |
The threshold in MB for re-encoding. Files smaller than this will not be re-encoded. Set to 0 to re-encode everything. | 20 |
--split.re-encode.encoder <encoder> |
The specific encoder to use (e.g., 'h264_nvenc'). | None (auto-detected) |
Directory Settings (--dir.*)
| Argument | Description | Default |
|---|---|---|
--dir.tmp <path> |
Temporary directory for intermediate files. | tmp_<video_name> in output dir |
--dir.out <path> |
Output directory for the final subtitle files. | Same directory as input video |
Concurrency Settings (--thread.*)
| Argument | Description | Default |
|---|---|---|
--thread.uploads <int> |
The number of concurrent threads for uploading video segments. This is only used for Gemini (google-gla) models. | 4 |
--thread.re-encode <int> |
The number of concurrent threads for re-encoding video chunks. | 2 |
--thread.subtitles1 <int> |
The number of concurrent threads to use for Pass 1 (Transcription). | 4 |
--thread.subtitles2 <int> |
The number of concurrent threads to use for Pass 2 (QA). | 4 |
Retry Settings (--retry.*)
| Argument | Description | Default |
|---|---|---|
--retry.run <int> |
The maximum number of times to retry a failed job in this run of the program. | 3 |
--retry.max <int> |
The absolute maximum number of times a job can be retried in total. | 9 |
--retry.delay <seconds> |
The number of seconds to wait between retries. | 30 |
Logging Settings (--log.*)
| Argument | Description | Default |
|---|---|---|
--log.level <level> |
The minimum log level to display. | info |
--log.timestamps <bool> |
Whether to include timestamps in the console output. | False |
--log.scrub <bool> |
Whether to scrub sensitive data from logs. | True |
Known Limitations
- Timestamp Accuracy: Subtitle timestamps may occasionally be inaccurate. This is an inherent characteristic of the Gemini AI model. Shorter video segments generally yield better accuracy.
- AI Hallucinations: Like all LLMs, Gemini may occasionally produce "hallucinations" or inaccurate information.
If you encounter issues, consider re-processing specific video segments as detailed below.
Advanced: Re-processing Segments
Intermediate files are stored in a temporary directory (default: tmp_<input_file_name>). You can customize this location using the --dir.tmp flag.
To re-process a specific segment:
- Navigate to the temporary directory (default:
tmp_<input_file_name>). - Locate and delete the corresponding
part_XXX.jsonstate file for the segment you want to re-process. - Re-run the script. It will automatically detect the missing state file and re-process only that segment from the beginning.
Project details
Release history Release notifications | RSS feed
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_sub-2.2.0b1.tar.gz.
File metadata
- Download URL: ai_sub-2.2.0b1.tar.gz
- Upload date:
- Size: 36.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16b9db521752f0faaf345de078c57293fc06db319dd2662942a2ddefe2167caf
|
|
| MD5 |
b564d1f4cf06e331fcaabeb5495cc557
|
|
| BLAKE2b-256 |
b5b8f872062943f0c220f74dcaa6341d6561a1b03abcdbd0c6bceeab2443f998
|
Provenance
The following attestation bundles were made for ai_sub-2.2.0b1.tar.gz:
Publisher:
publish.yml on FlippFuzz/ai-sub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ai_sub-2.2.0b1.tar.gz -
Subject digest:
16b9db521752f0faaf345de078c57293fc06db319dd2662942a2ddefe2167caf - Sigstore transparency entry: 1069743780
- Sigstore integration time:
-
Permalink:
FlippFuzz/ai-sub@96ef9bc96c224ba1387c89ba24eba68e59e244a4 -
Branch / Tag:
refs/tags/v2.2.0b1 - Owner: https://github.com/FlippFuzz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@96ef9bc96c224ba1387c89ba24eba68e59e244a4 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ai_sub-2.2.0b1-py3-none-any.whl.
File metadata
- Download URL: ai_sub-2.2.0b1-py3-none-any.whl
- Upload date:
- Size: 37.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7c8269d45c42daf3bd7bd6b78b7169c13a6841f12f5af6c8bc1e859622755b4
|
|
| MD5 |
96cc7c049a094f9392efe35ed8e440b4
|
|
| BLAKE2b-256 |
073b44cd1bf23f8186a7eff227550c370e81a05a9dc0d70e83f1932e7d1bb69c
|
Provenance
The following attestation bundles were made for ai_sub-2.2.0b1-py3-none-any.whl:
Publisher:
publish.yml on FlippFuzz/ai-sub
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ai_sub-2.2.0b1-py3-none-any.whl -
Subject digest:
c7c8269d45c42daf3bd7bd6b78b7169c13a6841f12f5af6c8bc1e859622755b4 - Sigstore transparency entry: 1069743800
- Sigstore integration time:
-
Permalink:
FlippFuzz/ai-sub@96ef9bc96c224ba1387c89ba24eba68e59e244a4 -
Branch / Tag:
refs/tags/v2.2.0b1 - Owner: https://github.com/FlippFuzz
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@96ef9bc96c224ba1387c89ba24eba68e59e244a4 -
Trigger Event:
release
-
Statement type: