# Podcast & Audio Transcriber: MP3 and RSS to Text and SRT (`datagleaner/audio-transcriber`) Actor

Transcribe audio file URLs or whole podcast RSS feeds to text, SRT subtitles and timed segments with Whisper, no API key. $0.012 per audio minute, billed only for the minutes transcribed. Audio is deleted after the run.

- **URL**: https://apify.com/datagleaner/audio-transcriber.md
- **Developed by:** [Data Gleaner](https://apify.com/datagleaner) (community)
- **Categories:** AI, Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $15.00 / 1,000 audio 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.
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

## Podcast & Audio Transcriber: MP3 and RSS to Text, SRT and VTT

**Give it links to audio files or a podcast's RSS feed, get the transcript back as text, SRT and VTT subtitles and timed segments.** It runs the open Whisper speech model (faster-whisper, on CPU) inside the Actor: no API key, your audio is not sent to any third-party service, and the audio file is deleted as soon as it is transcribed. Only the transcript is kept, in your run's dataset.

**Price: $0.015 per audio minute** ($0.90 per hour of audio), no start fee. You are billed only for the minutes actually transcribed. Failed downloads, refused links and files with no speech are returned with the reason and **not charged**. The `small` model, more accurate on accents, noise and non-English speech, is $0.03 per audio minute.

### What does the Podcast & Audio Transcriber do?

- **Direct audio links:** MP3, M4A, WAV, OGG, FLAC and similar files that download without a login.
- **Podcast RSS feeds:** give the show's feed link and it transcribes the newest `episodesPerFeed` episodes (default 1), keeping the podcast title, episode title, publish date and episode id on every row.
- **Four outputs:** `text` (always), `srt` (SubRip) and `vtt` (WebVTT) subtitles, both on by default and also saved as downloadable files in the run's key-value store (links in `srtFileUrl` and `vttFileUrl`), and `segments` (start, end, text in seconds, optional).
- **Language:** detected automatically, or set it (`en`, `es`, `de`, `fr`, `ja` ...). The detected `language` and its probability are returned.
- **Cost caps:** `maxMinutesPerFile`, `maxFiles` and your own max total charge all stop the run from billing more than you chose. The Actor never transcribes minutes your charge limit cannot pay for.

### Typical uses

- Searchable archives and show notes for a podcast back catalogue.
- Subtitles (SRT, VTT) for audio you own or have the right to use.
- Feeding recordings of meetings, lectures or interviews you have the right to process into LLM and RAG pipelines.
- Monitoring a public podcast feed for mentions of a topic.

### Input

| Field | What it does |
|---|---|
| `urls` | Audio file links and/or podcast RSS feed links. Leave empty for a free built-in sample. |
| `model` | `base` (default), `small` (more accurate, $0.03 per minute) or `tiny` (fastest, base price). |
| `language` | `auto` (default) or a language code. |
| `episodesPerFeed` | Newest episodes taken from each feed, default 1. |
| `maxMinutesPerFile` | Only the first N minutes of each file are transcribed and billed, default 120. |
| `maxFiles` | Stop after this many audio files (feed episodes count), default 50. |
| `includeSrt` / `includeVtt` / `includeSegments` | Add `srt` / `vtt` / `segments` to each row. |
| `maxFileSizeMb` | Skip larger files, default 200. |
| `proxyConfiguration` | Optional Apify Proxy for hosts that refuse the download. Default is no proxy. |

```json
{"urls": [{"url": "https://example.com/feed.xml"}, {"url": "https://example.com/episode-12.mp3"}], "episodesPerFeed": 3, "model": "base", "maxMinutesPerFile": 60}
```

An empty input runs a built-in sample, **not charged**: a short sample recording hosted by Keencrest (a synthetic voice reading a test text). Its transcript is stored, so the sample returns at once without loading the model.

### Output example

```json
{
  "audioUrl": "https://cdn.example.com/ep12.mp3",
  "feedUrl": "https://example.com/feed.xml",
  "feedTitle": "Example Show",
  "episodeTitle": "Episode 12",
  "episodePublished": "2026-10-30T13:19:00",
  "language": "en",
  "languageProbability": 0.997,
  "audioMinutes": 31.4,
  "billedMinutes": 32,
  "truncated": false,
  "wordCount": 4210,
  "text": "Welcome back to the show ...",
  "srt": "1\n00:00:00,940 --> 00:00:04,420\nWelcome back to the show.\n",
  "srtFileUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/subtitles-<id>.srt",
  "vtt": "WEBVTT\n\n00:00:00.940 --> 00:00:04.420\nWelcome back to the show.\n",
  "vttFileUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/subtitles-<id>.vtt",
  "error": null,
  "failureReason": null
}
```

### Pricing with a worked example

Billing is per audio minute, rounded up per file (at least 1 minute per transcribed file).

- 10 episodes of 40 minutes with `base`: 400 minutes x $0.015 = **$6.00**.
- One 25-minute interview with `small`: 25 x $0.03 = **$0.75**.
- A feed with 3 episodes, `maxMinutesPerFile` 10: at most 30 minutes = **$0.45**.

Speed on a 4 GB run is roughly 8 to 15 times faster than real time with `base`, so a 40-minute episode takes a few minutes.

### What is not supported

- **YouTube, TikTok, Instagram, Facebook, X (Twitter) and Spotify links are refused** with a clear message and are not charged: those platforms' terms do not allow downloading their media. Use the show's own RSS feed or a direct audio file link.
- **Sites whose terms forbid this kind of automated downloading are refused too**, for example archive.org (its terms grant access for scholarship and research only), with `failureReason: unsupported_platform` and no charge.
- **robots.txt is respected** for the feed, the audio host and every redirect in between, using the identifying user agent `KeencrestBot`. A disallowed URL is returned with `failureReason: robots_disallowed`.
- Files needing a login, DRM-protected audio and web pages are returned with an error.
- Speech recognition is automatic and can make mistakes, especially with noise, heavy accents, music and names. Use `small` for harder audio.

### FAQ

**Is my audio stored?** No. It is downloaded to temporary storage of the run, transcribed and deleted straight away. Nothing but the transcript is saved, and it goes only to your run's dataset.

**Can I transcribe any podcast?** Public podcast feeds, yes, for the uses the show's licence and your local law allow. Transcripts of someone else's recordings may be protected by copyright and may contain personal data. You are responsible for having the right to process the audio and for any personal-data obligations that apply to you.

**What if my files are very long?** `maxMinutesPerFile` (up to 360) caps each file. Files over `maxFileSizeMb` are skipped without charge.

**Why was a file not charged?** It could not be downloaded, was refused (platform link, robots.txt), could not be decoded, or contained no speech. The row says why in `error` and `failureReason`.

# Actor input Schema

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

Direct links to audio files, or links to a podcast's RSS feed (then the newest episodes are transcribed, see 'Episodes per feed'). One per line. Leave empty to transcribe the first minute of one built-in public-domain sample.

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

base: fast and accurate enough for clear speech, about $0.015 per minute. small: more accurate on accents, noise and non-English speech, about 2x slower, billed at the higher small-model price. tiny: fastest, rough quality, base price.

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

Spoken language as a two-letter code (en, es, de, fr, ja, zh ...), or auto to detect it from the first 30 seconds.

## `episodesPerFeed` (type: `integer`):

For a podcast RSS feed: how many of the newest episodes to transcribe. Ignored for direct audio links.

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

Only the first N minutes of each file are transcribed and billed. A cost cap for very long episodes.

## `maxFiles` (type: `integer`):

Upper bound on how many audio files are transcribed in this run (episodes from feeds count too). Also a cost cap.

## `includeSrt` (type: `boolean`):

Add an `srt` field with the transcript as SubRip subtitles, plus a downloadable .srt file in the run's key-value store (link in `srtFileUrl`).

## `includeVtt` (type: `boolean`):

Add a `vtt` field with the transcript as WebVTT subtitles (for web video players), plus a downloadable .vtt file in the run's key-value store (link in `vttFileUrl`).

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

Add a `segments` array of {start, end, text} in seconds.

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

Larger files are skipped with an error and are not billed.

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

Optional. The default is no proxy. Enable Apify Proxy only if a host refuses the download (HTTP 403).

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://keencrest-guides.web.app/samples/sample.mp3"
    }
  ],
  "model": "base",
  "language": "auto",
  "episodesPerFeed": 1,
  "maxMinutesPerFile": 3,
  "maxFiles": 3,
  "includeSrt": true,
  "includeVtt": true,
  "includeSegments": false,
  "maxFileSizeMb": 200,
  "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": [
        {
            "url": "https://keencrest-guides.web.app/samples/sample.mp3"
        }
    ],
    "maxMinutesPerFile": 3,
    "maxFiles": 3,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("datagleaner/audio-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": [{ "url": "https://keencrest-guides.web.app/samples/sample.mp3" }],
    "maxMinutesPerFile": 3,
    "maxFiles": 3,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("datagleaner/audio-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": [
    {
      "url": "https://keencrest-guides.web.app/samples/sample.mp3"
    }
  ],
  "maxMinutesPerFile": 3,
  "maxFiles": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call datagleaner/audio-transcriber --silent --output-dataset

```

## MCP server setup

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