# On-device and Cloud transcription

> The two transcription sources on a job, exactly what each one sends, and why the editing provider is a separate choice.
>
> Verified against the current RoughCut app on 28 August 2026
> https://www.roughcuteditor.com/docs/transcription-options

Every job carries a Transcription choice with two options. On-device is the default: Whisper runs on your Mac, nothing is uploaded for transcription, and no transcription API usage is billed, but it needs the local speech model installed. Cloud (OpenAI) is a Pro option chosen per job. It sends that job's audio, and only its audio, to OpenAI under your own API key as 16 kHz mono chunks split at silence boundaries; your video is never uploaded, no local model is needed, and OpenAI bills your key. Both paths must return word-level timestamps, because the cut plan and the SRT export are built from word times. The transcription source is independent of the AI provider that runs the editing pass.

## The control

`Transcription` is a two-option control on both `New Rough Cut` and `Transcribe Only`. It is a **per-job** choice — it is not a global mode you switch on once.

| Option | Default | Pro | Needs the local model | Needs an OpenAI key |
|---|---|---|---|---|
| `On-device` | Yes | No | Yes | No |
| `✦ Cloud (OpenAI)` | No | **Yes** | No | **Yes** |

When `✦ Cloud (OpenAI)` is selected, a `PRO` badge appears beside the `Transcription` label. Selecting it without a Pro subscription opens the Pro paywall and leaves the choice on `On-device`.

## On-device transcription

This is the default and it is the path the app is designed around.

> Transcribed on this Mac with Whisper — private, nothing uploaded, no API usage. The default.

What that means concretely:

- The transcript is produced by a Whisper speech model running locally on your Mac, with Metal acceleration on Apple Silicon.
- **Nothing is uploaded for transcription on this path.** Your audio and your video both stay where they are.
- **There is no transcription API bill**, from anyone. Local transcription costs nothing per minute.
- It requires the speech model to be installed — a one-time download of about 1.6 GB, cached on your Mac. See [Install the local speech model](/docs/speech-model). Until it is present, `Process` stays disabled and the screen tells you why.
- The local path also runs two protections the cloud path cannot: silence-gated transcription, and hallucination-loop recovery when the model gets stuck repeating itself.

## Cloud transcription (Pro)

`✦ Cloud (OpenAI)` is a RoughCut Pro option. It replaces local transcription for **that one job**.

> This job's audio is sent to OpenAI's transcription model with your own key — no local model download needed. Billed by OpenAI at their per-minute rate.

The mechanics, precisely:

- **Audio only.** RoughCut extracts a 16 kHz mono analysis track and uploads that. **Your video file is never uploaded** — not for this feature, not for any feature.
- **Only the selected job's audio.** Nothing from your other jobs, your library, or your Mac is included.
- **Chunked at silence boundaries.** The audio is split into chunks that stay under OpenAI's request size cap, and the split points land inside detected silences rather than mid-sentence. Word times are then shifted back into whole-file coordinates.
- **Your own API key.** The request is authenticated with the OpenAI key you saved in RoughCut, held in the macOS Keychain. There is no RoughCut server in the path.
- **OpenAI bills you** at their published per-minute rate for the model.
- **No local model needed.** This is the practical reason to use it: a Mac that has not downloaded the 1.6 GB speech model can still transcribe.

Without a key saved, the control shows:

```text
Cloud transcription needs your OpenAI API key.
```

with a link to add it in Settings. If the job runs anyway, the preflight check fails it with the full message:

```text
Cloud transcription needs your OpenAI API key. Add it in Settings → LLM, or switch this job
to on-device transcription.
```

Setting the key up is covered in [Create and add an OpenAI API key](/docs/openai-api-key).

## What leaves your Mac

| Path | What is sent | Where | When |
|---|---|---|---|
| `On-device` transcription | Nothing | — | Never |
| `✦ Cloud (OpenAI)` transcription | That job's **audio**, as 16 kHz mono chunks | OpenAI, with your key | Only for jobs where you selected Cloud |
| AI editing pass | Transcript **text** with word timing | Your chosen AI provider, with your key | Only when `Bad-take removal` is on |
| Video goal summarising | The goal **text** you typed | Your chosen AI provider, with your key | Only when you click `Summarize with AI` |
| Your video file | Nothing, on every path | — | Never |

