# How Transcript Caching Works in video-use: Preventing Unnecessary Re‑Transcription

> Learn how transcript caching in video-use prevents unnecessary re-transcription. Discover when video-use triggers new transcriptions, saving time and resources.

- Repository: [Browser Use/video-use](https://github.com/browser-use/video-use)
- Tags: internals
- Published: 2026-07-09

---

**`video-use` stores transcripts as JSON files in a dedicated `transcripts/` directory and skips API calls to ElevenLabs Scribe when a matching file already exists, only triggering re‑transcription when the video filename changes or the cache is missing.**

The `browser-use/video-use` repository implements an efficient **transcript caching** mechanism that avoids redundant API calls and duplicate billing. By persisting transcription results as JSON artifacts keyed to the video filename, the tooling ensures that repeated runs against unchanged video sources are fast, idempotent, and cost‑effective.

## Where Transcript Files Are Stored

Cached transcripts live in the *edit directory* under a `transcripts/` subdirectory. The cache key is the **stem of the video file**—the filename without its extension. For a video located at `media/example.mp4`, the helper expects to find (or creates) a cache file at:

```text
<edit_dir>/transcripts/example.json

```

This durable storage strategy treats transcripts as immutable outputs of immutable inputs, allowing the workflow to reference historical results without re‑contacting the ElevenLabs Scribe API.

## How video-use Checks for Cached Transcripts

The repository provides two primary entry points for transcription, both implementing the same cache‑first logic.

### Single Video Processing (transcribe_one)

In [`helpers/transcribe.py`](https://github.com/browser-use/video-use/blob/main/helpers/transcribe.py), the `transcribe_one` function performs an existence check before any upload occurs. The code explicitly checks `if out_path.exists():` and, upon finding a match, prints `f"cached: {out_path.name}"` and returns the existing path immediately. This short‑circuit prevents both audio extraction and the HTTP request to the transcription service.

According to the source comments in [`helpers/transcribe.py`](https://github.com/browser-use/video-use/blob/main/helpers/transcribe.py) (lines 90‑110), the behavior is summarized as: *"Cached: if the output file already exists, the upload is skipped."*

### Batch Processing (transcribe_batch)

For bulk operations, [`helpers/transcribe_batch.py`](https://github.com/browser-use/video-use/blob/main/helpers/transcribe_batch.py) partitions the workload into cached and pending items. The helper builds a list of already‑processed videos using a list comprehension that checks for the existence of the expected JSON file:

```python
already_cached = [v for v in videos if (edit_dir / "transcripts" / f"{v.stem}.json").exists()]

```

Only the videos absent from this list are forwarded to the API. The function reports the split (e.g., "found 10 videos (7 cached, 3 to transcribe)") so you can verify that **transcript caching** is reducing your API quota consumption.

## When Re‑Transcription Is Triggered

Re‑transcription occurs only when the expected cache file is not found. This happens in two scenarios:

1. **First‑time processing** – No JSON file exists for the video stem.
2. **Filename or content changes** – If you rename `example.mp4` to `example_v2.mp4`, the stem changes from `example` to `example_v2`, and the helper will not locate the old [`example.json`](https://github.com/browser-use/video-use/blob/main/example.json). Similarly, if you delete the `transcripts/` directory or the specific JSON file, the next run treats the video as new.

Because the cache system relies on the filename stem rather than content hashes, moving or renaming a video—regardless of whether the actual media changed—invalidates the cache and triggers a fresh transcription.

## Code Examples

### Processing a Single Video

The following example demonstrates how `transcribe_one` reuses an existing transcript on subsequent runs:

```python
from pathlib import Path
from helpers.transcribe import transcribe_one, load_api_key

video_path = Path("media/example.mp4")
edit_dir   = Path("my_edit")
api_key    = load_api_key()

# First run → transcript is created

transcript_path = transcribe_one(video_path, edit_dir, api_key)

# Subsequent run → same transcript is reused, output:

# cached: example.json

```

### Processing Multiple Videos

Use `transcribe_batch` to automatically separate cached items from those needing API processing:

```python
from pathlib import Path
from helpers.transcribe_batch import transcribe_batch
from helpers.transcribe import load_api_key

videos   = list(Path("media").glob("*.mp4"))
edit_dir = Path("my_edit")
api_key  = load_api_key()

# transcribe_batch prints:

# found 10 videos (7 cached, 3 to transcribe)

transcribe_batch(videos, edit_dir, api_key)

```

## Summary

- **Cache location**: `transcripts/<video-stem>.json` inside your specified edit directory.
- **Cache mechanism**: Existence check via `Path.exists()` in [`helpers/transcribe.py`](https://github.com/browser-use/video-use/blob/main/helpers/transcribe.py) and list filtering in [`helpers/transcribe_batch.py`](https://github.com/browser-use/video-use/blob/main/helpers/transcribe_batch.py).
- **Trigger for re‑transcription**: Missing JSON file, typically caused by renaming the video or deleting the cache.
- **Benefits**: Idempotent workflows, reduced API costs, and protection against rate limits.

## Frequently Asked Questions

### Where are cached transcripts stored?

Transcripts are stored as JSON files in `<edit_dir>/transcripts/<video_stem>.json`. The `video_stem` is the filename of the video without its extension.

### How does video-use know when to skip transcription?

In [`helpers/transcribe.py`](https://github.com/browser-use/video-use/blob/main/helpers/transcribe.py), the `transcribe_one` function checks if the output path exists using `out_path.exists()`. If the file is present, the function prints a "cached" message and returns immediately without contacting the ElevenLabs API. The batch helper in [`helpers/transcribe_batch.py`](https://github.com/browser-use/video-use/blob/main/helpers/transcribe_batch.py) performs a similar check to filter the upload queue.

### What happens if I rename a video file?

Renaming changes the file stem, which changes the expected cache path. Since the lookup `f"{v.stem}.json"` will no longer match the old transcript file, `video-use` will treat the renamed video as a new source and perform a fresh transcription.

### Is the transcript cache immutable?

Yes. According to the repository documentation in [`SKILL.md`](https://github.com/browser-use/video-use/blob/main/SKILL.md), transcripts are treated as "immutable outputs of immutable inputs." Once a JSON file is created, it is not modified by subsequent runs; the system simply reads the existing file and skips the API call.