# What Happens When a Video Has No Captions and No Whisper API Key

> Discover what happens when a video lacks captions and a Whisper API key. Learn how the watch skill performs a frames-only analysis for visual insights.

- Repository: [bradautomates/claude-video](https://github.com/bradautomates/claude-video)
- Tags: how-to-guide
- Published: 2026-07-31

---

**When a video lacks embedded captions and no Whisper API key is configured, the `watch` skill generates a frames-only analysis with a clear explanatory note in the Transcript section, allowing visual analysis to proceed without audio transcription.**

The `claude-video` repository provides a powerful `watch` skill for analyzing video content through Claude AI. When processing videos without embedded subtitles, the tool attempts a Whisper API fallback—but understanding the behavior when both captions and API credentials are missing ensures you know exactly what output to expect.

## The Two-Stage Transcript Acquisition Process

The `watch` skill in [`skills/watch/scripts/watch.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/watch.py) attempts to obtain transcripts through a specific hierarchy. First, it queries embedded subtitles via **yt-dlp** through the `fetch_captions` function, followed by a `parse_vtt` attempt to parse WebVTT files (lines 98–104).

If caption extraction fails—whether due to missing subtitle tracks or parsing exceptions—the script evaluates whether to invoke the Whisper transcription fallback.

## Three Conditions Required for Whisper Fallback

The fallback logic around line 389 in [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) guards the Whisper transcription path with three strict conditions:

1. **`--no-whisper`** is **not** set in the command arguments.
2. A video file was successfully downloaded (`video_path` is truthy).
3. The video metadata confirms an audio stream exists (`meta.get("has_audio")`).

```python

# Conceptual flow from watch.py lines 389-406

if not args.no_whisper and video_path and meta.get("has_audio"):
    # Attempt Whisper transcription

    api_key, provider = load_api_key()
    if api_key:
        # Proceed with transcription...

```

When any condition evaluates to false—most commonly when **no Whisper API key** is available—the transcription path is skipped entirely.

## How API Key Detection Works

The `load_api_key` function in [`skills/watch/scripts/whisper.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/whisper.py) (lines 65–78) searches for credentials in environment variables and `.env` files. It returns `(None, None)` when neither `GROQ_API_KEY` nor `OPENAI_API_KEY` are found.

```python

# From whisper.py - load_api_key logic

def load_api_key():
    # Checks GROQ_API_KEY, then OPENAI_API_KEY

    # Returns (None, None) if neither exists

    return (api_key, provider)  # or (None, None)

```

When the key tuple contains `None`, the code reaches an else branch that prints a user-friendly hint and exits the transcription path:

```text
[watch] no subtitles and no Whisper API key found — run `python3 <setup.py>` to enable the Whisper fallback

```

## Graceful Degradation to Frames-Only Mode

Rather than raising an exception, the tool continues execution and renders the final markdown report. In the "Transcript" section (handled around lines 77–84 in [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py)), the output displays:

```markdown
_No transcript available — proceed with frames only. Captions were missing and the Whisper fallback was unavailable (no API key set, or `--no-whisper` was used). Run `python3 <setup.py>` to enable Whisper, then re‑run._

```

This means **the outcome is a frames-only report** when the selected detail mode extracts visual frames, accompanied by a clear explanation that transcription could not be supplied.

## Practical Example

Running the skill on a video without captions and without API keys configured produces the following workflow:

```bash

# No API keys set, video has no captions

watch "https://example.com/video-with-no-captions.mp4" --detail balanced

```

The generated report includes:

```markdown
- **Source:** https://example.com/video-with-no-captions.mp4
- **Duration:** 02:15 (135.0s)
- **Detail:** balanced
- **Frames:** 23 selected from 23 candidates (scene engine, full range, budget 23, cap 23)

## Transcript

_No transcript available — proceed with frames only. Captions were missing and the Whisper fallback was unavailable (no API key set, or `--no-whisper` was used). Run `python3 /path/to/skills/watch/scripts/setup.py` to enable Whisper, then re‑run._

```

If you explicitly disable Whisper with the `--no-whisper` flag, the same message appears, indicating the flag rather than a missing key triggered the omission.

## Summary

- **Primary path**: The `watch` skill first attempts to extract embedded captions via `fetch_captions` and `parse_vtt` in [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py).
- **Fallback conditions**: Whisper transcription requires the absence of `--no-whisper`, a valid video path, audio metadata, and a configured API key.
- **Key detection**: The `load_api_key` function in [`whisper.py`](https://github.com/bradautomates/claude-video/blob/main/whisper.py) returns `(None, None)` when `GROQ_API_KEY` and `OPENAI_API_KEY` are both absent.
- **No-error behavior**: When both captions and Whisper are unavailable, the tool generates a frames-only report with an explanatory placeholder in the Transcript section.
- **Recovery path**: Users can run [`setup.py`](https://github.com/bradautomates/claude-video/blob/main/setup.py) to configure API keys and re-run the analysis to obtain audio transcription.

## Frequently Asked Questions

### Does the tool crash if no transcript is available?

No. The `watch` skill handles missing transcripts gracefully according to the source code in [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) (lines 77–84). It continues generating the markdown report with available visual data and inserts a placeholder message explaining why transcription was skipped.

### How do I enable Whisper transcription after seeing the "no API key" message?

Run `python3 /path/to/skills/watch/scripts/setup.py` as suggested in the console output and report message. This script configures either a **Groq** or **OpenAI** API key by setting `GROQ_API_KEY` or `OPENAI_API_KEY` in your environment or `.env` file, which the `load_api_key` function detects on subsequent runs.

### What happens if I use `--no-whisper` on a video without captions?

The behavior is identical to having no API key configured. The tool skips the Whisper fallback path entirely (failing the first condition at line 389 in [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py)) and produces a frames-only report with the same explanatory note in the Transcript section.

### Can I force the tool to transcribe audio without an API key?

No. The [`whisper.py`](https://github.com/bradautomates/claude-video/blob/main/whisper.py) module strictly requires either a **Groq** or **OpenAI** API key to process audio. When `load_api_key` returns `(None, None)`, the transcription logic is bypassed entirely, and no local transcription alternative is implemented in the current codebase.