Speech to Text (Whisper): Video & Audio Transcription
Pricing
Pay per usage
Speech to Text (Whisper): Video & Audio Transcription
Word-level speech to text on CPU with whisper.cpp. Transcribe video or audio in 90+ languages and get word timestamps, confidence scores and ready-to-use caption segments as JSON.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Andrew Babo
Maintained by CommunityActor stats
0
Bookmarked
26
Total users
22
Monthly active users
a day ago
Last modified
Share
Speech to Text (Whisper) — Video & Audio Transcription with Word Timestamps
Turn any audio or video file into an accurate transcript with word-level timestamps, confidence scores and ready-to-use caption segments. Runs whisper.cpp on CPU — no GPU, no API keys, no local install.
Use it for: subtitles and SRT-style captions, searchable video archives, podcast show notes, meeting notes, content repurposing, dataset labelling.
- 90+ languages, or automatic language detection
- Word timestamps, so captions can be split to any length
- Accepts MP4, MOV, MKV, WebM, MP3, WAV, M4A, OGG… (converted internally to 16 kHz mono)
- Accepts a public URL or a key-value-store record from a previous run
- Optional time window, so long media can be sharded across parallel runs
Quick start
{"op": "transcribe","source": "https://example.com/interview.mp4","options": { "preset": "balanced", "language": "en" }}
Feature-detect the build (free, a few seconds, needs no source):
{ "op": "capabilities" }
Input
| Field | Type | Notes |
|---|---|---|
op | transcribe | capabilities | default transcribe |
source | string | https:// URL or kv:<storeId>/<key>. Audio or video. |
options.preset | fast | adaptive | balanced | accurate | speed vs accuracy |
options.language | ISO code (en, vi, es…) | omit for auto-detect |
options.model | model name | overrides the preset default |
options.threads | integer | defaults to the run's vCPU count |
options.segment_gap_ms | number | silence gap that starts a new caption segment |
options.start_sec / duration_sec / overlap_sec | number | transcribe one window only |
options.keep_raw_json | boolean | also store the raw whisper output |
output.signed_upload_url | string | PUT transcript.json into your own storage |
cleanup | on_success | always | off | artifact retention |
callback | object | { url, secret_header: { name, value } } webhook |
Presets
| Preset | Best for | Relative speed |
|---|---|---|
fast | drafts, search indexing | fastest |
adaptive | mixed content, unknown quality | fast |
balanced | default choice for captions | medium |
accurate | publishing, noisy audio, accents | slowest |
Output
{"status": "success","op": "transcribe","artifacts": [{ "name": "transcript", "kv_key": "transcript.json", "url": "https://api.apify.com/v2/key-value-stores/.../transcript.json" }],"meta": {"language": "en","duration_sec": 338.4,"word_count": 912,"model": "…","words": [{ "id": 0, "text": "Hello", "startMs": 120, "endMs": 410, "confidence": 0.98 }],"segments": [{ "startMs": 120, "endMs": 4120, "text": "Hello and welcome back to the show" }]}}
words[]— one entry per word with start/end in milliseconds and confidence.segments[]— sentence-like caption blocks, split on pauses (segment_gap_ms).- The full transcript is also stored as the
transcript.jsonartifact.
Sharding a long file
Pass a window and the actor transcribes only that slice; timestamps are offset
back to the original timeline, and words inside the tail overlap are flagged
_overlap so you can de-duplicate when merging shards.
{"op": "transcribe","source": "https://example.com/audio16k.wav","options": { "start_sec": 600, "duration_sec": 300, "overlap_sec": 1.5 }}
For heavy parallel fan-out, use the dedicated Fast Speech to Text actor, which keeps the model warm and processes a list of windows per run.
Error handling
{ "ok": false, "reason": "BAD_INPUT", "message": "..." }
reason | Meaning | What to do |
|---|---|---|
BAD_INPUT | missing/unreadable source | verify the URL is publicly reachable |
UPSTREAM_BLOCKED | the host refused the download | host the file yourself, or fetch it first |
TIMEOUT | run exceeded its timeout | shard the media, or pick a faster preset |
OOM_LIMIT | not enough memory | run with 16 GB |
INTERNAL | unexpected failure | retry; report the run ID |
Performance
Measured on a 16 GB Apify run (≈4 vCPU), CPU only:
| Media length | fast | balanced | accurate |
|---|---|---|---|
| 5 min | ~1 min | ~2 min | ~4 min |
| 30 min | ~5 min | ~10 min | ~20 min |
| 60 min | shard it | shard it | shard it |
For anything over ~30 minutes, extract 16 kHz mono audio first (see the Video & Audio Toolkit actor) and transcribe in parallel windows.
FAQ
Does it need a GPU or an API key? No. It runs whisper.cpp on CPU inside the actor.
Which languages are supported? All Whisper languages (90+). Leave
language empty to auto-detect, or set it explicitly for better accuracy.
Can I get SRT/VTT? The output gives word and segment timings in milliseconds; building SRT/VTT from that is a few lines of code, and lets you choose your own caption length.
Can I transcribe a YouTube link directly? Not here — resolve/download the
media first with the Video Downloader or Video & Audio Toolkit actor,
then pass the resulting URL as source.
Are speaker names included? No. Pair it with the Speaker Diarization actor, which can label this transcript with who spoke each word.