Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 

Repository files navigation

Interview Transcriber

A FastAPI backend that transcribes interview audio using Groq Whisper Large v3 — no GPU, no local model download. Upload a pre-recorded file or record directly from your browser and get back a timestamped JSON transcript in seconds.


How It Works

Audio File / Browser Recording
        │
        ▼
  ┌─────────────┐
  │  Compress   │  → mono 16kHz 32kbps MP3  (shrinks files ~70%)
  └─────────────┘
        │
        ▼ if file > 20 MB
  ┌─────────────┐
  │   Chunk     │  → splits into 10-minute pieces
  └─────────────┘
        │
        ▼
  ┌─────────────────────────┐
  │  Groq Whisper Large v3  │  → transcribes each chunk
  └─────────────────────────┘
        │
        ▼
  ┌─────────────┐
  │    Merge    │  → stitches segments with corrected timestamps
  └─────────────┘
        │
        ▼
  Structured JSON transcript  →  saved to transcripts/

Project Structure

interview-transcriber/
├── main.py            ← FastAPI app — routes, compression, chunking, transcription
├── config.py          ← Loads GROQ_API_KEY from .env
├── pyproject.toml     ← uv project config + dependencies
├── static/
│   └── recorder.html  ← Browser-based PWA recorder (no install needed)
├── uploads/           ← Uploaded audio files (auto-created)
├── transcripts/       ← JSON transcripts (auto-created)
├── chunks/            ← Temp chunk files during processing (auto-cleaned)
└── .env               ← Your API key (you create this)

Prerequisites

Requirement Notes
Python ≥ 3.11 Required
uv Fast Python package manager
ffmpeg Required by pydub for audio processing
Groq API key Free at console.groq.com

Setup

1. Install uv

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
winget install astral-sh.uv

2. Install ffmpeg

# macOS
brew install ffmpeg

# Ubuntu / Debian
sudo apt install ffmpeg

# Windows (with Chocolatey)
choco install ffmpeg

3. Clone and install dependencies

git clone <your-repo-url>
cd interview-transcriber
uv sync

uv sync reads pyproject.toml, creates a virtual environment, and installs all dependencies automatically.

4. Configure your API key

Create a .env file in the project root:

# .env
GROQ_API_KEY=gsk_your_key_here

Get your free key from console.groq.com.

config.py will raise a RuntimeError at startup if GROQ_API_KEY is missing or empty.

5. Start the server

uv run uvicorn main:app --reload --host 0.0.0.0 --port 8000
URL Description
http://localhost:8000 Base URL
http://localhost:8000/docs Interactive Swagger UI
http://localhost:8000/recorder Browser-based audio recorder

Browser Recorder (PWA)

Open http://localhost:8000/recorder on any device (desktop or mobile). No app install required.

Flow:

  1. Tap Start — grants mic access and begins recording
  2. A live timer and animated waveform show recording is active
  3. Tap Stop — audio is uploaded and transcribed automatically
  4. The Done screen displays duration, segment count, detected language, and interview ID
  5. Tap New Recording to start again

The recorder auto-selects the best supported audio format (webm/opus → ogg → mp4) and uploads directly to /transcribe.


API Reference

GET /health

Check server status.

curl http://localhost:8000/health
{ "status": "ok", "transcription_engine": "groq/whisper-large-v3" }

POST /transcribe

Upload an audio file and receive a structured JSON transcript.

Supported formats: .mp3 .wav .m4a .ogg .webm .flac .mp4

Query Parameter Type Required Description
file file (form) The audio file
interview_id string Custom ID — auto-generated (interview_<8hex>) if omitted
language string ISO 639-1 code e.g. en, hi, es — auto-detected if omitted

curl:

curl -X POST "http://localhost:8000/transcribe?language=en" \
  -F "file=@interview.mp3"

Python:

import requests

with open("interview.mp3", "rb") as f:
    r = requests.post(
        "http://localhost:8000/transcribe",
        params={"interview_id": "candidate_bob", "language": "en"},
        files={"file": ("interview.mp3", f, "audio/mpeg")},
    )
print(r.json())

Response:

{
  "interview_id": "candidate_bob",
  "original_file": "interview.mp3",
  "transcribed_at": "2026-03-10T09:00:00",
  "language": "en",
  "duration_seconds": 182.4,
  "total_segments": 24,
  "full_transcript": "Tell me about yourself. Sure, I have five years of...",
  "segments": [
    { "segment_id": 1, "start": 0.0,  "end": 4.2,  "text": "Tell me about yourself." },
    { "segment_id": 2, "start": 5.1,  "end": 12.8, "text": "Sure, I have five years of experience in..." }
  ]
}

Transcripts are saved automatically to transcripts/<interview_id>.json.


GET /transcripts

List all saved transcripts (summaries only, no segments).

curl http://localhost:8000/transcripts
{
  "total": 2,
  "transcripts": [
    {
      "interview_id": "candidate_bob",
      "original_file": "interview.mp3",
      "transcribed_at": "2026-03-10T09:00:00",
      "language": "en",
      "duration_seconds": 182.4,
      "total_segments": 24
    }
  ]
}

GET /transcripts/{interview_id}

Retrieve a full transcript including all segments.

curl http://localhost:8000/transcripts/candidate_bob

DELETE /transcripts/{interview_id}

Delete a transcript permanently.

curl -X DELETE http://localhost:8000/transcripts/candidate_bob
{ "deleted": "candidate_bob" }

Configuration

All tunable constants are at the top of main.py:

Constant Default Description
GROQ_MAX_BYTES 20 * 1024 * 1024 (20 MB) Files larger than this are split into chunks before sending to Groq
CHUNK_MINUTES 10 Length of each audio chunk in minutes
ALLOWED_EXTENSIONS .mp3 .mp4 .wav .m4a .ogg .webm .flac Accepted file types

Audio compression settings (inside compress_audio()):

Setting Value Rationale
Channels Mono Interview audio is mono; halves file size
Sample rate 16 kHz Sufficient for speech recognition
Bitrate 32 kbps Keeps files well under Groq's 25 MB limit

Dependencies

Defined in pyproject.toml:

Package Purpose
fastapi Web framework
uvicorn[standard] ASGI server
python-multipart Multipart form / file uploads
groq Groq SDK — calls Whisper Large v3
pydub Audio compression and chunking (requires ffmpeg)
python-dotenv Loads .env into environment variables

Groq Free Tier

Limit Value
Audio transcription 2 hours / day
Transcription speed ~10 s for a 30-minute interview
API key Free at console.groq.com

Exposing Publicly (ngrok)

To use the browser recorder from a phone on a different network:

ngrok http 8000

Open the forwarding URL on your phone:

https://xxxx.ngrok-free.app/recorder

Troubleshooting

Problem Fix
RuntimeError: GROQ_API_KEY is not set Create .env with your key — see Setup step 4
pydub.exceptions.CouldntDecodeError Install ffmpeg — see Setup step 2
502 Transcription failed Check Groq API key validity and daily quota at console.groq.com
Microphone denied in browser Allow mic permissions in browser settings; HTTPS required on mobile
Large file times out File is being chunked — wait; each 10-min chunk takes ~3 s to transcribe

About

A FastAPI backend that transcribes interview audio using Groq Whisper Large v3

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors