Skip to content

scibilo/pitchfall

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Pitchfall

Free, local, open-source video transcription and subtitle generation.
Upload any video or audio file β€” or paste a URL β€” and get a timestamped transcript, synchronized playback, translation into 10 languages, and .srt subtitle export. No subscriptions, no usage limits, no data leaving your machine.


Screenshots

Transcription in progress Result with video sync Translation panel


Why this exists

Every transcription tool online either has a paywall, a strict free tier, or sends your files to a remote server. Pitchfall runs entirely on your own machine using faster-whisper β€” a highly optimized local implementation of OpenAI's Whisper model. No API key required for transcription. No account. No cloud.


Features

  • πŸŽ™οΈ Local transcription β€” powered by faster-whisper (Whisper small model by default, CPU-friendly)
  • πŸ”— Video sync β€” click any transcript segment to jump to that exact moment in the video
  • 🌍 Translation β€” translate the transcript into 10 languages (optional, see below)
  • πŸ“₯ Export β€” download transcript as .txt or subtitles as .srt
  • πŸ”— URL support β€” paste any YouTube or direct video URL (powered by yt-dlp)
  • πŸ”’ Privacy β€” files are processed locally and deleted immediately after transcription

Requirements

Dependency Version Notes
Python 3.10+ 3.12 recommended
Node.js 18+
ffmpeg any recent required by faster-whisper and yt-dlp
RAM 2GB+ free Whisper small uses ~1GB during transcription

First run: on first transcription, faster-whisper automatically downloads the Whisper small model (~245MB). This happens once and is cached locally in ~/.cache/huggingface/.


Installation

Option A β€” Docker (recommended)

git clone https://github.com/scibilo/pitchfall.git
cd pitchfall
cp .env.example .env
# Edit .env β€” see Configuration below
docker compose up

Open http://localhost:3000.


Option B β€” Manual setup

1. Clone

git clone https://github.com/scibilo/pitchfall.git
cd pitchfall

2. Backend

python3 -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r backend/requirements.txt

3. Frontend

cd frontend
npm install
cd ..

4. Configure

cp .env.example .env
# Open .env with any editor and fill in the values

5. Run

bash start.sh

Open http://localhost:3000. To stop: bash start.sh stop


Configuration

Copy .env.example to .env and edit:

# OpenRouter API key β€” OPTIONAL, only needed for translation.
# Transcription works fully without this key.
# Get a free key at: https://openrouter.ai/
OPENROUTER_API_KEY=

# Comma-separated list of allowed frontend origins.
ALLOWED_ORIGINS=http://localhost:3000
Variable Required Purpose
OPENROUTER_API_KEY No Enables the translation feature
ALLOWED_ORIGINS Yes (has default) Controls which origins can call the API

No other keys are needed. Whisper runs locally β€” no OpenAI key, no Google key, nothing else.


Translation

Translation is powered by OpenRouter using free-tier models (Gemma, Llama, Mistral, DeepSeek, Qwen β€” tried in order with automatic fallback).

Important things to know:

  • Free models have rate limits. A 503 - All translation models are temporarily unavailable error means the free tier is momentarily saturated. Wait 10–30 seconds and retry β€” this is not a bug.
  • Free models occasionally go offline. Pitchfall tries 5 different models before giving up, so partial outages are handled automatically.
  • Translation is optional. Transcription, video sync, and .srt export all work without any API key.
  • Want reliable translation? Upgrade to a paid plan on OpenRouter and change the model name in backend/services/translation_service.py. The code structure stays identical. At OpenRouter's current pricing, a few hundred transcriptions cost less than $1.

Usage

  1. Open http://localhost:3000
  2. Upload a file β€” drag & drop or browse (MP4, MP3, MOV, WAV, and most common formats)
  3. Or paste a URL β€” YouTube, Vimeo, or any direct media URL supported by yt-dlp
  4. Wait for transcription β€” a progress bar shows the current stage and latest recognized segment
  5. Click any segment in the transcript panel to jump to that moment in the video
  6. Translate (optional) β€” select a language and click Translate
  7. Export β€” copy to clipboard, download as .txt, or download subtitles as .srt

