# Audio & Video to Text — Whisper Transcriber + SRT (`sumitr_mardy/audio-video-transcriber`) Actor

Transcribe audio and video files and podcast RSS feeds to text with Whisper: timestamps, SRT/VTT subtitles, 99 languages auto-detected. One flat row per file, never null. Billed per audio minute, only for files that had speech.

- **URL**: https://apify.com/sumitr_mardy/audio-video-transcriber.md
- **Developed by:** [Sumitr Mardy](https://apify.com/sumitr_mardy) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.50 / 1,000 audio minute (fast)s

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 to Text — Whisper Transcriber + SRT

Give it audio or video links, or a podcast RSS feed, and get back the transcript: punctuated text, timestamped segments, and SRT/VTT subtitles if you want them. Whisper detects the language (99 supported) or you set it. One flat row per file, every field always present, never `null`. Built to be called from pipelines, n8n/Make/Zapier flows and AI agents.

**$6 per 1,000 audio minutes (fast) or $12 (accurate), less on higher Apify plans. Files with no speech, failed downloads and broken files are free.**

### Why this one

- **Podcast feeds, not just files.** Paste an RSS feed URL and the newest episodes are transcribed, each row carrying the episode title, publish date and podcast name.
- **One row for every file.** A 404, a web page instead of a file or a file with no audio track still comes back as a row with `status: "failed"` and a machine-readable `subStatus`.
- **Pay for speech, per minute, nothing else.** Billed on audio minutes of files that produced a transcript. No platform usage on top.
- **Preview long recordings cheaply.** `maxMinutesPerFile` transcribes only the start of each file, and you pay only for that part.
- **Measured, not promised.** On Apify at the default 4 GB, a 5-minute NPR newscast transcribed in 22 s (fast), and the JFK inaugural clip came back word-perfect on both tiers.

### Input

| Field | Default | What it does |
|---|---|---|
| `urls` | — | Audio/video file links (mp3, m4a, wav, ogg, opus, flac, aac, mp4, mov, webm, mkv…), Google Drive/Dropbox share links, or podcast RSS/Atom feeds. Required. |
| `quality` | `fast` | `fast` = Whisper base. `accurate` = Whisper small: better with names, accents and noisy audio, about 2.5x slower. |
| `language` | auto | ISO code (`en`, `vi`, `es`, `ja`…). Set it for short clips to avoid misdetection. |
| `maxEpisodesPerFeed` | `3` | Newest episodes to transcribe per feed (max 50). |
| `maxMinutesPerFile` | `120` | Transcribe at most this many minutes from the start of each file (max 240). |
| `includeSegments` | `true` | `segments[]` with start/end seconds per phrase. |
| `includeSubtitles` | `false` | `srt` and `vtt` subtitle text. |
| `maxFileSizeMb` | `500` | Larger files fail as `too_large`, uncharged (max 1,000). |
| `downloadTimeoutSecs` | `180` | Total time for one download (max 600). |
| `proxyConfiguration` | off | Optional. 401/403/429 hosts are retried once through Apify's datacenter proxy anyway. |

```json
{
  "urls": ["https://feeds.npr.org/500005/podcast.xml"],
  "maxEpisodesPerFeed": 1,
  "includeSubtitles": true
}
```

### Output

One row per media file, in completion order. A real row (shortened):

```json
{
  "inputIndex": 0,
  "url": "https://feeds.npr.org/500005/podcast.xml",
  "mediaUrl": "https://…/npr.simplecastaudio.com/…/audio/1",
  "title": "2am ET, October 27 | The latest headlines from NPR",
  "feedTitle": "NPR News Now",
  "publishedAt": "Tue, 27 Oct 2026 06:10:16 +0000",
  "status": "ok",
  "subStatus": "complete",
  "error": "",
  "text": "This message comes from Google Workspace with Gemini. … This is NPR News Now. The latest headlines every hour…",
  "charCount": 4822, "wordCount": 766,
  "language": "en", "languageProbability": 0.999,
  "durationSeconds": 319.9, "transcribedSeconds": 319.9, "billedMinutes": 6, "truncated": false,
  "quality": "fast", "model": "base", "hasVideo": false,
  "segments": [{ "start": 0, "end": 3.18, "text": "This message comes from Google Workspace with Gemini." }],
  "srt": "1\n00:00:00,000 --> 00:00:03,180\nThis message comes from Google Workspace with Gemini.\n…",
  "vtt": "WEBVTT\n\n00:00:00.000 --> 00:00:03.180\nThis message comes from Google Workspace with Gemini.\n…",
  "fileSizeBytes": 5118361,
  "notes": [],
  "processingMs": 22368
}
```

Strings are `""` when absent, numbers `0`, arrays `[]`. No field is ever `null` or missing. All episodes of one feed share the feed's `inputIndex`.

#### Status

| `status` | `subStatus` | Charged |
|---|---|---|
| `ok` | `complete` | `billedMinutes` |
| `ok` | `truncated`: only the start was transcribed (`maxMinutesPerFile`, or your maximum cost per run); `notes` says how much | `billedMinutes` of the part transcribed |
| `no_speech` | `no_speech_detected`: music, silence, noise | free |
| `failed` | `http_404` (any `http_<code>`), `not_media` (a web page), `too_large`, `download_timeout`, `download_error`, `bad_feed`, `no_episodes`, `no_audio_track`, `corrupt_media`, `empty_audio`, `invalid_url`, `cost_limit_reached`, `free_work_limit`, `transcription_error` | free |

### Pricing

| Event | Price per audio minute | When |
|---|---|---|
| `audio-minute` | $0.006 (free plan), $0.0055 Bronze, $0.005 Silver, $0.0045 Gold | `quality: "fast"`, per minute of a transcribed file |
| `audio-minute-accurate` | $0.012 (free plan), $0.011 Bronze, $0.010 Silver, $0.009 Gold | `quality: "accurate"` |

Minutes are counted per file and rounded up: a 5 min 20 s file is 6 minutes, an 11-second clip is 1. The only other charge is a start fee of $0.0005 per GB of memory per run ($0.002 at the default 4 GB). No platform usage is added on top. A run never transcribes more minutes than your *maximum cost per run* allows; files it cannot start come back `cost_limit_reached`, uncharged.

### Fair use

Failed and no-speech files are free, so a run that spends its compute on files that fail stops starting new ones; the rest come back `free_work_limit`, uncharged, and can be resubmitted. Also: 240 minutes and 1 GB per file at most, datacenter proxy only.

### What it does not do (yet)

- **No YouTube, TikTok or Instagram page links.** Give the direct media file. Social video transcripts are planned as separate actors.
- **No speaker labels (diarization)** and no word-level timestamps, only phrase-level segments.
- **Accuracy follows Whisper.** English and Spanish were checked by hand (JFK clip word-perfect; a Spanish LibriVox recording detected as `es` at 0.96 and read cleanly). Other languages work but were not measured; use `accurate` and set `language` for anything that matters.
- **CPU, not GPU.** Fast tier runs at ~0.07–0.13x real time at 4 GB, accurate ~0.3x. A 2-hour podcast on `accurate` takes ~40 minutes; raise memory to 8 GB to halve it.

### Use it from AI agents (MCP)

This Actor is a tool on the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp), so Claude, Cursor, VS Code or any MCP client can call it to read what is said in a recording. Load only this tool: a short tool list keeps the agent from picking the wrong one.

**Recommended: hosted server, OAuth sign-in (nothing secret on disk).** Add to your MCP client config (`claude_desktop_config.json`, `.cursor/mcp.json`, …):

```json
{
  "mcpServers": {
    "transcriber": {
      "url": "https://mcp.apify.com?tools=sumitr_mardy/audio-video-transcriber"
    }
  }
}
```

**With an API token instead** (clients without OAuth, or unattended setups):

```json
{
  "mcpServers": {
    "transcriber": {
      "url": "https://mcp.apify.com?tools=sumitr_mardy/audio-video-transcriber",
      "headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
    }
  }
}
```

**Local server (stdio):**

```json
{
  "mcpServers": {
    "transcriber": {
      "command": "npx",
      "args": ["-y", "@apify/actors-mcp-server@latest", "--tools", "sumitr_mardy/audio-video-transcriber"],
      "env": { "APIFY_TOKEN": "YOUR_APIFY_TOKEN" }
    }
  }
}
```

The hosted server also gives the agent this Actor's output schema, so it knows every field before the first call. `apify mcp install <client>` writes the config for you if you use the Apify CLI. Get a token at [Apify Console → API & Integrations](https://console.apify.com/settings/integrations), and never commit it.

**Tips for agents:**

- *"Summarise this podcast"*: pass the RSS feed with `maxEpisodesPerFeed: 1`, read `text`, cite `title` and `publishedAt`.
- *"What was said at minute 3?"*: read `segments` and match `start`/`end`.
- For a long file, set `maxMinutesPerFile` to keep the run inside the MCP `call-actor` 45-second wait, or fetch results later with `get-dataset-items`.
- Check `status` first: `no_speech` (music, silence) is an answer, not an error.

### Use it from code

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("sumitr_mardy/audio-video-transcriber").call(run_input={
    "urls": ["https://feeds.npr.org/500005/podcast.xml"],
    "maxEpisodesPerFeed": 1,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["title"], row["status"], row["billedMinutes"], row["text"][:100])
```

```bash
curl -X POST "https://api.apify.com/v2/acts/sumitr_mardy~audio-video-transcriber/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://raw.githubusercontent.com/ggml-org/whisper.cpp/master/samples/jfk.wav"]}'
```

# Actor input Schema

## `urls` (type: `array`):

One per item: a direct link to an audio or video file (mp3, m4a, wav, ogg, opus, flac, aac, mp4, mov, webm, mkv…), a Google Drive or Dropbox share link, or a podcast RSS/Atom feed URL (its latest episodes are transcribed). Web pages and YouTube links are not supported: use the direct file link.

## `quality` (type: `string`):

fast = Whisper base: clear speech, podcasts, news. accurate = Whisper small: about 2.5x slower, gets proper nouns, accents and noisy audio right more often. Priced per audio minute.

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

ISO 639-1 code of the spoken language ("en", "vi", "es", "de", "ja"…). Leave empty to auto-detect per file; set it when you know it, to avoid misdetection on short clips.

## `maxEpisodesPerFeed` (type: `integer`):

For RSS/Atom feed URLs: how many of the newest episodes to transcribe.

## `maxMinutesPerFile` (type: `integer`):

Transcribe at most this many minutes of each file (from the start); the rest is skipped and not billed. Use a small value to preview long recordings cheaply.

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

Add segments\[]: each phrase with start and end time in seconds.

## `includeSubtitles` (type: `boolean`):

Add srt and vtt fields: ready-to-use subtitle files as text.

## `maxFileSizeMb` (type: `integer`):

Larger files fail as too_large, uncharged.

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

Total time allowed for one download. Slower hosts fail as download_timeout, uncharged.

## `proxyConfiguration` (type: `object`):

Optional proxy for downloads. Hosts answering 401/403/429 are retried once through the Apify datacenter proxy anyway. Residential is not supported.

## Actor input object example

```json
{
  "urls": [
    "https://raw.githubusercontent.com/ggml-org/whisper.cpp/master/samples/jfk.wav"
  ],
  "quality": "fast",
  "language": "",
  "maxEpisodesPerFeed": 3,
  "maxMinutesPerFile": 120,
  "includeSegments": true,
  "includeSubtitles": false,
  "maxFileSizeMb": 500,
  "downloadTimeoutSecs": 180,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `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 = {
    "urls": [
        "https://raw.githubusercontent.com/ggml-org/whisper.cpp/master/samples/jfk.wav"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sumitr_mardy/audio-video-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 = { "urls": ["https://raw.githubusercontent.com/ggml-org/whisper.cpp/master/samples/jfk.wav"] }

# Run the Actor and wait for it to finish
run = client.actor("sumitr_mardy/audio-video-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 '{
  "urls": [
    "https://raw.githubusercontent.com/ggml-org/whisper.cpp/master/samples/jfk.wav"
  ]
}' |
apify call sumitr_mardy/audio-video-transcriber --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sumitr_mardy/audio-video-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/8ZHuU1i3vjMXG5wdV/builds/cwXslyabTfkogINAs/openapi.json
