Audio & Video Transcription (Whisper): Podcast, MP3 to SRT
Pricing
Pay per event
Audio & Video Transcription (Whisper): Podcast, MP3 to SRT
Transcribe MP3, MP4, WAV and other audio/video files, podcast RSS feeds and Apple Podcasts links with Whisper. Get text, timestamped segments, SRT/VTT subtitles and word timestamps in 99 languages. Pay per audio minute.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Tidewell Software
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 hours ago
Last modified
Categories
Security
Limited permissionsShare
Audio & Video Transcription with Whisper: podcasts, MP3, MP4 to text and SRT
Transcribe audio and video files, podcast RSS feeds and Apple Podcasts links to text with OpenAI's open-source Whisper model. Each file gives you plain text, timestamped segments, SRT and VTT subtitles and, if you want them, word-level timestamps, in 99 languages with automatic language detection.
- Any direct media link. MP3, M4A, WAV, FLAC, OGG, OPUS, AAC, MP4, MOV, WEBM, MKV, AVI and more. Video files are fine: only the audio track is read.
- Podcasts built in. Paste an RSS feed and choose how many episodes, with title and date filters. Apple Podcasts show and episode links are resolved to the show's public feed. Episode title, date and podcast name are added to every row.
- Subtitles that read well. SRT and VTT cues are cut from word timings at sentence and clause boundaries, at most 42 characters per line and 2 lines, which is the broadcast standard (you can change both).
- Private by design. Transcription runs inside the Actor with faster-whisper. Your audio is not sent to OpenAI or any other third-party API.
- Pay per audio minute. From $0.004 per minute. Failed downloads, broken files and files with no speech are free.
What can you use it for?
| Use case | How |
|---|---|
| Podcast show notes, blog posts and SEO | Give the feed URL, set maxEpisodesPerFeed, then use text |
| Subtitles for videos and reels | Give the MP4/MOV link or upload it, then download srt_url or vtt_url |
| Searchable archives of interviews, lectures and meetings | Use segments (sentence + start/end seconds) to jump to the moment |
| AI agents, RAG and LLM pipelines | Feed text or segments to Claude, GPT or a vector store |
| Translate any language to English | task: translate |
| n8n / Make / Zapier automations | Call the Actor with a file URL and read the dataset row |
Input
{"mediaUrls": ["https://feeds.example.com/my-podcast.rss","https://cdn.example.com/interview.mp3","https://example.com/videos/webinar.mp4"],"maxEpisodesPerFeed": 3,"model": "small","language": "auto","wordTimestamps": false}
| Field | Default | What it does |
|---|---|---|
mediaUrls | Direct audio/video file links, podcast RSS/Atom feeds, Apple Podcasts links, or web pages that embed a media file (<audio>, <video>, og:audio). Google Drive and Dropbox share links work | |
uploadedFiles | Upload files from your computer in the Console | |
maxEpisodesPerFeed | 1 | Episodes per feed, newest first. 0 = all that match |
episodeTitleFilter | Only episodes whose title contains this text. Use | for alternatives | |
episodesPublishedAfter, episodesPublishedBefore | YYYY-MM-DD, or relative like 30 days | |
model | base | tiny, base, small, medium or large-v3-turbo (see below) |
language | auto | Spoken language, or auto-detect |
task | transcribe | translate gives an English translation |
wordTimestamps | off | Every word with start, end and confidence. No extra cost |
initialPrompt | Names and jargon to steer spelling, e.g. "Kubernetes, Grafana, Dr. Nkemelu" | |
vadFilter | on | Skip silence and music (faster, avoids made-up text in silent parts) |
subtitleMaxLineLength, subtitleMaxLines | 42 / 2 | Subtitle layout |
maxDurationMinutes | whole file | Transcribe only the first N minutes of each file |
maxFileSizeMb, downloadTimeoutSecs | 2000 / 900 | Limits |
httpHeaders | Headers for private file servers or private feeds |
Which model?
Measured on Apify at the default 4 GB of memory (1 CPU core), on a 5.4-minute LibriVox recording:
| Model | Speed | Accuracy | Price per minute |
|---|---|---|---|
tiny | about 20x realtime | Rough drafts, keyword search | $0.004 |
base (default) | about 8x realtime | Good for clear English speech | $0.004 |
small | about 3x realtime | Clearly better on names, accents and other languages | $0.009 |
medium | about 1x realtime (2x at 8 GB) | High accuracy | $0.025 |
large-v3-turbo | about 1x realtime (2x at 8 GB) | High accuracy, best for many languages | $0.025 |
A 1-hour podcast takes about 8 minutes with base and about 20 minutes with small at 4 GB. More memory makes runs faster: Apify gives one CPU core per 4 GB, and the Actor uses all of them. For medium and large-v3-turbo, use 8-16 GB. The price per minute is the same at any memory.
Output
One dataset row per file. The TXT, SRT, VTT and JSON files are also saved to the run's key-value store and linked from the row.
{"media_id": "media-0001","status": "succeeded","source_url": "https://feeds.example.com/my-podcast.rss","source_type": "rss","media_url": "https://cdn.example.com/episodes/ep42.mp3","title": "Ep 42: Pricing your first product","podcast_title": "The Indie Hour","episode_published_at": "2026-11-03T06:00:00+00:00","duration_secs": 2843.2,"transcribed_secs": 2843.2,"billed_minutes": 48,"model": "small","language": "en","language_probability": 0.998,"text": "Welcome back to the Indie Hour. Today we're talking about pricing...\n\nSo the first thing I did was...","word_count": 7412,"segments": [{ "id": 0, "start": 0.42, "end": 3.1, "text": "Welcome back to the Indie Hour." },{ "id": 1, "start": 3.48, "end": 7.92, "text": "Today we're talking about pricing your first product." }],"srt_url": "https://api.apify.com/v2/key-value-stores/.../records/media-0001-ep42.srt","vtt_url": "https://api.apify.com/v2/key-value-stores/.../records/media-0001-ep42.vtt","text_url": "https://api.apify.com/v2/key-value-stores/.../records/media-0001-ep42.txt","json_url": "https://api.apify.com/v2/key-value-stores/.../records/media-0001-ep42.json","processing_secs": 951.3,"speed_x": 3.0,"errors": [],"warnings": []}
With wordTimestamps on, rows also have words: [{"start": 0.42, "end": 0.71, "word": " Welcome", "probability": 0.98}, ...].
SRT example:
100:00:00,420 --> 00:00:03,100Welcome back to the Indie Hour.200:00:03,480 --> 00:00:07,920Today we're talking about pricingyour first product.
Failed files get status: "failed" and an error code, such as download_failed, unsupported_platform, not_media, no_media_found, no_audio_stream, decode_failed, no_episodes or file_too_large. Files skipped because the run hit your cost limit get status: "skipped". Neither is charged.
The dataset has four views: Overview, Transcripts, Segments (one row per sentence) and Status & errors.
Use from the API, n8n or Make
curl -X POST "https://api.apify.com/v2/acts/tidewell~media-transcriber/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"mediaUrls": ["https://example.com/interview.mp3"], "model": "small"}'
Synchronous calls wait up to 5 minutes, which is enough for about 30 minutes of audio with base. For longer files, start the run asynchronously and read the dataset when it finishes. In n8n or Make, use the Apify node with "Run Actor" and "Get dataset items".
Python:
from apify_client import ApifyClientclient = ApifyClient("<APIFY_TOKEN>")run = client.actor("tidewell/media-transcriber").call(run_input={"mediaUrls": ["https://feeds.example.com/my-podcast.rss"], "maxEpisodesPerFeed": 5, "model": "small",})for row in client.dataset(run["defaultDatasetId"]).iterate_items():if row["status"] == "succeeded":print(row["title"], row["srt_url"])
Pricing
Pay per event, per minute of audio transcribed. A file is billed seconds transcribed / 60, rounded up to the next minute.
| Event | Price | When |
|---|---|---|
| Audio minute (tiny or base) | $0.004 | Per minute transcribed with tiny or base |
| Audio minute (small) | $0.009 | Per minute transcribed with small |
| Audio minute (medium or large-v3-turbo) | $0.025 | Per minute transcribed with medium or large-v3-turbo |
| Actor start | $0.0005 per GB of memory | Once per run ($0.002 at the default 4 GB) |
| Example | Cost |
|---|---|
1-hour podcast episode, base | $0.24 |
1-hour podcast episode, small | $0.54 |
10 x 45-minute episodes, small | $4.05 |
100 one-minute clips, base (one run) | $0.40 |
Failed downloads, broken or unsupported files and files with no speech cost nothing. The Actor respects your maximum cost per run: before each file it works out how many minutes your limit still pays for and transcribes only that much, so it never does work it cannot bill.
FAQ
Can I transcribe YouTube, TikTok, Instagram, Spotify or Vimeo links? No. Downloading from those platforms breaks their terms of service, and Spotify audio is DRM-protected, so the Actor refuses those links with unsupported_platform (not charged). If you own the video, download it and upload the file, or use a direct file link from your own storage. For YouTube captions, a YouTube transcript Actor that reads the official captions is the better tool.
Which podcast links work? Any public RSS or Atom feed with audio/video enclosures (Buzzsprout, Libsyn, Anchor/Spotify for Podcasters RSS, Megaphone, Transistor, Podbean, Simplecast and more), and Apple Podcasts show or episode links, which are resolved through Apple's public lookup API to the show's own feed. Spotify-exclusive shows have no public feed.
Does it identify speakers (diarization)? Not yet. You get timestamps per sentence and per word, not speaker labels.
How accurate is it? It is Whisper. base is good on clear speech in English and the big European languages. Use small or larger for accents, names, noisy audio, phone calls and other languages. Adding names and jargon to initialPrompt helps with spelling.
What about music, silence or ads with no speech? Voice activity detection skips them, so they take little time and produce no made-up text. A file with no speech at all is not charged.
How long can files be? There is no fixed limit. Audio is decoded in 10-minute windows, so memory stays low even for multi-hour recordings. Very long files simply take longer; use more memory to speed them up. Files over 2 GB need maxFileSizeMb.
Is my audio stored or shared? Files are downloaded to the Actor's temporary disk and deleted after transcription. Transcripts are saved only to your own run's dataset and key-value store, under your retention settings. Nothing is sent to OpenAI or other APIs.
Are the transcripts mine to use? The transcript is yours, but the rights in the audio belong to whoever owns it. Only transcribe media you own or have permission to use.
Keywords
audio to text, speech to text, transcribe mp3, mp3 to text, video to text, mp4 to text, podcast transcription, podcast transcript, rss to text, whisper, whisper api, faster-whisper, openai whisper, srt subtitles, vtt subtitles, subtitle generator, word timestamps, transcription api, transcribe audio, audio transcription, wav to text, m4a to text, translate audio to english