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:
- Environment variables – Checks for
GROQ_API_KEYfirst, thenOPENAI_API_KEY - User configuration file – Reads from
~/.config/watch/.envif 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, andyt-dlpare installed and accessible - Environment creation – Generates
~/.config/watch/.envwith restrictive permissions (0600) containing placeholder keys:
GROQ_API_KEY=
OPENAI_API_KEY=
- Completion tracking – Writes
SETUP_COMPLETE=trueto 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 underMAX_UPLOAD_BYTESsplit_audio()– Physically segments the audio file using ffmpeg timestampsshift_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/transcriptionsusing modelwhisper-large-v3 - OpenAI: Endpoint
https://api.openai.com/v1/audio/transcriptionsusing modelwhisper-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 inwhisper.pyprioritizesGROQ_API_KEYover OpenAI credentials for cost and speed advantages. - Seamless fallback – If Groq keys are absent, the system automatically detects and uses
OPENAI_API_KEYwithout requiring code modifications. - Configuration location – All API keys reside in
~/.config/watch/.env, created with secure permissions bysetup.py. - Runtime override – The
--whisperCLI 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →