# Audio & Video Transcriber – Whisper Speech to Text, SRT, VTT (`gazidev/media-transcriber`) Actor

Transcribe audio and video files and podcast RSS feeds to text with Whisper. Any direct mp3, m4a, wav, ogg, mp4 or webm link, Dropbox or Google Drive. 99 languages, auto-detect, translate to English, word timestamps. Get text, timestamped segments, SRT and VTT subtitles. From $0.009 per minute.

- **URL**: https://apify.com/gazidev/media-transcriber.md
- **Developed by:** [Cemal Atakli](https://apify.com/gazidev) (community)
- **Categories:** AI, Videos, For creators
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $9.00 / 1,000 minute transcribeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Audio & Video Transcriber – Whisper Speech to Text (SRT, VTT, JSON)

Turn **audio and video files into text** with OpenAI's **Whisper** speech recognition. Paste direct links to **mp3, m4a, wav, ogg, flac, mp4, mov or webm** files, Dropbox or Google Drive share links, or a **podcast RSS feed**. You get the full transcript, the detected language, **timestamped segments**, ready-to-use **SRT and WebVTT subtitles**, and downloadable **.txt, .srt, .vtt and .json** files.

Whisper runs inside the Actor (faster-whisper, int8 on CPU). **No OpenAI API key, no upload, no subscription.** You pay **$0.009 per minute** of audio, and failed files are free.

### What it does

- **Speech to text in 99 languages.** The language is detected automatically, or you can force one (`en`, `es`, `de`, `fr`, `pt`, `tr`, `ja`, `zh`…).
- **Translate to English.** Set `task: translate` to get English text and subtitles from any spoken language, at the same price.
- **Subtitles ready to upload:** SRT for YouTube Studio, Premiere, DaVinci Resolve and CapCut, and WebVTT for HTML5 `<track>`, Vimeo and LMS players. Lines are wrapped at 42 characters.
- **Timestamped segments** (`start`, `end`, `text`) and optional **word-level timestamps** with confidence scores, for karaoke captions, search and clip cutting.
- **Podcast RSS feeds:** give a feed URL and the newest N episodes (enclosures) are transcribed, with episode title and publish date.
- **Files in the key-value store:** each transcript is saved as `.txt` (with paragraphs), `.srt`, `.vtt` and `.json`, with direct download links in the row.
- **Three Whisper models:** `tiny` (fastest), `base` (default, good for clear speech) and `small` (most accurate for accents, noise and non-English).
- **Skips silence** with voice activity detection (VAD). It is faster and avoids hallucinated words during pauses and music.
- **Length and cost control:** `maxDurationMinutes` cuts or skips long files, and the Actor never transcribes more minutes than your *Maximum cost per run* allows.
- **Robust:** downloads are retried, web pages and private links are detected, and every failure becomes a clear, free error row. One bad file never stops the run.

#### What it does not do

**YouTube, TikTok, Instagram, Spotify, Facebook, X/Twitter, Vimeo and SoundCloud links are rejected** with a clear error. Their terms of service do not allow downloading their media with third-party tools. Use a direct link to a file you have the rights to: your own upload, the podcast's RSS feed or enclosure URL, a cloud storage link, or a CDN or S3 URL.

### Use cases

- **Podcasters:** show notes, blog posts, SEO pages and accessible transcripts for every episode, straight from your RSS feed.
- **Video creators and editors:** SRT/VTT captions for your own videos, Reels and course lessons. Translate captions to English for a wider audience.
- **Researchers and journalists:** transcribe interviews, focus groups, lectures and public-domain archives (Internet Archive, government recordings).
- **AI and RAG pipelines:** convert audio libraries into searchable text with timestamps for LLM summarization, Q\&A and chaptering.
- **Meeting and call recordings** (that you own) exported to Dropbox or Google Drive.
- **Language learning and accessibility:** word-timed transcripts and captions.

### Input example

```json
{
  "mediaUrls": [
    "https://archive.org/download/spc141_1503_librivox/spc141_spiderandfly_lcw_64kb.mp3",
    "https://www.dropbox.com/scl/fi/abc123/interview.m4a?rlkey=xyz&dl=0",
    "https://drive.google.com/file/d/1AbCdEf.../view?usp=sharing"
  ],
  "podcastFeedUrls": ["https://feeds.example.com/my-podcast.xml"],
  "maxEpisodes": 3,
  "model": "base",
  "language": "auto",
  "task": "transcribe",
  "wordTimestamps": false,
  "maxDurationMinutes": 60
}
```

The default input transcribes a 4-minute public-domain LibriVox poem (35 s end to end on a laptop core; expect about 1 minute on Apify). Whisper output is not perfect: names and rare words can be misheard (here "Howett" for "Howitt").

| Field | Default | Notes |
|---|---|---|
| `mediaUrls` | LibriVox sample | Direct media links. Dropbox `?dl=0`, Google Drive `/file/d/…/view` and OneDrive links are converted to direct downloads automatically |
| `podcastFeedUrls` / `maxEpisodes` | – / 3 | RSS 2.0 or Atom feeds; newest episodes first |
| `model` | `base` | `tiny`, `base` ($0.009/min) or `small` ($0.05/min) |
| `language` | `auto` | Or a Whisper code such as `en`, `de`, `es`, `fr`, `tr` |
| `task` | `transcribe` | `translate` gives English output |
| `wordTimestamps` | false | Adds `words` to each segment |
| `initialPrompt` | – | Vocabulary hint for names and jargon |
| `vadFilter` | true | Skip silence |
| `maxDurationMinutes` / `longFileHandling` | 60 / `truncate` | `truncate` transcribes the first N minutes, `skip` ignores the file (free) |
| `maxFileSizeMB` | 2000 | Larger downloads are stopped (free) |
| `saveFiles` | true | Save .txt/.srt/.vtt/.json to the key-value store |
| `includeSegments` | true | Keep the `segments` array in dataset rows |

### Output example

One dataset row per file. The **Transcripts**, **Subtitles (SRT & VTT)** and **Errors** views are in the Output tab.

```json
{
  "type": "transcript",
  "url": "https://archive.org/download/spc141_1503_librivox/spc141_spiderandfly_lcw_64kb.mp3",
  "status": "ok",
  "model": "base",
  "task": "transcribe",
  "language": "en",
  "languageProbability": 0.999,
  "durationSeconds": 244.85,
  "transcribedSeconds": 244.85,
  "truncated": false,
  "billableMinutes": 5,
  "wordCount": 526,
  "segmentCount": 47,
  "text": "The Spider and the Fly, by Mary Howett, read for Librevox.org by Larry Wilson. An up-a-log, a new version of an old story. Will you walk into my parlour, said the spider to the fly, …",
  "segments": [
    {"id": 0, "start": 0.24, "end": 9.12, "text": "The Spider and the Fly, by Mary Howett, read for Librevox.org by Larry Wilson."},
    {"id": 1, "start": 9.12, "end": 12.16, "text": "An up-a-log, a new version of an old story."}
  ],
  "srt": "1\n00:00:00,240 --> 00:00:09,120\nThe Spider and the Fly, by Mary Howett,\nread for Librevox.org by Larry Wilson.\n\n2\n…",
  "vtt": "WEBVTT\n\n00:00:00.240 --> 00:00:09.120\nThe Spider and the Fly, by Mary Howett,\nread for Librevox.org by Larry Wilson.\n\n…",
  "txtFileUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/001-spc141-spiderandfly-lcw-64kb.txt",
  "srtFileUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/001-spc141-spiderandfly-lcw-64kb.srt",
  "vttFileUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/001-spc141-spiderandfly-lcw-64kb.vtt",
  "jsonFileUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/001-spc141-spiderandfly-lcw-64kb.json",
  "contentType": "audio/mpeg",
  "fileSizeBytes": 1960448,
  "processingSeconds": 30.1,
  "realtimeFactor": 0.123,
  "cpuSecondsPerAudioMinute": 6.75,
  "transcribedAt": "2026-10-04T09:35:12Z"
}
```

- Podcast episodes also have `feedUrl`, `feedTitle`, `episodeTitle` and `episodePublished`.
- With `wordTimestamps`, each segment has `words: [{start, end, word, probability}]`.
- `truncated: true` with `truncatedReason` (`maxDurationMinutes` or `maxTotalCharge`) means only the first `transcribedSeconds` were transcribed and billed.
- Failed inputs are rows with `"type": "error"` and an `error` message. They are free.
- The key-value store record `OUTPUT` holds the run summary: files, audio minutes, speed and whether the run stopped at the cost limit.

See `SAMPLE_OUTPUT.json` for complete rows (an mp3, a webm video, a podcast RSS episode and a rejected YouTube link).

### Pricing

Pay per event: you pay only for **minutes of audio actually transcribed**, rounded up per file to the started minute (a 61.5-second file is 2 minutes, a 60.4-second file is 1).

| Event | Price |
|---|---|
| Minute transcribed, `tiny` or `base` model | **$0.009** |
| Minute transcribed, `small` model | $0.05 |
| Actor start | $0.00005 |

One hour of podcast with the default model costs **$0.54**. Failed downloads, rejected links, skipped files and minutes cut by `maxDurationMinutes` are free.

Compared with other Store Actors (public Store prices, 2026-10-04):

| Actor | Price per audio minute | Platform downloading (YouTube, TikTok…) | Model choice | Translate to English |
|---|---|---|---|---|
| **Audio & Video Transcriber (this Actor)** | **$0.009** (small: $0.05) | No (ToS-compliant) | tiny / base / small | Yes |
| memo23/video-audio-transcriber | $0.048 ($0.0008/s) + $0.005 per GB at start | Yes | – | – |
| parsebird/video-audio-transcriber | $0.05 | Yes | – | – |
| eliai/audio-transcriber-whisper | $0.03 | – | – | – |
| amanatools/whisper-transcriber | $0.008 + $0.005 per file | – | – | – |
| steadyfetch/media-transcriber | $0.006 | Yes | – | – |

Set **Maximum cost per run** in the run options to cap spending. The Actor transcribes only the minutes that fit in the budget, then stops cleanly.

### FAQ

**Why are YouTube, TikTok, Instagram and Spotify links rejected?**
Their terms of service prohibit downloading their content with third-party tools. Downloading them could get your account or ours suspended and could infringe the creator's rights. If it is your own video, download it from your creator studio (YouTube Studio, TikTok, Instagram data export) and use the file link, or use the podcast's public RSS feed instead of the Spotify page.

**Do I need rights to the media?**
Yes. **Only transcribe media you own, have permission for, or that is in the public domain or under a licence that allows it.** You are responsible for the content you submit. Transcripts of copyrighted material may not be republished without permission.

**How accurate is it?**
`base` is accurate for clear speech in major languages (podcasts, lectures, narration). For strong accents, background noise, several overlapping speakers or less common languages, use `small`. Proper names improve with `initialPrompt` (e.g. `Apify, Kubernetes, Dr. Nguyen`). Whisper does not label speakers (no diarization).

**How fast is it?**
With the default model, transcription runs at roughly 4–8× real time on Apify: a 60-minute podcast takes about 10–15 minutes, plus the download. `tiny` is about 2× faster and `small` about 3× slower. Each row reports `processingSeconds` and `realtimeFactor`. Files are processed one after another, and the next file downloads while the current one is transcribed.

**Which formats work?**
Anything ffmpeg can decode: mp3, m4a/aac, wav, ogg/opus, flac, wma, aiff, amr, mp4, m4v, mov, webm, mkv, avi, mpeg, 3gp and more. Only the audio track of videos is used.

**Google Drive or Dropbox link does not work?**
Share the file as *Anyone with the link*. A private file returns a login page, which is reported as "The URL returned a web page, not a media file". Very large Google Drive files can need a direct link from another host.

**What happens with a 3-hour file?**
By default only the first 60 minutes are transcribed and billed (`truncated: true`). Raise `maxDurationMinutes` (up to 300) or set `longFileHandling: skip`.

**Is my audio stored?**
Media is downloaded to the run's temporary disk and deleted right after transcription. Only the transcripts are kept in your dataset and key-value store, under your normal Apify data retention.

### Use with AI agents / Apify MCP

- **Apify MCP server:** add the Actor to Claude Desktop, Cursor or VS Code with `https://mcp.apify.com?actors=gazidev/media-transcriber`. An agent can call it with `{"podcastFeedUrls":["https://feeds.example.com/show.xml"],"maxEpisodes":1}` and summarize the latest episode, or with `{"mediaUrls":["https://…/lecture.mp4"],"task":"translate"}` to get English text.
- **API:** `POST https://api.apify.com/v2/acts/gazidev~media-transcriber/run-sync-get-dataset-items?token=…` with the input JSON returns the transcript rows directly (for files up to a few minutes; use the async run API for long media).
- **Automation:** schedule a Task on your podcast feed with `maxEpisodes: 1` and send new transcripts to Google Sheets, Slack, Make, Zapier or n8n via webhooks. LLM-friendly fields: `text` for summaries, `segments` for timestamped chapters and quotes.

### More from the toolkit

- [RSS Feed Reader](https://apify.com/gazidev/rss-feed-reader): any RSS, Atom or JSON Feed to JSON, with only-new mode. Find new episodes before transcribing.
- [Document to JSON](https://apify.com/gazidev/document-invoice-to-json): PDFs, Word files and images (OCR) to structured text.
- [Website to Markdown](https://apify.com/gazidev/website-to-markdown): any URL or whole site to clean Markdown for LLMs.

Powered by [faster-whisper](https://github.com/SYSTRAN/faster-whisper) and OpenAI Whisper models (MIT licence). Not affiliated with OpenAI, YouTube, TikTok, Instagram or Spotify.

# Actor input Schema

## `mediaUrls` (type: `array`):

Direct links to audio or video files: mp3, m4a, wav, ogg, opus, flac, mp4, mov, webm, mkv and more. Podcast episode (enclosure) URLs, S3/CDN links, Dropbox and Google Drive share links (shared as 'Anyone with the link') and OneDrive links work. **YouTube, TikTok, Instagram, Spotify, Facebook, X, Vimeo and SoundCloud page links are rejected**: their terms of service forbid downloading. Only submit media you have the right to transcribe.

## `podcastFeedUrls` (type: `array`):

Podcast RSS or Atom feeds. The newest `Max episodes per feed` episodes (audio/video enclosures) are transcribed.

## `maxEpisodes` (type: `integer`):

How many of the newest episodes to take from each feed.

## `model` (type: `string`):

`base` (default): good accuracy for clear speech; a 60-minute podcast takes roughly 10–15 minutes. `tiny`: about 2× faster, for clean single-speaker English. `small`: most accurate (accents, noise, non-English), about 3× slower than base, billed with the `minute-transcribed-small` event.

## `language` (type: `string`):

`auto` detects the spoken language from the first 30 seconds. Or force a Whisper language code to skip detection and avoid mistakes on short or noisy clips: `en`, `es`, `de`, `fr`, `pt`, `it`, `nl`, `pl`, `tr`, `ru`, `uk`, `ar`, `hi`, `ja`, `ko`, `zh`, `id`, `vi`, `sv`… (99 languages).

## `task` (type: `string`):

`transcribe`: text in the spoken language. `translate`: Whisper translates the speech to English text and subtitles (same price).

## `wordTimestamps` (type: `boolean`):

Add a `words` list (start, end, word, probability) to every segment. Useful for karaoke-style captions, search and clip cutting. Adds about 10–20% processing time (same price).

## `initialPrompt` (type: `string`):

Optional text that helps Whisper spell names and jargon, e.g. `Apify, Crawlee, Kubernetes, Dr. Nguyen`.

## `vadFilter` (type: `boolean`):

Voice activity detection skips silent parts. Faster and fewer hallucinated words in pauses and music. Timestamps still match the original file.

## `maxDurationMinutes` (type: `integer`):

Longer files are cut at this length (or skipped, see below). You are billed only for the minutes actually transcribed.

## `longFileHandling` (type: `string`):

`truncate`: transcribe the first N minutes (`truncated: true`). `skip`: do not transcribe the file at all (free error row).

## `maxFileSizeMB` (type: `integer`):

Downloads larger than this are stopped (free error row). Video files are big: 1 hour of 720p MP4 is about 500–1500 MB.

## `saveFiles` (type: `boolean`):

Store the transcript files in the run's key-value store and add download links (`txtFileUrl`, `srtFileUrl`, `vttFileUrl`, `jsonFileUrl`) to each row.

## `includeSegments` (type: `boolean`):

Keep the timestamped `segments` array in each dataset row. Turn off for smaller rows (the JSON file still has them).

## `downloadTimeoutSecs` (type: `integer`):

Maximum time to download one file. Downloads are retried on network errors and HTTP 429/5xx.

## Actor input object example

```json
{
  "mediaUrls": [
    "https://archive.org/download/spc141_1503_librivox/spc141_spiderandfly_lcw_64kb.mp3"
  ],
  "podcastFeedUrls": [],
  "maxEpisodes": 3,
  "model": "base",
  "language": "auto",
  "task": "transcribe",
  "wordTimestamps": false,
  "vadFilter": true,
  "maxDurationMinutes": 60,
  "longFileHandling": "truncate",
  "maxFileSizeMB": 2000,
  "saveFiles": true,
  "includeSegments": true,
  "downloadTimeoutSecs": 900
}
```

# Actor output Schema

## `transcripts` (type: `string`):

No description

## `subtitles` (type: `string`):

No description

## `errors` (type: `string`):

No description

## `files` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mediaUrls": [
        "https://archive.org/download/spc141_1503_librivox/spc141_spiderandfly_lcw_64kb.mp3"
    ],
    "language": "auto"
};

// Run the Actor and wait for it to finish
const run = await client.actor("gazidev/media-transcriber").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mediaUrls": ["https://archive.org/download/spc141_1503_librivox/spc141_spiderandfly_lcw_64kb.mp3"],
    "language": "auto",
}

# Run the Actor and wait for it to finish
run = client.actor("gazidev/media-transcriber").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mediaUrls": [
    "https://archive.org/download/spc141_1503_librivox/spc141_spiderandfly_lcw_64kb.mp3"
  ],
  "language": "auto"
}' |
apify call gazidev/media-transcriber --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gazidev/media-transcriber"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/0UcJ9pfU3aUlsomDo/builds/ebrvtZl55W7IYT87G/openapi.json
