Groq vs OpenAI for Whisper Transcription Setup in Claude-Video

The Claude-Video watch skill automatically prefers Groq's Whisper API for faster, cheaper transcription while seamlessly falling back to OpenAI when Groq credentials are unavailable.

The transcription system in the bradautomates/claude-video repository implements a backend-agnostic architecture that prioritizes Groq for Whisper transcription due to superior speed and cost efficiency, with OpenAI serving as a robust fallback. This dual-backend approach is managed entirely within the /watch skill, which extracts audio from video content and generates timestamped captions. All configuration is centralized in a user-scoped environment file, allowing seamless switching between providers without code changes.

How Backend Selection Works

The transcription logic in skills/watch/scripts/whisper.py implements a priority-based detection system that evaluates available credentials before initiating any API calls.

API Key Discovery

The load_api_key() function searches for credentials in a specific order of precedence:

  1. Environment variables – Checks for GROQ_API_KEY first, then OPENAI_API_KEY
  2. User configuration file – Reads from ~/.config/watch/.env if environment variables are unset

The function returns a tuple containing the backend identifier ("groq" or "openai") and the corresponding API key. This discovery mechanism ensures that Groq is always attempted first, aligning with the project's cost-optimization goals.

Runtime Backend Selection

The transcribe_video() function receives optional backend and api_key parameters. When these are omitted, it invokes load_api_key() to determine the available service:

if backend is None or api_key is None:
    detected_backend, detected_key = load_api_key()
    backend = backend or detected_backend
    api_key = api_key or detected_key

If neither key is found, the system raises a SystemExit with explicit instructions to configure credentials via the setup script:

No Whisper API key available. Set GROQ_API_KEY (preferred) or OPENAI_API_KEY 
in the environment or in ~/.config/watch/.env. 
Run `python3 setup.py` to configure.

Configuring Your API Keys

The skills/watch/scripts/setup.py installer automates credential scaffolding and dependency verification.

Running python3 setup.py performs three critical tasks:

  • Binary verification – Confirms ffmpeg, ffprobe, and yt-dlp are installed and accessible
  • Environment creation – Generates ~/.config/watch/.env with restrictive permissions (0600) containing placeholder keys:
GROQ_API_KEY=
OPENAI_API_KEY=
  • Completion tracking – Writes SETUP_COMPLETE=true to prevent redundant configuration prompts

Users populate this file with either a Groq API key, an OpenAI API key, or both to enable automatic fallback behavior.

Transcription Pipeline Implementation

The complete workflow from video input to structured captions involves several specialized functions within whisper.py.

Audio Extraction and Chunking

The extract_audio() function uses ffmpeg to convert video streams into mono 16kHz MP3 format. For long videos exceeding the 24 MiB upload limit, the system calculates optimal split points:

  • plan_chunks() – Determines time-based segmentation to keep each part under MAX_UPLOAD_BYTES
  • split_audio() – Physically segments the audio file using ffmpeg timestamps
  • shift_segments() – Adjusts timestamps post-transcription to align chunk segments with the original video timeline

Backend-Specific Endpoints and Models

The implementation defines service-specific constants that map to distinct model versions:

  • Groq: Endpoint https://api.groq.com/openai/v1/audio/transcriptions using model whisper-large-v3
  • OpenAI: Endpoint https://api.openai.com/v1/audio/transcriptions using model whisper-1

Both services accept identical multipart/form-data payloads, allowing the _post_whisper() function to remain provider-agnostic while routing requests to the correct URL.

Manual Multipart Upload Handling

The _post_whisper() function constructs HTTP requests using only Python standard library modules to avoid external dependencies. It manually builds the multipart body and sets a custom User-Agent header specifically to bypass Groq's Cloudflare WAF restrictions. Response parsing occurs in _segments_from_response(), which normalizes verbose JSON into uniform {start, end, text} dictionaries regardless of which backend generated the transcript.

Forcing a Specific Backend

While automatic selection prefers Groq, the command-line interface in watch.py allows explicit backend specification:


# Automatic selection (prefers Groq)

watch https://www.youtube.com/watch?v=example

# Force OpenAI backend

watch https://www.youtube.com/watch?v=example --whisper openai

# Force Groq backend

watch https://www.youtube.com/watch?v=example --whisper groq

The argument parser defines this behavior in watch.py:

parser.add_argument(
    "--whisper",
    choices=["groq", "openai"],
    default=None,
    help="Force a specific Whisper backend. Default: prefer Groq, fall back to OpenAI."
)

During execution, the skill outputs the selected backend to stderr for transparency:

[watch] extracting audio for Whisper (groq)…
[watch] transcribed 42 segments via groq

Summary

  • Groq is the default – The load_api_key() function in whisper.py prioritizes GROQ_API_KEY over OpenAI credentials for cost and speed advantages.
  • Seamless fallback – If Groq keys are absent, the system automatically detects and uses OPENAI_API_KEY without requiring code modifications.
  • Configuration location – All API keys reside in ~/.config/watch/.env, created with secure permissions by setup.py.
  • Runtime override – The --whisper CLI argument forces a specific backend regardless of automatic detection logic.
  • Unified payload – Both backends use identical multipart upload logic in _post_whisper(), differing only in endpoint URLs and model names.

Frequently Asked Questions

Why does the Claude-Video skill prefer Groq over OpenAI for Whisper transcription?

According to the source code comments in whisper.py, Groq provides significantly faster inference and lower pricing for the Whisper-large-v3 model compared to OpenAI's whisper-1 implementation. The automatic preference ensures users benefit from reduced latency and cost unless they explicitly configure only an OpenAI key.

Can I use both Groq and OpenAI keys simultaneously in the configuration?

Yes. The .env file at ~/.config/watch/.env supports both GROQ_API_KEY and OPENAI_API_KEY variables simultaneously. When both are present, the load_api_key() function selects Groq by default, but you can force OpenAI usage at runtime with the --whisper openai command-line flag.

What happens if my audio file exceeds the upload size limit?

The transcribe_video() function automatically detects file sizes exceeding 24 MiB (MAX_UPLOAD_BYTES) and triggers the chunking pipeline. The plan_chunks() function calculates time-based splits, split_audio() creates temporary audio segments using ffmpeg, and transcribe_chunks() processes each part individually before shift_segments() reconciles timestamps into a continuous transcript.

How do I troubleshoot API connection errors with Groq specifically?

The _post_whisper() function in whisper.py implements a custom User-Agent header specifically to circumvent Groq's Cloudflare WAF restrictions. If you encounter connection errors, verify your GROQ_API_KEY is correctly set in ~/.config/watch/.env and ensure the file permissions are 0600. Run python3 setup.py to validate your configuration and check that all required binaries (ffmpeg, ffprobe, yt-dlp) are installed.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →