# Speech to Text: Audio & Video Transcription with SRT Subtitles (`jumblemog/speech-to-text`) Actor

Transcribe audio and video files, podcast feeds and Google Drive or Dropbox links to text with NVIDIA Parakeet, one of the most accurate open speech models. Get sentence and word timestamps plus SRT and VTT subtitles. 25 European languages.

- **URL**: https://apify.com/jumblemog/speech-to-text.md
- **Developed by:** [Jumble Mog](https://apify.com/jumblemog) (community)
- **Categories:** AI, Videos, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

## Speech to Text: Audio & Video Transcription with SRT Subtitles

Turn audio and video files, podcast episodes and Google Drive or Dropbox links into accurate text, with a timestamp on every sentence and word, plus ready-to-use **SRT and WebVTT subtitle files**. Transcription runs inside the Actor on [NVIDIA Parakeet TDT 0.6B v3](https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3), one of the most accurate open speech recognition models, so there's no API key to bring and your audio isn't sent to a third-party AI service.

### What you get

- **Accurate transcripts with punctuation and capitalization.** Parakeet TDT 0.6B v3 averages a 6.32% word error rate on the [Hugging Face Open ASR Leaderboard](https://huggingface.co/spaces/hf-audio/open_asr_leaderboard), lower than OpenAI Whisper large-v3's 7.44% there.
- **Timestamps for every sentence and, if you want, every word**, for searchable transcripts, clipping, highlights and karaoke-style captions.
- **SRT and WebVTT subtitles** with captions sized for readability (two lines of up to 42 characters by default; set 32 for vertical video).
- **Podcast feeds and Apple Podcasts links**: give a show's RSS feed or Apple Podcasts page and get its newest episodes transcribed.
- **Google Drive and Dropbox share links** work as they are, and you can upload files straight from your computer.
- **Fair billing**: you pay per minute of audio transcribed. Links that fail, files that can't be decoded and recordings with no speech are reported in the results and never charged.
- **25 European languages**, detected automatically: Bulgarian, Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, German, Greek, Hungarian, Italian, Latvian, Lithuanian, Maltese, Polish, Portuguese, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish and Ukrainian.

### Sample output

Input: the 36-second trailer of NASA's *Houston We Have a Podcast* (public domain), which is also the Actor's example input.

```json
{
  "url": "https://traffic.megaphone.fm/NATIONALAERONAUTICSANDSPACEADMINISTRATION8123271079.mp3",
  "title": "NATIONALAERONAUTICSANDSPACEADMINISTRATION8123271079.mp3",
  "status": "ok",
  "language": "en",
  "languageName": "English",
  "durationSeconds": 36.1,
  "speechSeconds": 30.53,
  "billedMinutes": 1,
  "wordCount": 94,
  "text": "Hey there, NASA Superfans. If you're fascinated by the idea of humans traveling through space and curious about how all that works, I think you'll love Houston We Have a Podcast. The official podcast of the NASA Johnson Space Center in Houston, Texas. We have a podcast. I'm Gary Jordan, I host the show. ...",
  "segments": [
    {"start": 1.08, "end": 2.6, "text": "Hey there, NASA Superfans."},
    {"start": 2.76, "end": 10.6, "text": "If you're fascinated by the idea of humans traveling through space and curious about how all that works, I think you'll love Houston We Have a Podcast."},
    {"start": 10.68, "end": 14.28, "text": "The official podcast of the NASA Johnson Space Center in Houston, Texas."}
  ],
  "files": {
    "txt": "https://api.apify.com/v2/key-value-stores/<store>/records/001-NATIONALAERONAUTICSANDSPACEADMINISTRATION8123271079.txt",
    "srt": "https://api.apify.com/v2/key-value-stores/<store>/records/001-NATIONALAERONAUTICSANDSPACEADMINISTRATION8123271079.srt",
    "vtt": "https://api.apify.com/v2/key-value-stores/<store>/records/001-NATIONALAERONAUTICSANDSPACEADMINISTRATION8123271079.vtt"
  },
  "model": "nvidia/parakeet-tdt-0.6b-v3"
}
```

The SRT file from the same run:

```
1
00:00:01,080 --> 00:00:02,760
Hey there, NASA Superfans.

2
00:00:02,760 --> 00:00:06,840
If you're fascinated by the idea of humans
traveling through space and curious about

3
00:00:06,840 --> 00:00:10,680
how all that works, I think you'll
love Houston We Have a Podcast.
```

### How to use it

1. Paste links to audio or video files, upload files, or add podcast RSS feeds.
2. Pick the files you want saved (text, SRT, VTT, full JSON) and click **Start**.
3. Read the transcripts in the **Output** tab, download them as JSON, CSV or Excel, or open the subtitle files from the links in each result.

You can also run it through the [Apify API](https://docs.apify.com/api/v2), on a schedule (for example, to transcribe each new episode of a podcast every morning), or from Make, n8n, Zapier and other integrations.

### Input

| Field | What it does |
| --- | --- |
| `mediaUrls` | Direct links to audio or video files (MP3, M4A, WAV, FLAC, OGG, OPUS, MP4, MOV, MKV, WEBM and more), Google Drive or Dropbox share links, Apple Podcasts show links, or podcast pages that link to an RSS feed. |
| `files` | Files uploaded from your computer or picked from an Apify key-value store. |
| `podcastFeeds` | Podcast RSS or Atom feeds. |
| `episodesPerFeed` | How many of the newest episodes to transcribe per feed (default 1). |
| `maxFiles` | Stop after this many files, so cost stays predictable (default 100). |
| `maxMinutesPerFile` | Only the first this-many minutes of each file are transcribed and billed (default 240). |
| `outputFormats` | Files to save: `txt`, `srt`, `vtt`, `json` (default text, SRT and VTT). |
| `includeSegments` | Add sentences with timestamps to each result (default on). |
| `includeWords` | Add every word with timestamps to each result (default off). |
| `maxCharsPerLine` | Subtitle line length (default 42). |

Example input for a podcast:

```json
{
  "podcastFeeds": ["https://www.nasa.gov/feeds/podcasts/curious-universe"],
  "episodesPerFeed": 3,
  "outputFormats": ["txt", "srt"]
}
```

### Output

Each file becomes one item in the dataset with the transcript (`text`), sentences with timestamps (`segments`), optional word timestamps (`words`), detected `language`, `durationSeconds`, `billedMinutes`, `wordCount` and download links to the saved files (`files`). Items for podcast episodes also carry `feedTitle` and `publishedAt`. A file that couldn't be processed gets `status: "failed"` and an `error` explaining why; a file without speech gets `status: "no-speech"`. Neither is billed.

The transcript files are saved in the run's key-value store as `001-<name>.txt`, `.srt`, `.vtt` and `.json`.

### Pricing

You pay per started minute of audio transcribed, at the price shown on this page. A 36-second clip is billed as 1 minute; a 60-minute podcast as 60 minutes. Failed links, undecodable files and silent recordings cost nothing, and `maxMinutesPerFile` and `maxFiles` cap what a run can cost. If you set a maximum cost per run in Apify, the Actor transcribes only as much as fits and stops.

### Speed

With the default 8 GB of memory, the Actor transcribes about 10 minutes of audio per minute (a one-hour episode takes about 6 minutes). Choose 16 GB or more for faster runs; the price per audio minute stays the same.

### Supported links and limits

- Files up to 4 GB and 12 hours (set `maxMinutesPerFile` up to 720).
- Links to YouTube, TikTok, Instagram, Facebook, X, Vimeo, SoundCloud and Spotify aren't supported, because those platforms' terms don't allow downloading. Use a direct link to a file you have the right to use.
- Languages outside the 25 listed above aren't supported yet; the model will produce poor text for them.

### For AI agents and developers

This Actor works with the [Apify MCP server](https://mcp.apify.com), so agents can call it as a tool: pass `mediaUrls` (or `podcastFeeds`) and read the dataset. Every item has the same fields, documented in the dataset schema, and `status` tells you whether a file succeeded. For long transcripts, read the `.txt` or `.json` file from `files` instead of loading the whole dataset item.

### Privacy

Your files are downloaded into the run, transcribed there and deleted when the file is done. Transcripts are stored only in your own Apify storage. No audio or text is sent to an outside AI service.

### Credits and licenses

- Speech model: [NVIDIA Parakeet TDT 0.6B v3](https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3), licensed CC BY 4.0, run as the int8 ONNX export by [istupakov](https://huggingface.co/istupakov/parakeet-tdt-0.6b-v3-onnx) (CC BY 4.0) for CPU speed.
- Voice activity detection: [Silero VAD](https://github.com/snakers4/silero-vad) (MIT), via [onnx-asr](https://github.com/istupakov/onnx-asr) (MIT).
- Audio decoding: [FFmpeg](https://ffmpeg.org).

# Actor input Schema

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

Direct links to audio or video files (MP3, M4A, WAV, FLAC, OGG, OPUS, MP4, MOV, MKV, WEBM and more), Google Drive or Dropbox share links, Apple Podcasts show links, or podcast pages that link to an RSS feed. Links to YouTube, TikTok, Instagram, Facebook, X, Vimeo, SoundCloud and Spotify aren't supported, because their terms don't allow downloading.

## `files` (type: `array`):

Upload audio or video files from your computer, or pick files you already stored in an Apify key-value store.

## `podcastFeeds` (type: `array`):

Podcast RSS or Atom feed URLs. The newest episodes are transcribed (see 'Episodes per feed').

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

How many of the newest episodes to transcribe from each podcast feed or Apple Podcasts link.

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

Stop after transcribing this many files, so the cost of a run stays predictable.

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

Only the first this-many minutes of each file are transcribed and billed. Longer files are marked as truncated.

## `outputFormats` (type: `array`):

Transcript files to save in the run's key-value store, with download links in each result: plain text, SRT subtitles, WebVTT subtitles and full JSON (segments and every word with timestamps).

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

Add the transcript split into sentences, each with a start and end time in seconds, to every result.

## `includeWords` (type: `boolean`):

Add every word with its start and end time to every result. Useful for clipping, highlighting and karaoke-style captions. Makes the dataset larger.

## `maxCharsPerLine` (type: `integer`):

Maximum characters per subtitle line in the SRT and VTT files (two lines per caption). 42 is the common broadcast standard; use about 32 for vertical videos.

## Actor input object example

```json
{
  "mediaUrls": [
    "https://traffic.megaphone.fm/NATIONALAERONAUTICSANDSPACEADMINISTRATION8123271079.mp3"
  ],
  "episodesPerFeed": 1,
  "maxFiles": 100,
  "maxMinutesPerFile": 240,
  "outputFormats": [
    "txt",
    "srt",
    "vtt"
  ],
  "includeSegments": true,
  "includeWords": false,
  "maxCharsPerLine": 42
}
```

# Actor output Schema

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

One item per file: transcript text, sentences with timestamps, language, duration and links to the saved files.

## `sentences` (type: `string`):

Every sentence as its own row with start and end times in seconds.

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

Saved TXT, SRT subtitle, WebVTT subtitle and JSON files, one set per transcribed file.

# 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://traffic.megaphone.fm/NATIONALAERONAUTICSANDSPACEADMINISTRATION8123271079.mp3"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jumblemog/speech-to-text").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://traffic.megaphone.fm/NATIONALAERONAUTICSANDSPACEADMINISTRATION8123271079.mp3"] }

# Run the Actor and wait for it to finish
run = client.actor("jumblemog/speech-to-text").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://traffic.megaphone.fm/NATIONALAERONAUTICSANDSPACEADMINISTRATION8123271079.mp3"
  ]
}' |
apify call jumblemog/speech-to-text --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jumblemog/speech-to-text"
        }
    }
}
```

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/ZX3YKzAkWUzZZbz9Z/builds/OGezzRpxuDcf4ZDQZ/openapi.json
