# Facebook Video & Reel Transcript Scraper — Text, SRT & VTT (`memo23/facebook-video-transcript-scraper`) Actor

Facebook video and Reel transcripts. Paste any facebook.com or fb.watch link and get full text, timestamped segments, word-level timings, SRT and VTT files, HD video and thumbnail URLs, plus post metadata. Whisper runs inside the Actor — no API key. 99+ languages. Billed per second.

- **URL**: https://apify.com/memo23/facebook-video-transcript-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Videos, Social media, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 second of media 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Facebook Video & Reel Transcript Scraper

<p align="center"><img src="https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/logo-facebook-video-transcript-scraper.png" width="140" alt="Facebook Video Transcript Scraper"></p>

**Paste any Facebook video, Reel or Watch link and get the words back.** Full transcript, timestamped segments, optional word-level timings, ready-to-save SRT and VTT subtitle files, the HD video URL, the thumbnail and the post's metadata. Whisper runs inside the Actor, so there is no API key to obtain and no proxy of your own to configure.

| Input you paste | What you get back |
|---|---|
| `facebook.com/reel/<id>` | one row: transcript, segments, SRT/VTT, video + thumbnail URL, metadata |
| `facebook.com/watch/?v=<id>` | same |
| `facebook.com/<page>/videos/<id>` | same |
| `fb.watch/<code>` | same |

> Billed **per second of audio**, not per rounded-up minute. A 20-second Reel is billed 20 seconds.

### How it works

<p align="center"><img src="https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-facebook-video-transcript-scraper.png" width="820" alt="How it works"></p>

1. **Read the post.** Every link is checked as a Facebook URL first — anything else is named and skipped rather than failing halfway through. The post is then read for its title, author, publish date, view count, thumbnail and the list of available video renditions.
2. **Pull the audio.** Only the audio track is downloaded; the video itself is never stored. Each attempt tries a direct connection first and falls back to the Actor's own residential pool where Facebook blocks datacenter IPs, so no proxy quota of yours is spent.
3. **Transcribe.** faster-whisper runs locally on the audio, VAD-filtered, and returns the language, the segments and — when you ask for them — per-word timings.
4. **Package.** Segments become SRT and VTT files, saved to the run's key-value store and linked from the row.

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `videoUrls` | array | — (required) | Facebook video, Reel or Watch URLs, one per line |
| `language` | string | auto-detect | ISO 639-1 code (`en`, `es`, `pt`, `de`, …) to force a language |
| `model` | string | `base` | `tiny` (fastest) · `base` (fast, accurate on clear speech) · `small` (most accurate) |
| `translateToEnglish` | boolean | `false` | Return an English translation instead of the original language |
| `wordTimestamps` | boolean | `false` | Add per-word start/end/confidence inside every segment |
| `maxMinutesPerItem` | integer | `120` | Per-video cap; longer videos are transcribed up to the cap |
| `cookies` | string (secret) | — | Netscape cookies.txt, only for private or age-gated posts |
| `proxyConfiguration` | object | none needed | The Actor brings its own pool; set this only to add a fallback |

#### Example input

```json
{
  "videoUrls": ["https://www.facebook.com/reel/636216875539019"],
  "model": "base",
  "wordTimestamps": true
}
```

### Output schema

One row per video. Real row from the run above, trimmed:

```jsonc
{
  "url": "https://www.facebook.com/reel/636216875539019",
  "title": "The viral spider video explained! 🤯",
  "uploader": "Steven Bartlett",
  "publishedAt": "2025-07-17",
  "viewCount": 3263423,
  "durationSeconds": 60.8,
  "transcribedSeconds": 60.8,
  "billedSeconds": 61,
  "language": "en",
  "languageProbability": 0.9962,
  "wordCount": 259,
  "text": "Have you ever seen that video of the ant in the pen? …",
  "segments": [
    { "start": 0.0, "end": 4.46, "text": "Have you ever seen that video of the ant in the pen?",
      "words": [ { "start": 0.0, "end": 0.26, "word": "Have", "probability": 0.84 } ] }
  ],
  "srt": "1\n00:00:00,000 --> 00:00:04,460\n…",
  "vtt": "WEBVTT\n\n00:00:00.000 --> 00:00:04.460\n…",
  "srtFileUrl": "https://api.apify.com/v2/key-value-stores/…/001-the-viral-spider.srt",
  "vttFileUrl": "https://api.apify.com/v2/key-value-stores/…/001-the-viral-spider.vtt",
  "videoUrl": "https://video.fsjj1-1.fna.fbcdn.net/o1/v/t2/f2/m366/…",
  "videoHeight": 1920,
  "thumbnailUrl": "https://scontent.fsjj1-1.fna.fbcdn.net/v/t15.5256-10/…",
  "error": null
}
```

#### Key output fields

| Field | Description |
|---|---|
| `text` | Full transcript as one string |
| `segments` | `[{ start, end, text }]`; each also carries `words` when `wordTimestamps` is on |
| `srt` / `vtt` | Subtitle strings, ready to save |
| `srtFileUrl` / `vttFileUrl` | Direct download links to the stored `.srt` / `.vtt` |
| `videoUrl` / `videoHeight` | Highest-resolution video link Facebook listed, and its pixel height |
| `thumbnailUrl` | Post thumbnail |
| `title`, `uploader`, `publishedAt`, `viewCount` | Post metadata |
| `durationSeconds` / `transcribedSeconds` | Full length vs. what was transcribed after the cap |
| `billedSeconds` | Seconds charged for this video |
| `language` / `languageProbability` | Detected language and confidence |
| `error` | `null` on success; failed videos keep the reason and are never charged |

### Pricing

| Event | When | Rate |
|---|---|---|
| Actor start | Once per run, per GB of run memory | $0.005 |
| Second of media transcribed | Per second of audio actually transcribed | $0.0008 |

$0.0008/second works out to **$0.048 per minute**. A 20-second Reel costs about $0.026 all-in at the default 2 GB. Failed and skipped videos are never charged, and `maxMinutesPerItem` plus the run's maximum-cost setting bound the spend.

### What makes this richer than the competition

| Capability | Typical Facebook transcript Actor | This Actor |
|---|---|---|
| Billing granularity | per video or per rounded-up minute | **per second of audio** |
| Word-level timings | sometimes, extra cost | included, one toggle |
| SRT + VTT files | text only, or SRT only | both, as strings **and** stored files |
| HD video URL | rarely | included, with pixel height |
| API key needed | usually yes | **no** — Whisper runs in the Actor |
| Proxy quota needed | usually yours | **no** — the Actor brings its own pool |
| Languages | varies | 99+, auto-detected |

### Notes & limitations

- **Private, friends-only and age-gated posts need cookies.** Public Reels and page videos work without them. Export a `cookies.txt` from a browser where the post opens normally and paste it into the `cookies` field.
- **`videoUrl` and `thumbnailUrl` are signed CDN links and expire within hours.** Download them during or shortly after the run; they are not durable storage.
- **Live videos have to finish first.** A stream that is still live or being processed cannot be transcribed; the row says so and nothing is charged. Retry once the recording is published.
- **Longer videos need more run memory.** Whisper decodes at roughly 2-3× realtime on the 2 GB default; for anything over about 20 minutes, raise the run's memory so it also gets more CPU.
- **The model is clamped to the memory it fits in.** `small` needs 2 GB; below that the Actor drops to a model that fits and says so in the log rather than being killed mid-decode.

### 🤖 For AI Agents & LLM Apps

- **Purpose:** Facebook video/Reel → transcript, subtitles and post metadata. One dataset row per input URL.
- **Minimal tested input:** `{"videoUrls": ["https://www.facebook.com/reel/636216875539019"]}`
- **Output fields (flat):** `url`, `inputUrl`, `platform`, `sourceType`, `title`, `uploader`, `publishedAt`, `viewCount`, `thumbnailUrl`, `videoUrl`, `videoHeight`, `durationSeconds`, `transcribedSeconds`, `billedSeconds`, `billedMinutes`, `language`, `languageProbability`, `task`, `model`, `engine`, `wordTimestamps`, `text`, `wordCount`, `segments`, `srt`, `vtt`, `srtFileUrl`, `vttFileUrl`, `error`.
- **Nested:** `segments[] = {start, end, text, words?}`; `words[] = {start, end, word, probability}`.
- **Billing:** `media-second-transcribed` × `billedSeconds`, $0.0008 each, plus `apify-actor-start` at $0.005 per GB of run memory. Bound spend with `maxMinutesPerItem` and the run's maximum cost.
- **Behaviours worth knowing:** non-Facebook URLs are skipped with a logged reason rather than failing the run; a video that cannot be fetched produces a row with `error` set and `text: null` and is not charged; the run stops cleanly and explains itself if it would otherwise hit its timeout.
- **For other platforms** (YouTube, TikTok, Instagram, X, podcasts, direct files) use `memo23/video-audio-transcriber`.

