Media URL Transcriber - Video, Podcast RSS, Vimeo, Loom to Text
Pricing
from $12.00 / 1,000 stt minute (zero-setup)s
Media URL Transcriber - Video, Podcast RSS, Vimeo, Loom to Text
Transcribe any media URL via API, MCP, or schedule — direct audio/video files, HLS/m3u8, podcast RSS feeds, Vimeo, Loom. Deepgram Nova-3 STT plus free caption reuse when available. Timestamped segments, SRT/VTT subtitles, summaries. Zero setup from $0.005/item; BYOK discount. One JSON row per item.
Pricing
from $12.00 / 1,000 stt minute (zero-setup)s
Rating
0.0
(0)
Developer
Heim AI
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Media URL Transcriber — Video, Podcast RSS, Vimeo, Loom to Text
Any cooperative media URL → transcript. Pass direct files, HLS VOD playlists, Vimeo videos, Loom shares, or podcast RSS feeds; get one JSON dataset row per media item. Zero setup for captioned Vimeo; Deepgram Nova-3 for everything else. Built for MCP agents, API clients, and scheduled pipelines.
| Actor id | kaz_kakyo/media-url-transcriber |
| Minimal input | { "mediaUrls": ["https://vimeo.com/76979871"] } |
| Cost | $0.012/min STT zero-setup · $0.005/min BYOK · $0.005 caption item · $0.005/run start |
| Output | Dataset rows with type: "transcript" or type: "error" |
Supported inputs
| Input | How it works |
|---|---|
| Direct audio/video URL (mp3, mp4, m4a, wav, flac, ogg, opus, aac, webm, mov, mkv) | Deepgram fetches the file (STT) |
HLS .m3u8 VOD playlist | Actor assembles audio, sends to Deepgram |
Vimeo (vimeo.com/{id}, player, unlisted hash) | Published captions ($0.005) when available; else STT |
Loom share/embed (loom.com/share/{32hex}) | Signed mp4 → STT (no keyless captions) |
| Podcast RSS/Atom feed | Latest N episode enclosures → STT |
Use something else instead:
| You have… | Use instead |
|---|---|
| YouTube watch/shorts/youtu.be | kaz_kakyo/youtube-transcripts |
| TikTok / Instagram / Facebook / X page | A dedicated platform transcript actor from the Apify Store |
| Spotify / SoundCloud / Apple Podcasts page | The podcast's RSS feed URL (this actor accepts feeds directly) |
| Google Drive / Dropbox share page | Direct-download / ?dl=1 / raw=1 file URL |
| Only a direct media file URL | Also fine here — or kaz_kakyo/audio-transcriber |
Pricing
| Event | Price | When |
|---|---|---|
| Actor start | $0.005 | Once per run |
| STT minute (zero-setup) | $0.012 | No BYOK key — transcription included |
| STT minute (BYOK) | $0.005 | deepgramApiKey set — you also pay Deepgram ~$0.0043/min |
| Caption item | $0.005 | Vimeo delivered via published captions (no STT) |
Minutes round up per item. Worked examples:
- 30-min podcast episode (zero-setup) → 30 × $0.012 + $0.005 start ≈ $0.365.
- 30-min podcast episode (BYOK) → $0.15 = $0.005×30 min actor fee + ~$0.13 Deepgram wholesale (plus $0.005 start → ~$0.155 actor-side; ~$0.285 all-in with Deepgram).
- Captioned Vimeo (preferCaptions) → $0.005 caption + $0.005 start = $0.01 total.
Call it (MCP / API / schedule)
MCP (agents)
{"actor": "kaz_kakyo/media-url-transcriber","input": {"mediaUrls": ["https://dpgr.am/spacewalk.wav","https://vimeo.com/76979871"]}}
Optional extras:
{"mediaUrls": ["https://feeds.npr.org/510289/podcast.xml"],"episodesPerFeed": 3,"preferCaptions": true,"includeSrt": true,"diarize": true}
After the run, read the default dataset. Filter type === "transcript"; treat type === "error" as per-item failure. Bad/unsupported URLs become error rows and the run still SUCCEEDS. The run fails on Deepgram auth/credit errors, post-charge delivery failure, or when every STT item is stt-unavailable and nothing was delivered (no key configured).
API / apify-client
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('kaz_kakyo/media-url-transcriber').call({ mediaUrls: ['https://vimeo.com/76979871'], includeVtt: true },{ maxTotalChargeUsd: 1.0 },);const { items } = await client.dataset(run.defaultDatasetId).listItems();const transcripts = items.filter((i) => i.type === 'transcript');
REST: POST /v2/acts/kaz_kakyo~media-url-transcriber/runs with your token.
Schedule / chain
- Save a Task with fixed options (
preferCaptions,episodesPerFeed, BYOK key). - Schedule the Task for recurring podcast feeds or URL lists.
- Webhook on
SUCCEEDED— process onlytype === "transcript"rows. - Cap spend with
maxTotalChargeUsd. Over-budget items become unchargedover-budget/ skipped rows. - Chain: RSS scraper or CMS export → this actor. YouTube URLs →
youtube-transcriptsinstead.
Output contract
Success row:
{"type": "transcript","url": "https://vimeo.com/76979871","source": "vimeo-captions","title": "The New Vimeo Player…","videoId": "76979871","transcript": "…","segments": [{ "start": 0.0, "end": 2.4, "speaker": null, "text": "…" }],"srt": "1\n00:00:00,000 --> …","vtt": "WEBVTT\n\n…","durationSeconds": 62,"language": "en","billedEvent": "caption-item","billedCount": 1}
| Field | Notes |
|---|---|
source | direct | hls | vimeo-captions | vimeo-stt | loom | podcast-rss |
segments | Present on success; if the row exceeds ~4 MB, segments (and/or srt/vtt) may be spilled to the key-value store and replaced by segmentsUrl / srtUrl / vttUrl |
srt / vtt | Per includeSrt (default true) / includeVtt (default false); same KVS spill as above when oversized |
summary | STT + summarize + English only; never on caption path |
confidence, model | STT only (model is always nova-3) |
feedUrl, episodeTitle, episodeGuid, pubDate | Podcast RSS rows |
billedEvent, billedCount | Always present |
Dataset views (Transcripts / Errors) select columns for display — they do not filter by row type. Both transcript and error rows appear in the underlying dataset; filter client-side on type.
Error row (never charged):
{"type": "error","url": "https://…","errorCode": "unsupported-platform","error": "…pointed FIX…","billedEvent": null,"billedCount": 0}
errorCode values: unsupported-platform · not-media · not-found · private · too-long · too-large · live-stream · encrypted-hls · stt-unavailable · stt-upstream · no-audio · fetch-failed · feed-empty · invalid-url · over-budget · skipped
When the run itself fails vs. reports a row. Anything wrong with one input (not-found, too-long, no-audio, …) becomes an error row and the run still succeeds — check type per row. Anything that made transcription impossible for the whole run (stt-unavailable = no key available, stt-upstream = Deepgram throttling or down) fails the run when nothing at all was delivered, so an automated caller can retry on status instead of parsing rows. A run that delivered some transcripts still succeeds, with the blocked items recorded as rows.
Retrying after stt-upstream or stt-unavailable. Items blocked because speech-to-text could not run are not checkpointed, so resurrecting the run re-attempts them once the cause clears — you are not charged twice, because charges only ever land on delivery. A re-attempted item keeps its original error row and gains a new row, so deduplicate on url and prefer the row with type: "transcript".
Honest limits
- Loom = STT only — no keyless caption endpoint.
- HLS is beta: fMP4 and MPEG-TS/AAC (or MP3) covered; encrypted, live, and byte-range playlists are rejected. Assembly capped at 512 MB (sequential stream-to-disk).
- No YouTube / TikTok / Instagram / Facebook / X — use dedicated actors.
- Direct-file duration is not knowable pre-STT — clamped by file size (2048 MB) only.
- Summaries are English-only (Deepgram
summarize=v2). - Caption quality = whatever the Vimeo publisher uploaded.
- Privacy: transcripts contain whatever is spoken (or captioned) in the media URLs you submit — that is the product. Treat outputs as sensitive if the source media is.
- Caps: 100 URLs/run, 200 items after feed expansion, default
maxDurationMinutes180.
Input (agent-first)
mediaUrls(required) — see Supported inputs. Prefill demo: spacewalk.wav + public Vimeo (caption path works keyless).episodesPerFeed— default 1 (max 25).preferCaptions— default true (Vimeo caption path).captionLanguage— BCP-47 prefix; fallbacken, then first track.deepgramApiKey— optional BYOK; encrypted; sent only toapi.deepgram.com.language/detectLanguage/diarize/smartFormat/paragraphs/summarize/includeSrt/includeVtt/maxDurationMinutes— see Input tab; every field states its default there.
See the Input tab for the full schema. See the API tab for run/dataset endpoints.