Audio & Video Transcription to JSON: RAG Chunks + Timestamps
Pricing
from $12.00 / 1,000 audio minute, standard tiers
Audio & Video Transcription to JSON: RAG Chunks + Timestamps
Transcribe audio and video to JSON with the same RAG chunk schema as pdf-to-json-tables: chunks with time citations, timestamped segments, full text, SRT and VTT. Open-source Whisper on CPU, no API key, two accuracy tiers, pay per audio minute.
Pricing
from $12.00 / 1,000 audio minute, standard tiers
Rating
0.0
(0)
Developer
Landon Brewington
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Give this Actor audio or video URLs and get the same JSON your PDF pipeline already understands. It is the sibling of pdf-to-json-tables: both return RAG chunks in the exact same chunk schema, the PDF Actor with page citations, this one with time citations, so one ingestion pipeline can index reports and recordings the same way and show "p. 3" or "00:12:03-00:12:48" as the source.
{ "chunkIndex": 4, "text": "...", "charStart": 4712, "charEnd": 5899, "citation": { "type": "page", "page": 3, "label": "p. 3" } }{ "chunkIndex": 4, "text": "...", "charStart": 4712, "charEnd": 5899, "citation": { "type": "time", "startMs": 723000, "endMs": 768000, "label": "00:12:03-00:12:48" } }
On top of the chunks you get timestamped segments (the audio equivalent of table cells with coordinates: every sentence with startMs, endMs and a confidence score, optionally every word), the full text, and SRT and VTT subtitle files. Speech recognition is open-source Whisper (whisper.cpp) running on CPU inside the Actor: no API key, no third-party speech service, two accuracy tiers, pay per audio minute. Video files (MP4, MOV, WebM, MKV) are transcribed from their audio track, so it is a video transcription, podcast transcription, meeting transcription, audio to text, speech to text and subtitle generator in one call.
What it does
- Downloads each file from the URL you give (up to 50 per run, 200 MB each by default), checks that it really is media, reads its duration with ffprobe, and transcribes it. Nothing is stored after the run: the file is deleted as soon as it is transcribed.
- Any common format. Audio: MP3, WAV, FLAC, OGG Vorbis, Opus, M4A, AAC, WMA, AIFF. Video: MP4, MOV, WebM, MKV, AVI (the first audio track is used). Decoding is done by ffmpeg, so anything ffmpeg can read works.
- Two accuracy tiers.
standardruns the Whisper base model: fast and cheap, good for clear speech.accurateruns the Whisper small model: noticeably fewer errors on accents, proper names, noisy audio and non-English speech, about three times the compute. Both are multilingual (99 languages) with automatic language detection, and both can translate the transcript to English. - Segments:
index,startMs,endMs,text,confidence(0 to 1, the geometric mean of token probabilities), and withincludeWordTimestampsawordsarray of{word, startMs, endMs, confidence}. - Chunks:
chunkSizecharacters (default 1200, about 300 tokens) withchunkOverlap(default 150), cut at sentence ends when possible. Each chunk carrieschunkIndex,text,charStart,charEnd(offsets intotext),startMs,endMsandcitation. The chunker is the same code as in pdf-to-json-tables. - Subtitles:
<documentId>.srtand<documentId>.vttare written to the run's key-value store and linked fromsubtitles.srtUrlandsubtitles.vttUrl. - Two output shapes:
documents(one dataset item per file, the default) orsegments(one item per segment and one per chunk, each withtype, for recordings so long that one item would be unwieldy). - A file that cannot be fetched or decoded never fails the run: it produces one item with
erroranderrorType(http_403,http_404,not_audio,unsupported_format,no_audio_stream,too_long,too_large,timeout,decode_error) and is not charged. The other files still return data.
Who it is for
- AI agents and RAG pipelines that already ingest PDFs with pdf-to-json-tables and want recordings in the same shape. Call it through the Apify MCP server (see below) and index
chunks[].textwithcitation.labelas the reference. - Podcast, meeting and lecture archives that need searchable text with timestamps, not a wall of words.
- Video teams that want SRT or VTT subtitles for MP4, MOV or WebM files without a desktop tool.
- Researchers and journalists transcribing interviews and public hearings, with time codes to quote exactly.
- Anyone who needs audio to text or video to text for a handful of files without an API key for a speech service.
Quick start
- Open the Actor in Apify Console and press Start. The default input transcribes a 100 second public-domain reading of the Gettysburg Address (LibriVox) in well under a minute.
- Replace the URL with your own MP3, M4A, WAV, MP4 or MOV link. It must point at the media file itself, not a player page or a YouTube URL.
- Pick
accuratewhen the audio is noisy, accented or not in English. Setlanguagewhen you know it (slightly faster, no wrong guesses). - Read results from the default dataset (JSON, CSV or Excel) or the API:
https://api.apify.com/v2/datasets/<datasetId>/items. Subtitle files are in the key-value store; theSUMMARYrecord lists every file's status, duration, minutes billed and timings.
Input example
{"audioUrls": ["https://archive.org/download/gettysburg_shurtagal_librivox/Gettysburg_Address_Lincoln_64kb.mp3"],"model": "standard","language": "auto","translateToEnglish": false,"outputMode": "documents","chunkSize": 1200,"chunkOverlap": 150,"includeWordTimestamps": false,"subtitles": true}
All fields are optional. A run with no input transcribes the Gettysburg Address above.
| Field | Type | Default | Meaning |
|---|---|---|---|
audioUrls | array of strings | one sample MP3 | Public http(s) links to audio or video files, up to 50 |
audioUrl | string | empty | Shortcut for a single URL, merged into audioUrls |
model | standard or accurate | standard | Whisper base (fast) or Whisper small (fewer errors, 3x the compute) |
language | ISO 639-1 code or auto | auto | Spoken language; auto detects it from the first 30 seconds |
translateToEnglish | boolean | false | Return an English translation instead of the spoken language |
outputMode | documents or segments | documents | One item per file, or one per segment and per chunk |
chunkSize | integer | 1200 | Chunk size in characters, 0 disables chunks |
chunkOverlap | integer | 150 | Characters shared by consecutive chunks |
includeWordTimestamps | boolean | false | Add words with start, end and confidence to every segment |
subtitles | boolean | true | Write SRT and VTT files to the key-value store |
maxDurationMinutes | integer 1 to 180 | 180 | Longer files are skipped with a too_long error item |
maxFileSizeMb | integer 1 to 500 | 200 | Larger files are skipped with a too_large error item |
Output example
The item from the default run (text, segments and chunks are shortened here):
{"sourceUrl": "https://archive.org/download/gettysburg_shurtagal_librivox/Gettysburg_Address_Lincoln_64kb.mp3","documentId": "247ecb8f79ca4937c028ffd5ae45d2286c304a9d","fileName": "Gettysburg_Address_Lincoln_64kb.mp3","durationMs": 100336,"transcribedMs": 100336,"durationMinutesBilled": 2,"language": "en","languageProbability": 0.9953,"model": "standard","text": "This is the Libra Box Recording, all the Vox recordings in the public domain. To find out more or see how you can volunteer, please visit LibraBox.org. The Gideysburg Address by Abraham Lincoln, November 19, 1863. Four score and s ...","segments": [{"index": 2,"startMs": 8120,"endMs": 13680,"text": "The Gideysburg Address by Abraham Lincoln, November 19, 1863.","confidence": 0.631},{"index": 3,"startMs": 13680,"endMs": 18440,"text": "Four score and seven years ago our father's brought forth on this continent a new nation","confidence": 0.7007},{"index": 4,"startMs": 18440,"endMs": 23560,"text": "conceived in liberty and dedicated to the proposition that all men are created equal.","confidence": 0.82},...],"chunks": [{"chunkIndex": 0,"text": "This is the Libra Box Recording, all the Vox recordings in the public domain. To find out more or see how you ...","charStart": 0,"charEnd": 563,"startMs": 0,"endMs": 34320,"citation": {"type": "time","startMs": 0,"endMs": 34320,"label": "00:00:00-00:00:34"}},{"chunkIndex": 1,"text": "at civil war, testing whether that nation or any nation so conceived and so dedicated can long endure. We are ...","charStart": 414,"charEnd": 969,"startMs": 23560,"endMs": 57440,"citation": {"type": "time","startMs": 23560,"endMs": 57440,"label": "00:00:24-00:00:57"}},...],"subtitles": {"srtUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/247ecb8f79ca4937c028ffd5ae45d2286c304a9d.srt","vttUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/247ecb8f79ca4937c028ffd5ae45d2286c304a9d.vtt"},"warnings": [],"transcribedAt": "2026-10-23T08:05:08.347Z"}
In segments mode the dataset holds one item per segment (type: "segment", with index, startMs, endMs, text, confidence) and one per chunk (type: "chunk", with chunkIndex, text, charStart, charEnd, startMs, endMs, citation), each also carrying sourceUrl, documentId, fileName, durationMs, language, model and transcribedAt.
Family: the same chunks for PDFs and recordings
pdf-to-json-tables turns PDFs into tables with cell coordinates and RAG chunks with page citations. This Actor turns recordings into segments with time coordinates and RAG chunks with time citations. The chunk object is identical in both:
| Field | pdf-to-json-tables | transcribe-to-json-chunks |
|---|---|---|
chunkIndex | position in the page or document | position in the recording |
text | sentence-aligned chunk of the page text | sentence-aligned chunk of the transcript |
charStart | offset into the page's text | offset into the transcript text |
charEnd | end offset (exclusive) | end offset (exclusive) |
citation | {"type": "page", "page": 3, "label": "p. 3"} | {"type": "time", "startMs": 723000, "endMs": 768000, "label": "00:12:03-00:12:48"} |
The PDF chunks additionally carry page; the transcript chunks additionally carry startMs and endMs at the top level. Chunk boundaries behave the same way because both Actors run the same chunker code (family_chunker.py).
Pricing in plain words
Pay per started minute of audio, nothing else: $0.012 per minute on the standard tier (the audio-minute-standard event) or $0.035 per minute on the accurate tier (the audio-minute-accurate event), plus Apify's standard tiny Actor start fee. A 45 minute podcast episode costs 54 cents on the standard tier and $1.58 on the accurate tier. Minutes are counted per file after the duration is read and before transcription starts; failed downloads, files that are not media and files that cannot be decoded are never charged. You set the maximum you are willing to spend per run; when the limit is reached the Actor transcribes only the covered minutes of the current file, says so in warnings, skips the rest and still finishes successfully. Platform compute is included in the price; these prices were set from measured platform cost so every run clears its own compute with margin.
Speed and accuracy
Measured on the Apify platform on 2026-10-23 with a 13 minute LibriVox short story (MP3, continuous speech) and a 9 minute public-domain educational film (MP4, speech with music and pauses), both in English:
| Tier | Memory | 13 min speech MP3 | 9 min film MP4 |
|---|---|---|---|
standard | 2048 MB | 8.4 min wall time (1.6x real time) | 5.6 min wall time (1.7x real time) |
standard | 4096 MB | 4.6 min wall time (3.0x real time) | 2.7 min wall time (3.7x real time) |
accurate | 2048 MB | ACC2048MAGI_WALL | ACC2048DUCK_WALL |
accurate | 4096 MB | 13.7 min wall time (1.0x real time) | 9.1 min wall time (1.0x real time) |
Rules of thumb: the standard tier runs about 3 times faster than real time at the default 4096 MB (about 1.6 times at 2048 MB); the accurate tier runs at about real time at 4096 MB (about half real time at 2048 MB). A 3 hour recording on the accurate tier therefore takes about 3 hours; the default run timeout is 4 hours. Apify gives CPU in proportion to memory, so doubling memory roughly halves wall time at about the same cost per audio minute. Download and decoding take a few seconds per file; the model loads in under a second.
Accuracy: on the 100 second Gettysburg Address sample the standard tier (Whisper base) misheard "LibriVox" and "Gettysburg" in the spoken intro and got the speech itself right; the accurate tier (Whisper small) got the names right too. Whisper small is roughly 25 to 35 percent fewer word errors than base on common English benchmarks and the gap is larger for accents, noisy audio and other languages. Both models are the multilingual versions, so language: "auto" and non-English speech work on either tier; the English-only .en variants would be slightly more accurate on English alone and are not included.
Limits
- File size: 200 MB per file by default (
maxFileSizeMb, up to 500). Up to 50 URLs per run. - Duration: 180 minutes per file at most (
maxDurationMinutes). Longer recordings should be split; a 3 hour file on the accurate tier also needs the run timeout raised well above the default hour. - Run timeout: the Actor transcribes slower than real time on the accurate tier (see Speed and accuracy). For files over about 40 minutes on the accurate tier, or over about 2 hours on the standard tier, raise the run timeout; the Actor itself stops a file that would exceed the time left and returns a
timeouterror item for it. - Memory: 4096 MB by default, which Apify maps to about one CPU. Both tiers also fit in 2048 MB at about half the speed. Cost per audio minute is roughly the same at either setting, so the default favors speed.
- Speech only. Music, applause and long silences produce no segments (or the odd hallucinated phrase, as with any Whisper model). Speaker labels (diarization) are not provided.
- URLs must be public. Pages behind a login (HTTP 401) or a bot wall (HTTP 403) return an error item; YouTube and other player pages are not media files. Upload such files to storage you control (for example an Apify key-value store) and pass that URL.
- Language detection looks at the first 30 seconds; recordings that start with music or silence in a different language than the speech may be misdetected. Set
languagewhen you know it. - Runs are stateless. Files are fetched from the URLs you provide, decoded on the run's disk and deleted when the run ends. Only the JSON in the dataset and the subtitle files in the key-value store are kept.
Use it from an AI agent (Apify MCP server)
Connect your agent to https://mcp.apify.com (see the Apify MCP docs for the clients it supports). Then:
- Search for the tool:
search-actorswith the query "audio transcription json" or "video to text with timestamps". - Read the schema:
fetch-actor-detailsfor this Actor returns the input fields above and the dataset schema. - Call it:
call-actorwith{"audioUrls": ["https://example.com/episode.mp3"]}, or{"audioUrls": ["..."], "model": "accurate", "language": "de"}for a German recording, or{"audioUrls": ["..."], "outputMode": "segments"}for a long lecture. - Read results with
get-dataset-items. Indexchunks[].textwithcitation.label,startMsandendMsas metadata; quotesegments[].textwith its time code; downloadsubtitles.srtUrlfor captions.
The Actor runs with limited permissions and charges only pay-per-event events, so it works with Apify's agentic payments.
Open-source credits and licenses
Every library linked into the Actor is permissively licensed. ffmpeg is used as a separate command-line program, never linked into our code.
| Component | Role | License |
|---|---|---|
| whisper.cpp | Speech recognition engine (CPU) | MIT |
| pywhispercpp | Python bindings to whisper.cpp | MIT |
Whisper base and small models (ggml, 8-bit quantized) from the whisper.cpp model repository | Speech models, multilingual | MIT |
| NumPy | Audio buffers | BSD-3-Clause |
| ffmpeg with ffprobe | Decoding and duration, invoked as a separate command-line process, installed from the Alpine package | LGPL/GPL (not linked into our code) |
| Apify SDK for JavaScript, got-scraping | Actor runtime and downloads | Apache-2.0 / MIT |
Base image apify/actor-node:22 (Node.js on Alpine Linux) | Runtime | MIT / various permissive |
Python dependencies pulled in transitively (requests, tqdm, platformdirs, urllib3, idna, certifi, charset-normalizer) are MIT, BSD, MPL or Apache licensed. The Actor's own code is Apache-2.0.
FAQ
Which tier should I use? standard (Whisper base) for clear speech in English and major languages, at $0.012 per minute. accurate (Whisper small) for accents, proper names, noisy audio and smaller languages, at $0.035 per minute and about three times the compute.
How long does it take? At the default 4096 MB the standard tier runs about three times faster than real time and the accurate tier about real time, so a one-hour recording takes about 20 minutes on standard and about an hour on accurate.
Does it handle video? Yes. MP4, MOV, WebM, MKV and AVI are decoded with ffmpeg and the first audio track is transcribed.
Do I need an API key for a speech service? No. Whisper runs inside the Actor on CPU. The only key involved is your own Apify token.
Are my files stored? No. Each file is downloaded, transcribed and deleted when the run ends. The transcript, SRT and VTT live in your own dataset and key-value store.
What do I get for citations? Every chunk carries startMs, endMs and citation.label like 00:12:03-00:12:48, the same chunk schema as pdf-to-json-tables, which uses page citations. Working pipelines for both are in the rag-ingestion-examples repository.
Support
Open an issue on the Actor's Issues tab in Apify Console. Include the run id, the media URL (if you can share it) and the input you used.