Audio & Video to Text (Whisper) — Transcript + SRT Subtitles avatar

Audio & Video to Text (Whisper) — Transcript + SRT Subtitles

Pricing

from $24.00 / 1,000 transcribed audio minutes

Go to Apify Store
Audio & Video to Text (Whisper) — Transcript + SRT Subtitles

Audio & Video to Text (Whisper) — Transcript + SRT Subtitles

Transcribe an audio file to text with timestamps. Any direct audio or video URL (podcast, MP3, WAV, M4A, MP4) returns plain text, timestamped segments and SRT. Whisper runs in-actor, no API keys. $0.03 per started audio-minute; failures never charged.

Pricing

from $24.00 / 1,000 transcribed audio minutes

Rating

0.0

(0)

Developer

Broke to Built

Broke to Built

Maintained by Community

Actor stats

1

Bookmarked

30

Total users

26

Monthly active users

3 days ago

Last modified

Share

Audio & Video Transcriber — Whisper (no API keys)

Give it a direct audio or video URL, get back the transcript as plain text, timestamped segments, and a ready-to-use SRT subtitle file. Whisper runs inside the actor — no OpenAI key, no third-party transcription service, nothing to configure or sign up for.

  • Model: Whisper small (int8, CPU) via faster-whisper. The model is baked into the actor image, so runs start transcribing immediately — no download wait.
  • Formats: anything FFmpeg can decode — mp3, wav, m4a, ogg, flac, opus, and the audio track of video files (mp4, webm, mov, mkv…).
  • Languages: Whisper's ~100 languages, auto-detected by default (detected language + probability in every record). Optional translate-to-English.

Who uses it

  • Podcasters and video editors who need a transcript and burn-ready SRT captions from an episode URL.
  • Journalists and researchers turning recorded interviews into searchable text.
  • Developers adding speech-to-text to a pipeline without holding an OpenAI or AssemblyAI key.
  • AI agents (over Apify MCP) handed a media link that must read what was said.
  • Anyone with a media archive who wants a bulk pass: hand it a list of URLs, get one record each.

Input

FieldTypeDefaultWhat it does
audioUrlsstring[]a public-domain demo mp3Direct URLs to audio/video files. One dataset record per URL
languagestring"" (auto)ISO 639-1 code (en, es, de, ja…). Empty = auto-detect
formatboth | text | segmentsbothtext = plain text only; segments = timestamped segments + SRT only
translateToEnglishbooleanfalseUse Whisper's translate task instead of transcribing in the original language
maxFileSizeMbinteger500Larger downloads are skipped (recorded, never charged)
maxDurationMinutesinteger600Longer audio is refused before any compute is spent. You rarely need this — the run timeout, not this cap, is what limits length, and a file that overruns the timeout returns the transcript so far

What you get

One dataset record per URL:

FieldMeaning
urlThe URL you supplied
oktrue on success, false on a failure (which is never charged)
durationSecondsDecoded audio length, to 2 decimals
languageLanguage Whisper detected (or the one you forced)
languageProbabilityConfidence in that detection, 0-1
wordCountWords in the transcript
tookMsWall-clock milliseconds for that file
textFull transcript as one string (format = both or text)
segments[{ start, end, text }] phrase-level, seconds (format = both or segments)
srtComplete SRT subtitle file as a string (format = both or segments)
errorPresent with ok:false instead of the transcript when that file failed

Examples

1. Transcribe one file (the built-in demo — run it with empty input)

Input:

{ "audioUrls": ["https://raw.githubusercontent.com/lordbasilaiassistant-sudo/b2b-assets/main/gettysburg_address_64kb.mp3"] }

Real output from that run (a 2:38 public-domain LibriVox recording), with text/segments/srt trimmed for space:

{
"url": "https://raw.githubusercontent.com/lordbasilaiassistant-sudo/b2b-assets/main/gettysburg_address_64kb.mp3",
"ok": true,
"durationSeconds": 157.88,
"language": "en",
"languageProbability": 0.9997,
"wordCount": 299,
"tookMs": 87043,
"text": "This is a LibriVox recording. All LibriVox recordings are in the public domain. [...] Four score and seven years ago, our fathers brought forth on this continent a new nation conceived in liberty [...]",
"segments": [
{ "start": 0.05, "end": 6.01, "text": "This is a LibriVox recording. All LibriVox recordings are in the public domain. For more" },
{ "start": 6.01, "end": 13.13, "text": "information or to volunteer, please visit LibriVox.org." }
],
"srt": "1\n00:00:00,050 --> 00:00:06,010\nThis is a LibriVox recording. [...]"
}

That run cost 3 events = $0.09 (2:38 rounds up to 3 started minutes).

2. Subtitles only, for a video file

{
"audioUrls": ["https://example.com/interview.mp4"],
"format": "segments"
}

You get segments and srt and no text field — write srt straight to a .srt file next to the video. The audio track is pulled out of the video container for you; you do not need to demux anything first.

3. Batch, with the language forced and translation on

{
"audioUrls": [
"https://example.com/ep01.mp3",
"https://example.com/ep02.mp3",
"https://example.com/broken-link.mp3"
],
"language": "es",
"translateToEnglish": true
}

Three records come back. The dead link returns { "url": "...", "ok": false, "error": "HTTP 404 from server" } and is not charged; the other two transcribe Spanish speech into English text. Forcing language skips detection and helps on short or noisy clips where auto-detect can guess wrong.

Call it from code

curl — synchronous run, JSON straight back:

curl -X POST "https://api.apify.com/v2/acts/eliai~audio-transcriber-whisper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"audioUrls":["https://example.com/episode.mp3"]}'

Python (pip install apify-client):

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("eliai/audio-transcriber-whisper").call(
run_input={"audioUrls": ["https://example.com/episode.mp3"]}
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if row["ok"]:
open("episode.srt", "w", encoding="utf-8").write(row["srt"])
print(row["language"], row["wordCount"], "words")

Node.js (npm install apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('eliai/audio-transcriber-whisper').call({
audioUrls: ['https://example.com/episode.mp3'],
format: 'text',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].text);

Speed and limits (measured, not estimated)

  • Whisper small on CPU — solid accuracy for clear speech. It is not a GPU service and will not match large-model accuracy on very noisy audio or heavy accents.
  • Measured at the default 4 GB actor memory (one full CPU core): the 2:38 test file end-to-end in 87 s, a 36-minute file in 838 sroughly 2.3-2.6x faster than realtime, varying with platform CPU contention.
  • Peak memory is flat at ~1.7 GB whatever the file length, because audio is transcribed in 10-minute windows rather than loaded whole. A 3-minute clip and a 6-hour audiobook have the same footprint.
  • About 145 minutes of audio fit inside the default 3600 s run timeout. For longer files raise the timeout under Input > Run options, or split the file. If the timeout arrives first you still get the transcript so far, flagged truncated, and are charged only for the minutes actually transcribed.
  • Download timeout 30 s per file; size cap 500 MB by default (maxFileSizeMb, up to 1000).
  • Segments are phrase-level (start/end in seconds). Word-level timestamps are not included.
  • No speaker diarization — the transcript does not say who is talking.
  • Decoding and transcription run in a separate process, so a crash on one file hands back the partial transcript with an explanation instead of failing your whole run.

Pricing

Pay per event, one event: audio-minute.

EventWhat one event coversPrice
audio-minuteOne started minute of audio successfully transcribed (duration rounded up)$0.03

A 2:38 file is 3 events = $0.09. A 45-minute podcast is 45 events = $1.35. There is no start fee and no monthly fee. Failed downloads, oversized or over-long files, and undecodable inputs are recorded in the dataset with ok:false and never charged.

Comparators on the Apify store, read from their listings on 2026-08-07 (check them yourself — store prices change):

ActorPrice
This actor$0.03 / audio-minute
tictechid/vanzi-universal-transcriber$0.0025 / transcription-second = $0.15 / audio-minute
memo23/video-audio-transcriber$0.02-0.05 / audio-minute

Honest note: this is cheaper than GPU-backed services partly because you are not paying for idle GPU time, and partly because it is slower per minute of audio. That trade is the product.

When NOT to use this

  • You need a YouTube, TikTok, or Spotify link transcribed. This takes a direct media file URL — a watch page is not a file. Send one anyway and you get a plain-English row telling you so, free of charge. For YouTube use eliai/youtube-transcript-clean; for TikTok use eliai/tiktok-transcript-clean.
  • You need word-level timestamps or karaoke-style alignment. Segments are phrase-level only.
  • You need to know who said what. There is no speaker diarization.
  • You need a 3-hour file back in five minutes. CPU Whisper runs slower than realtime; a long file is a long run. Split it, raise memory, or use a GPU service.
  • The audio is heavily accented, very noisy, or highly technical and you cannot tolerate errors. small is a good general model, not a medical or legal transcription service. Always review before publishing.
  • The file is private or behind a login. Only public URLs you supply are fetched — no credentials, no cookies.

FAQ

How do I transcribe a podcast episode to text? Put the episode's direct .mp3 URL in audioUrls and run it. Most podcast feeds expose that URL in the RSS <enclosure> tag. You get the plain text, the timestamped segments, and an SRT.

How do I generate SRT subtitles from a video? Pass the video URL (mp4, webm, mov, mkv) and set format to segments. The srt field in the result is a complete subtitle file — write it to a .srt next to your video. The audio track is extracted for you.

Do I need an OpenAI API key? No. Whisper runs inside this actor; there is no external API call and no key to manage. That is the main reason to use it over a wrapper around someone else's API.

Which Whisper model does it use, and can I change it? Whisper small, int8-quantized, on CPU. The model is fixed — it is baked into the image so runs start instantly. If you need large-v3 accuracy, this is not the right actor.

Can it transcribe a language other than English? Yes, around 100 languages, auto-detected. Set language to an ISO 639-1 code to skip detection (more reliable on short or noisy clips), and set translateToEnglish to get English output from non-English speech.

How much does it cost to transcribe an hour of audio? 60 started minutes = 60 events = $1.80. Failures cost nothing.

How long does a run take? Roughly 0.4-0.45 minutes of processing per minute of audio at the default 4 GB memory — about 2.3-2.6x faster than realtime (measured: 87s end-to-end for a 2:38 clip, 838s for a 36-minute file). About 145 minutes of audio fit inside the default 3600s run timeout; for anything longer, raise the timeout under Input > Run options, or split the file.

What happens if the transcriber crashes half way through my file? You get the part it finished, marked ok:false with the reason, and you are not charged for that file at all. Decoding and transcription run in a separate process precisely so that a crash returns a partial transcript instead of a failed run.

Changelog

2026-08-27. Listing bake: the FAQ and Pricing sections that were already in source are now in the README the store actually serves (they lived in git, not in the live build). No code or price change.

2026-08-27 (health). Parent process now asks the Linux OOM killer to spare it (PID 1) and the transcriber child volunteers to die instead, with its address space capped short of the container. A memory death that used to fail the whole run should now return the transcript so far, uncharged. No price change.

2026-08-22. Decoding and transcription moved into a child process. Some media files could previously kill the run outright — an out-of-memory kill or a decoder crash inside FFmpeg stops a process without raising an error anyone can catch, so the run ended as a bare failure with no output and no explanation. Those deaths are now contained: you get every minute that was transcribed before it stopped, a plain-English reason, and no charge for that file. Also: URLs that return a web page instead of a media file (YouTube, Spotify, or any HTML page) now say so and name the Actor that does the job, instead of returning an FFmpeg error code.

What happens if one URL in my batch is dead? That record comes back with ok:false and an error message, the rest still transcribe, and the failure is never charged.

Who made this

Broke to Built — a company of machines, building things it gives away. This is one of them; the rest are free too.

For AI agents

This Actor is built to be called by software, not just by people.

  • Mount it directly as an MCP tool — no Store search, no ranking, just this one tool: https://mcp.apify.com/?actors=eliai/audio-transcriber-whisper
  • Or call it over HTTP and get the results in the same request: POST https://api.apify.com/v2/acts/eliai~audio-transcriber-whisper/run-sync-get-dataset-items
  • Pay with x402, without an Apify account. This Actor is whitelisted for agentic payments, so an agent holding USDC on Base can buy a prepaid token and spend it here. The minimum purchase is $1, the token balance is an absolute spending cap, and it expires 14 days after purchase.
  • Costs are predictable before you call. Pricing is pay-per-event (see Pricing above), so an agent can budget a run in advance instead of discovering the bill afterwards.
  • Send only the field you mean. If you pass the bulk field, it is used on its own; the single-value field is a fallback, never merged into your request. You are charged for the items you sent and nothing else.