### ⚠️ Disclaimer

This Actor collects only data that is publicly accessible without logging in. It does not bypass authentication, and it does not collect private or personal data beyond what the post itself displays publicly. You are responsible for how you use the output, including compliance with Facebook's terms, applicable copyright, and data-protection law such as GDPR and CCPA. Transcripts are derived works of the source video — check the rights before republishing. Use for research, accessibility, subtitling and content analysis.

### SEO Keywords

facebook transcript, facebook video to text, facebook reel transcript, facebook video transcription, facebook subtitle generator, facebook srt, facebook vtt, facebook watch transcript, fb.watch transcript, facebook speech to text, facebook video captions, facebook reel to text, whisper facebook, facebook video downloader url, facebook video metadata, transcribe facebook video, facebook accessibility captions, facebook content analysis

# Actor input Schema

## `videoUrls` (type: `array`):

One or more Facebook links, one per line. Reels, Watch videos and page videos all work:

- `https://www.facebook.com/reel/636216875539019`
- `https://www.facebook.com/watch/?v=1234567890`
- `https://www.facebook.com/PageName/videos/1234567890`
- `https://fb.watch/AbCdEfGh/`

Private or friends-only posts need a `cookies.txt` — see the Cookies field below.

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

ISO 639-1 code of the spoken language (`en`, `es`, `pt`, `de`, …). Leave empty to auto-detect — detection is reliable on clear speech and costs nothing extra.

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

Accuracy against speed. `base` is the right default for most Reels; `small` is worth it for accents, background music or technical vocabulary; `tiny` is for bulk runs where speed matters more than the last few percent.

## `translateToEnglish` (type: `boolean`):

Return an English translation instead of the original language. Works from any of the 99+ supported source languages.

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

Add per-word start/end times and confidence inside every segment (`segments[].words`). Needed for karaoke-style captions, precise clip cutting and word-accurate search. Costs roughly 15-25% extra transcription time.

## `maxMinutesPerItem` (type: `integer`):

Safety cap on how much of each video is transcribed. Longer videos are transcribed up to the cap and the row says how much was covered. Keeps a stray 3-hour livestream replay from eating the run.

## `cookies` (type: `string`):

Contents of a Netscape `cookies.txt` exported from a browser where the post opens normally. Only needed for private, friends-only or age-gated videos — public Reels and page videos work without it.

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

Optional. This Actor downloads through its own residential pool, so Facebook works without you configuring anything and without spending your proxy quota. Turn on Apify Proxy here only if you want it as an extra fallback, or paste your own proxy URLs to use those exclusively.

## Actor input object example

```json
{
  "videoUrls": [
    "https://www.facebook.com/reel/636216875539019"
  ],
  "model": "base",
  "translateToEnglish": false,
  "wordTimestamps": false,
  "maxMinutesPerItem": 120,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Full text, timestamped segments with optional per-word timings, detected language, and the post's title, author, publish date and view count.

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

Ready-to-download SRT and VTT files for each video, stored in the run's key-value store.

# 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 = {
    "videoUrls": [
        "https://www.facebook.com/reel/636216875539019"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/facebook-video-transcript-scraper").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 = {
    "videoUrls": ["https://www.facebook.com/reel/636216875539019"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/facebook-video-transcript-scraper").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 '{
  "videoUrls": [
    "https://www.facebook.com/reel/636216875539019"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call memo23/facebook-video-transcript-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/facebook-video-transcript-scraper"
        }
    }
}

```

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/w0EDCQvS3edo1dz4H/builds/UqoUsPk9Z3Qyc45Kb/openapi.json