The full picture, including what is written to disk and for how long, is in [Privacy and data flow](/docs/privacy-data-flow).

## Both paths must return word timestamps

This is not a preference; it is a structural requirement. RoughCut builds the cut plan by snapping removals to word boundaries, and it builds the SRT export from word times. A transcript without word-level timing cannot produce either.

The local model returns word timestamps. On the cloud side, only OpenAI's `whisper-1` currently does. If you point the transcription model at something else, the job fails loudly rather than quietly producing a broken cut:

```text
OpenAI model '<model>' returned a transcript without word timestamps, which the cut
pipeline and SRT export require. Per OpenAI's docs only 'whisper-1' supports word
timestamps — set Settings → Full → Transcription → OpenAI transcription model to 'whisper-1'.
```

Leave `OpenAI transcription model` at `whisper-1` unless you have verified that a newer model returns word-level timing.

## The editing provider is a different setting

This trips people up often enough to deserve its own section.

| Setting | Where | What it controls |
|---|---|---|
| `Transcription` | On the job, next to the other cut controls | **How speech becomes text** — locally, or by OpenAI |
| `LLM provider` | Settings → `Basic` or `Full → LLM` | **Which AI reads the transcript** and proposes bad-take removals |

They are independent. All four combinations are valid:

- Gemini editing with on-device transcription — the common configuration.
- Gemini editing with OpenAI Cloud transcription — perfectly normal; two providers, two keys.
- OpenAI editing with on-device transcription.
- OpenAI editing with OpenAI Cloud transcription.

Choosing `✦ Cloud (OpenAI)` on a job does **not** move your editing pass to OpenAI, and setting `LLM provider` to `openai` does **not** enable cloud transcription. See [Choose an AI provider](/docs/choose-ai-provider).

## Going back to On-device

- **On a job:** select `On-device` in the `Transcription` control before clicking `Process`. That job then transcribes locally and uploads nothing. There is no confirmation step and no penalty.
- **For all future jobs:** open `Settings → Full → Transcription` and turn off `Cloud transcription by default`. That setting only pre-selects Cloud on new jobs, and only for Pro subscribers — every job still shows the choice, and every job can be switched back before you process it.
- **If your subscription lapses:** new jobs start on `On-device` automatically. Non-Pro users always start on-device.

On-device needs the speech model, so if you adopted Cloud specifically to skip the download, install the model before switching back.

## Common mistakes

- **Assuming Cloud is faster or better.** It is a different trade, not an upgrade. Its real advantage is not needing the local model.
- **Assuming Pro alone enables it.** Cloud transcription needs Pro **and** your own OpenAI key. Both.
- **Changing the transcription model away from `whisper-1`.** The job fails at the word-timestamp check.
- **Expecting Transcribe Only to be exempt.** The `Transcribe Only` screen offers the same two options. If you pick Cloud there, that job's audio is sent to OpenAI too, regardless of what that screen's own subtitle suggests.
- **Believing the stage label.** The progress screen reads `Transcribing audio (whisper.cpp)` even on a Cloud job. The label is generic; the work happening is whichever source you chose.

## Troubleshooting

| Message or symptom | Cause | Fix |
|---|---|---|
| `Cloud transcription needs your OpenAI API key.` | No key saved | Save the key in Settings, or switch the job to `On-device` |
| Selecting `✦ Cloud (OpenAI)` does nothing, paywall appears | Not subscribed to Pro | Use `On-device`, or subscribe |
| `OpenAI cloud transcription failed (<model>): …` | Network, rate limit, or key problem | RoughCut already retried once; check the key and connection, or switch to `On-device` |
| `OpenAI model '<model>' returned a transcript without word timestamps…` | Transcription model is not `whisper-1` | Set it back to `whisper-1` |
| `Whisper model missing at <path>. Download or import it in Settings.` | On-device selected, model not installed | Install the model, or select Cloud if you have Pro and a key |
| `transcription produced no words — cannot build a cut` | The audio contained no recognisable speech | Check that you loaded the right file and that it has audio |
