AI-powered subtitle generation with automatic timing synchronization
Generate accurate subtitles for video files using state-of-the-art AI transcription. Perfect for creating subtitles when existing ones don't match the audio track (e.g., English dub with Japanese subtitle translations in anime).
- π― AI-Powered Transcription - Uses OpenAI's Whisper API for highly accurate speech-to-text
- π Automatic Timing Sync - Integrates ffsubsync to fix progressive timing drift
- π Multi-Language Support - Supports 99+ languages with automatic detection
- π Multi-Language Translation - Generate subtitles in multiple languages from single transcription
- ποΈ Multi-Track Handling - Detects and processes multiple audio tracks
- π SRT Format Output - Generates universally compatible subtitle files
- β‘ Batch Processing - Process entire seasons with a single command
- π° Cost-Effective - ~$0.14 per 23-minute episode (transcription only)
- Prerequisites
- Installation
- Quick Start
- Usage
- Workflow
- Cost
- Troubleshooting
- Project Structure
- Contributing
- License
- Node.js 16.x or higher (Download)
- Python 3.7+ with pip (Download)
- OpenAI API Key (Get one here)
- FFmpeg (automatically included via dependencies)
git clone https://github.com/yourusername/syncscribe.git
cd syncscribenpm installpip install ffsubsyncCreate a .env file from the example:
cp .env.example .envEdit .env and add your OpenAI API key:
OPENAI_API_KEY=sk-your-actual-api-key-herenode generate-and-sync.js -i "path/to/video.mkv"This will:
- Extract audio from the video
- Transcribe using Whisper API
- Sync timestamps with ffsubsync
- Generate
video.srtsubtitle file
node app.js -i "path/to/video.mkv" --languages en,es,fr --autoThis will:
- Extract audio from the video
- Transcribe using Whisper API
- Translate to each target language
- Generate
video.en.srt,video.es.srt,video.fr.srt
# Extract audio from all videos first
npm run extract:src
# Then process each video
for file in src/**/*.mkv; do
node generate-and-sync.js -i "$file"
done| Command | Description |
|---|---|
npm run extract:src |
Extract audio from all videos in ./src directory |
node generate-and-sync.js -i "video.mkv" |
Complete pipeline: extract β transcribe β sync |
node shift-timing.js "subtitle.srt" 3 |
Manually shift subtitle timing by 3 seconds |
# Specify language (default: en)
node generate-and-sync.js -i "video.mkv" -l ja
# Generate subtitles in multiple languages
node app.js -i "video.mkv" --languages en,es,ja --auto
# Skip synchronization (use raw Whisper timestamps)
node generate-and-sync.js -i "video.mkv" --skip-sync
# Enable debug logging
node generate-and-sync.js -i "video.mkv" --debugWhisper supports 99+ languages including:
| Language | Code | Language | Code |
|---|---|---|---|
| English | en |
Japanese | ja |
| Spanish | es |
French | fr |
| German | de |
Italian | it |
| Portuguese | pt |
Chinese | zh |
| Korean | ko |
Russian | ru |
Any format supported by FFmpeg:
.mkv(Matroska).mp4(MPEG-4).avi(AVI).mov(QuickTime).webm(WebM)- And many more...
βββββββββββββββββββ
β Video File β
β (.mkv, .mp4) β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β 1. Extract β β FFmpeg (local, free)
β Audio β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β 2. Transcribe β β OpenAI Whisper API (~$0.14)
β with AI β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β 3. Sync β β ffsubsync (local, free)
β Timing β Fixes timing drift
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β 4. Translate β β OpenAI API (optional)
β (Optional) β Generate multiple languages
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β Subtitle Files β
β (.srt) β
βββββββββββββββββββ
AI-generated timestamps from Whisper can drift over time, especially during:
- Long musical sequences (opening themes)
- Multiple overlapping voices
- Background noise/action scenes
ffsubsync uses spectral analysis to automatically correct these timing issues by comparing the audio waveform with the subtitle timing.
Results from testing:
- Episode with 0.14s drift β Perfect sync after ffsubsync
- Episode with 3s drift β Corrected to 0.01s accuracy
- Sync scores: 17,000-55,000 (higher = better alignment)
- Rate: $0.006 per minute of audio
- Examples:
- 23-minute anime episode: ~$0.14
- 45-minute TV show: ~$0.27
- 90-minute movie: ~$0.54
- Full 10-hour season: ~$3.60
When using --languages to generate multiple translations:
- Model: GPT-4o-mini
- Rate: ~$0.0008 per language for a 23-minute episode (~500 subtitle segments)
- Examples:
- Single episode (en + es): ~$0.14 (transcription) + $0.0008 (translation) β $0.14
- Single episode (en + es + fr + de): ~$0.14 + $0.0024 β $0.14
- Translation is extremely cheap compared to transcription!
- β Audio extraction (FFmpeg - local)
- β Timing synchronization (ffsubsync - local)
- β All processing except OpenAI API calls
Solution: Ensure you've created a .env file with your API key.
cp .env.example .env
# Edit .env and add your keySolution: Install ffsubsync using pip.
pip install ffsubsyncSolution: Whisper API has a 25MB file size limit. For longer videos:
- The tool automatically compresses to 64kbps mono MP3
- If still too large, split the video into segments
Solution: Use the manual timing shift tool.
# Shift forward by 3 seconds
node shift-timing.js "subtitle.srt" 3
# Shift backward by 2 seconds
node shift-timing.js "subtitle.srt" -2Solutions:
- Specify the language explicitly:
--language en - Ensure the audio quality is clear
- Check that you're using the correct audio track
node generate-and-sync.js -i "video.mkv" --debugsyncscribe/
βββ app.js # Main CLI entry point
βββ generate-and-sync.js # Complete pipeline orchestrator
βββ extract-audio.js # Batch audio extraction tool
βββ shift-timing.js # Manual timing adjustment tool
βββ sync-subtitles.js # ffsubsync wrapper
βββ lib/
β βββ SubtitleGenerator.js # Main orchestrator class
β βββ VideoProcessor.js # FFmpeg operations
β βββ AudioAnalyzer.js # Audio track detection
β βββ Transcriber.js # OpenAI Whisper API client
β βββ Translator.js # OpenAI translation service
β βββ SubtitleWriter.js # SRT file generation
βββ tmp/ # Temporary files (gitignored)
βββ output/ # Output directory (gitignored)
βββ src/ # Your video files (gitignored)
βββ .env # Your API keys (gitignored)
βββ .env.example # Environment template
βββ package.json # Node dependencies
βββ USAGE.md # Quick reference guide
βββ README.md # This file
Problem: You have English-dubbed anime, but the subtitles are translated from Japanese audio.
Solution:
node generate-and-sync.js -i "anime-episode.mkv" -l enResult: Subtitles that match the English dub perfectly!
Problem: Video has multiple audio tracks, need subtitles for specific track.
Solution:
# The tool will prompt you to select which audio track to use
node generate-and-sync.js -i "movie.mkv"Problem: Need subtitles for an entire season.
Solution:
# 1. Extract all audio files first
npm run extract:src
# 2. Process all episodes
for file in src/Season1/*.mkv; do
node generate-and-sync.js -i "$file"
doneProblem: Need subtitles in multiple languages for international distribution.
Solution:
# Generate English, Spanish, and French subtitles from one transcription
node app.js -i "video.mkv" --languages en,es,fr --autoOutput:
video.en.srt- English subtitlesvideo.es.srt- Spanish subtitlesvideo.fr.srt- French subtitles
Benefits:
- Single transcription, multiple languages
- Same timing windows across all languages
- Minimal additional cost (~$0.001 per language)
- Perfect for content creators, educators, and international releases
This project follows a modular, service-based architecture inspired by professional Node.js applications:
- Services - Each functionality is a self-contained class
- Orchestrator - Main generator coordinates all services
- CLI Tools - Simple command-line interfaces for each operation
- Error Handling - Comprehensive error messages and validation
Contributions are welcome! Please feel free to submit issues or pull requests.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the ISC License - see the LICENSE file for details.
- OpenAI Whisper - AI transcription
- ffsubsync - Subtitle synchronization
- FFmpeg - Audio/video processing
- Inspired by the need for accurate English dub subtitles in anime
- Issues: GitHub Issues
- Documentation: See USAGE.md for quick reference
Made with β€οΈ for anime fans and subtitle enthusiasts