Project structure

pitchfall/
β”œβ”€β”€ backend/                      # FastAPI + faster-whisper
β”‚   β”œβ”€β”€ main.py                   # API endpoints, startup/shutdown cleanup
β”‚   β”œβ”€β”€ requirements.txt
β”‚   └── services/
β”‚       β”œβ”€β”€ transcription_service.py   # Whisper streaming transcription
β”‚       β”œβ”€β”€ translation_service.py     # OpenRouter with 5-model fallback
β”‚       └── ytdlp_service.py           # URL media download
β”œβ”€β”€ frontend/                     # Next.js 16 + Tailwind CSS 4
β”‚   β”œβ”€β”€ postcss.config.mjs        # Required for Tailwind CSS 4
β”‚   β”œβ”€β”€ next.config.ts
β”‚   β”œβ”€β”€ package.json
β”‚   └── src/
β”‚       β”œβ”€β”€ app/
β”‚       β”‚   β”œβ”€β”€ layout.tsx
β”‚       β”‚   β”œβ”€β”€ page.tsx          # Main page, state management, reset logic
β”‚       β”‚   └── globals.css
β”‚       └── components/
β”‚           β”œβ”€β”€ TranscriptViewer.tsx   # Video player + transcript sync
β”‚           β”œβ”€β”€ UploadForm.tsx
β”‚           β”œβ”€β”€ UrlForm.tsx
β”‚           └── ProgressBar.tsx
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ start.sh                      # Dev launcher (no Docker required)
β”œβ”€β”€ cleanup.sh                    # Clears temp files and build caches
└── .env.example

Changing the Whisper model

In backend/services/transcription_service.py, change:

model_size = "small"
Model Download size RAM Speed (CPU) Accuracy
tiny ~75MB ~390MB fastest lower
base ~145MB ~500MB fast decent
small ~245MB ~1GB moderate good (default)
medium ~770MB ~2GB slow very good
large-v3 ~1.5GB ~3GB very slow best

For everyday use on a laptop, small is the right tradeoff. For professional subtitling, medium or large-v3 deliver significantly better accuracy (GPU strongly recommended for those sizes).


Troubleshooting

Page loads but has no styling (plain HTML)
The postcss.config.mjs file is missing from frontend/. Add it:

const config = { plugins: { "@tailwindcss/postcss": {} } };
export default config;

Then delete frontend/.next/ and restart.

Translation returns 503
Free OpenRouter models are rate-limited or temporarily offline. Wait 10–30 seconds and retry. Check status.openrouter.ai for ongoing outages.

Transcription hangs at 0%
The Whisper model is downloading for the first time (~245MB). Check the terminal for download progress β€” it only happens once.

ffmpeg: command not found
sudo apt install ffmpeg on Ubuntu/Debian, or brew install ffmpeg on macOS.

CORS error in browser console
Set ALLOWED_ORIGINS in .env to match the exact URL your frontend runs on.


Security

Pitchfall is designed for local, single-user use on a trusted machine. It is not hardened for public deployment. Before exposing it on a network:

  • No authentication. Any client reaching the backend port can upload files and consume your OpenRouter credits.
  • No file size limits. A large upload can fill your disk.
  • CORS defaults to http://localhost:3000. Do not widen it without also adding authentication.
  • .env must never be committed. Run git status before every push and confirm .env is not in the staged files. If a key is leaked, rotate it on the OpenRouter dashboard immediately.
  • For anything beyond local use, deploy behind a reverse proxy (nginx/Caddy) with HTTPS, HTTP basic auth, and rate limiting.

Cleanup

bash cleanup.sh

Removes leftover temp files, Python __pycache__, and Next.js build caches.


Contributing

Pull requests are welcome. For major changes, open an issue first to discuss what you'd like to change.


License

MIT β€” see LICENSE.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors