README.md

March 7, 2026 · View on GitHub

AutoSubtitle Icon

AutoSubtitle

AI-powered video subtitle generator with translation
Speech recognition (Whisper) + LLM translation + SRT generation, all in one GUI.

FeaturesScreenshotsInstallationUsageBuild macOS AppProject StructureFAQLicense


Features

  • Speech Recognition — Powered by faster-whisper (CTranslate2), runs locally on CPU with no cloud dependency
  • Multi-language Support — Auto-detect or manually select source language (Japanese, English, Chinese, Korean, French, German, Spanish, Russian)
  • LLM Translation — Translate subtitles via any OpenAI-compatible API (LM Studio, Ollama, OpenAI, DeepSeek, etc.)
  • Bilingual Subtitles — Generated SRT files contain both original and translated text
  • Batch Processing — Import entire folders, process hundreds of videos overnight unattended
  • Burn-in Option — Optionally hardcode subtitles into the video file (FFmpeg)
  • Bilingual UI — Switch between Chinese and English interface with one click
  • macOS App — Build as a standalone .app bundle with DMG installer, no Python required
  • Drag & Drop — Drag video files directly into the app window
  • Smart Folder Import — Recursively scans folders, automatically skips videos that already have subtitles

Supported Formats

Input VideoOutput
.mp4 .mkv .avi .mov .ts .m2ts .webm .wmv.srt subtitle file (+ optional burned-in video)

Whisper Models

ModelSizeSpeedAccuracyRecommended For
tiny~75 MBFastestLowQuick tests
base~150 MBFastFairShort clips
small~500 MBMediumGoodGeneral use
medium~1.5 GBSlowGreatRecommended
large-v3~3 GBSlowestBestMaximum accuracy

Models are downloaded automatically on first use and cached at ~/.cache/vr-subtitle-app/whisper/.

Sensitivity Presets

PresetBest For
ConservativeNoisy environments, only clear speech
StandardBalanced, works for most videos
SensitiveVideos with low audio volume
MaxCatches all speech, may include false positives

Screenshots

AutoSubtitle main interface


Installation

Prerequisites

  • Python 3.10+ (3.11 recommended)
  • FFmpeg — must be in your system PATH

From Source

# Clone the repository
git clone https://github.com/Linwei-Chen/AutoSubtitle.git
cd AutoSubtitle

# (Recommended) Create a virtual environment
conda create -n autosub python=3.11
conda activate autosub
# or: python -m venv venv && source venv/bin/activate

# Install dependencies
pip install -r requirements.txt

# Run
python main.py

macOS DMG (Pre-built)

Download the latest .dmg from the Releases page.

Note: The app is unsigned. On first launch:

  • Right-click the app → Open, or
  • Run in Terminal: xattr -cr /Applications/AutoSubtitle.app

Usage

Quick Start

  1. Launch the app (python main.py or open AutoSubtitle.app)
  2. Add videos — Click "Add Files" / "Add Folder", or drag & drop
  3. Select Whisper modelmedium is recommended for most cases
  4. Configure translation API — Enter your API URL and key (see below)
  5. Choose languages — Source language (or Auto Detect) and target language
  6. Click Start — Sit back and wait

Translation API Setup

AutoSubtitle works with any OpenAI-compatible chat completions API:

ProviderAPI URLAPI Key
LM Studio (local)http://localhost:1234(leave empty)
Ollama (local)http://localhost:11434(leave empty)
OpenAIhttps://api.openai.comsk-...
DeepSeekhttps://api.deepseek.comsk-...

You can save multiple API profiles and switch between them.

Click Refresh to fetch available models from the API, or type a model name directly (e.g., gpt-4o-mini, deepseek-chat).

Batch Processing

  1. Click Add Folder to import an entire directory
  2. The app recursively scans for video files and skips those that already have a matching .srt
  3. Click Start — all files are processed sequentially in a background thread
  4. You can safely minimize the window or leave it running overnight

Output

  • SRT file is saved next to the original video with the same filename: video.mp4video.srt
  • If Burn subtitles is checked, a new video file is created: video.mp4video_subtitled.mp4
  • SRT format is bilingual (original + translation):
1
00:00:01,200 --> 00:00:03,800
これは日本語のテストです
This is a Japanese test

2
00:00:04,100 --> 00:00:06,500
字幕が自動で生成されます
Subtitles are generated automatically

Build macOS App

Build a standalone .app bundle and DMG installer:

# 1. Make sure you have a conda environment with all dependencies
conda create -n vr-sub python=3.11
conda activate vr-sub
pip install -r requirements.txt

# 2. Run the build script (downloads static FFmpeg, builds with PyInstaller, creates DMG)
chmod +x build_macos.sh
./build_macos.sh

The output DMG will be at dist/AutoSubtitle.dmg.

What the Build Script Does

  1. Installs PyInstaller
  2. Downloads static ffmpeg and ffprobe binaries (if not already present)
  3. Builds the app bundle with PyInstaller using vr_subtitle.spec
  4. Creates a compressed DMG image

Build Customization

Edit vr_subtitle.spec to customize:

  • hiddenimports — Add additional Python packages
  • excludes — Remove unnecessary packages to reduce size
  • info_plist — Modify app metadata, bundle identifier, etc.

Project Structure

AutoSubtitle/
├── main.py                  # GUI entry point (PyQt5 MainWindow + worker thread)
├── i18n.py                  # Bilingual UI strings (Chinese/English)
├── process_video.py         # Standalone CLI script for single video
├── requirements.txt         # Python dependencies

├── engines/
│   ├── whisper_engine.py    # Speech recognition (faster-whisper + Silero VAD)
│   ├── translator.py        # LLM translation (OpenAI-compatible API)
│   ├── languages.py         # Language code mappings + prompt generation
│   └── subtitle.py          # SRT file generation

├── utils/
│   ├── ffmpeg_utils.py      # Audio extraction + subtitle burning (FFmpeg)
│   └── config.py            # Persistent user config (~/.config/autosubtitle/)

├── assets/
│   ├── icon.icns            # macOS app icon
│   └── icon_1024.png        # Source icon (1024x1024)

├── build_macos.sh           # One-click macOS build script
├── vr_subtitle.spec         # PyInstaller configuration
└── entitlements.plist       # macOS hardened runtime entitlements

Architecture

┌──────────────────────────────────────────────────┐
│                   PyQt5 GUI                       │
│         (main thread — UI + signals)              │
└──────────────────┬───────────────────────────────┘
                   │ start

┌──────────────────────────────────────────────────┐
│              SubtitleWorker (QThread)             │
│                                                   │
│  for each video in queue:                         │
│    1. FFmpeg: extract audio → WAV (16kHz mono)    │
│    2. Whisper: transcribe → segments              │
│    3. LLM API: translate each segment             │
│    4. Write bilingual .srt file                   │
│    5. (Optional) FFmpeg: burn subtitles           │
│                                                   │
│  ► Entire batch runs in one thread               │
│  ► No main-thread dependency between files        │
└──────────────────────────────────────────────────┘

Configuration

User configuration is stored at ~/.config/autosubtitle/config.json:

{
  "profiles": [
    {
      "name": "LM Studio (local)",
      "api_base": "http://localhost:1234",
      "api_key": ""
    },
    {
      "name": "OpenAI",
      "api_base": "https://api.openai.com",
      "api_key": "sk-..."
    }
  ],
  "active_profile": 0
}

Crash logs (if any) are written to ~/.config/autosubtitle/crash.log.


FAQ

Q: The app says "connection failed" when I click Refresh

Make sure your translation API is running. For local models:

  • LM Studio: Start the local server (default port 1234)
  • Ollama: Run ollama serve (default port 11434)

For cloud APIs, check that your API key is correct.

Q: Whisper model download is slow

Models are downloaded from Hugging Face on first use. If you're in China or have slow connectivity, consider setting an HF mirror:

export HF_ENDPOINT=https://hf-mirror.com
python main.py

Q: Can I use it without translation (transcription only)?

Currently the app always runs the translation step. As a workaround, set the source and target language to the same language — the LLM will effectively pass through the original text.

Q: macOS says the app is damaged / can't be opened

The app is unsigned. Run this command to remove the quarantine flag:

xattr -cr /Applications/AutoSubtitle.app

Or: Right-click → Open → Open.

Q: Processing stops when I minimize the window (macOS)

This has been fixed. The app disables macOS App Nap via Info.plist and NSProcessInfo activity assertions. If you experience this on an older version, please update.

Q: How much memory does it use?

Whisper ModelApprox. RAM
tiny~300 MB
base~500 MB
small~1 GB
medium~2 GB
large-v3~4 GB

The model is loaded once and reused across all files in a batch.

Q: What about GPU acceleration?

Currently the app runs Whisper on CPU with int8 quantization. GPU support (CUDA/Metal) could be added by modifying device and compute_type in engines/whisper_engine.py.


Dependencies

PackagePurpose
faster-whisperSpeech recognition (CTranslate2 backend)
PyQt5GUI framework
requestsHTTP client for translation API
srtSRT subtitle file parsing/generation
FFmpegAudio extraction and subtitle burning (external binary)

Contributing

Contributions are welcome! Feel free to open issues or submit pull requests.

Some areas that could use help:

  • GPU acceleration (CUDA / Apple Metal)
  • More language support
  • Windows / Linux packaging
  • Speaker diarization
  • Subtitle style customization

License

This project is licensed under the MIT License.


Acknowledgments