# Video Scene Detection & Chapter Generator: Cuts, Keyframes (`bossless/video-scene-chapters`) Actor

Find every scene cut in a video file: a keyframe per scene, a contact sheet, scenes as CSV, and chapters ready to paste into a YouTube description, optionally AI-titled from the narration. MP4, MOV, WebM, Google Drive or Dropbox links. Pay per video minute.

- **URL**: https://apify.com/bossless/video-scene-chapters.md
- **Developed by:** [Alexander Daskalov](https://apify.com/bossless) (community)
- **Categories:** Videos, AI, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $12.00 / 1,000 video minute analyseds

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

## Video Scene Detection & Chapter Generator

**Find every scene cut in a video and turn it into YouTube chapters, keyframes and a contact sheet.** Paste links to your video files (MP4, MOV, WebM, MKV…, or Google Drive and Dropbox file links) and get, for every video:

- ✂️ **Scene cuts**: the start, end and length of every shot, frame-accurate, as JSON and CSV.
- 🖼️ **Keyframes**: one JPEG per scene, taken from inside the scene (never the first frame of a fade).
- 🗂️ **Contact sheet**: one image with up to 48 keyframes in a grid, each with its timecode, to see the whole video at a glance.
- 📑 **YouTube chapters**, ready to paste into a description (`0:00 Introduction`…), checked against YouTube's rules.
- 🧠 **Optional AI chapters**: the AI listens to the narration, starts each chapter where the topic changes (always at a real cut or pause) and writes a title and a one-sentence summary.

No API key, no software to install. Works for vlogs, tutorials, lectures, webinars, product demos, trailers and stock footage.

### What can you do with it?

- **YouTube chapters in seconds:** paste the `youtubeChapters` text into your description; viewers jump straight to the part they want and Google can show the chapters as key moments.
- **Video editing and logging:** a shot list with timecodes and a picture of every shot, before you open the editor.
- **Thumbnails and previews:** pick a thumbnail from the keyframes, or use the contact sheet as a storyboard.
- **Video libraries and AI pipelines:** split long videos into scenes for search, tagging or feeding scene by scene to other tools.
- **Quality checks:** count shots, measure cut pace and find too-short scenes.

### What videos does it accept?

| Input | Example | Supported |
|---|---|---|
| Direct video file link | `https://example.com/videos/demo.mp4` | ✅ mp4, mov, webm, mkv, avi, m4v… (H.264, HEVC, VP9, AV1…) |
| Cloud storage file URL | a public S3, Google Cloud Storage or CDN link | ✅ if it opens without logging in |
| Google Drive file | `https://drive.google.com/file/d/…/view` | ✅ shared as "Anyone with the link" |
| Dropbox file | `https://www.dropbox.com/scl/fi/…?dl=0` | ✅ |
| YouTube, TikTok, Vimeo or Instagram page links | `https://www.youtube.com/watch?v=…` | ❌ link the video file itself |

Up to 200 videos per run, each up to 240 minutes and up to 4K at 60 fps (set **Max minutes per video** to analyse only the start). A video that can't finish before the run's timeout is analysed from the start for as long as fits, and the record says so; raise the timeout for long videos. With the default 2 GB of memory a file can be up to about 3.9 GB; each extra 1 GB of memory adds 2 GB.

### How much does it cost?

Pay per minute of video. No monthly fee.

| Event | Price (FREE/BRONZE) | Lower on paid plans |
|---|---|---|
| Video minute analysed (cuts, keyframes, contact sheet, visual chapters, CSV) | **$0.013** / started minute | down to $0.012 |
| AI chapter minute (only with AI chapters) | **$0.01** / started minute | down to $0.008 |
| Actor start | $0.00005 / run | — |

A 10-minute video costs **$0.13**, or **$0.23** with AI chapters. Minutes are counted per video and rounded up, so a 61-second video is 2 minutes. Bigger or faster videos take longer to decode, so above 1080p at 30 fps a minute counts double (1080p at 60 fps, 4K at 30 fps) or four times (4K at 60 fps); larger videos aren't supported. Nothing is charged for a link that isn't a usable video, and if the AI can't make chapters for a video it gets visual chapters and the AI minutes aren't charged.

**Cap your spend:** set a **maximum cost per run**. When the budget can't pay for a whole video, only the minutes it covers are analysed, and the record says so.

**Free plan:** the AI runs on paid infrastructure, so free-plan runs include AI chapters for 10 minutes of video per run; the other videos get visual chapters. Scene detection, keyframes and visual chapters work on every plan.

### How to make chapters for a video

1. Click **Try for free**. The example input analyses a 55-second sample video with 5 shots.
2. Paste your own video links into **Video links**, one per line.
3. Choose **Chapters**: *Visual* (at the strongest cuts, titled Chapter 1, 2, 3) or *AI* (titled from the narration). Set the **Shortest chapter** and **Most chapters per video**.
4. Run, then open the **Videos** view, the contact sheets, or download JSON, CSV or Excel.

#### Input example

```json
{
  "videoUrls": ["https://example.com/videos/product-demo.mp4"],
  "chapters": "ai",
  "minChapterSeconds": 30,
  "maxChapters": 8,
  "chapterLanguage": "en"
}
```

| Field | Default | What it does |
|---|---|---|
| `videoUrls` | — | Links to video files, one per line, up to 200. |
| `chapters` | `visual` | `visual` or `ai`. |
| `minChapterSeconds` | 60 | Chapters are at least this long (YouTube needs 10 or more). |
| `maxChapters` | 12 | The most chapters per video. |
| `chapterLanguage` | the video's own | Language of AI chapter titles and summaries. |
| `sensitivity` | 3 | How different a frame must be to count as a cut: lower finds more cuts, higher only hard cuts. |
| `minSceneSeconds` | 0.6 | Cuts closer together are merged, so flashes and fast montages don't become dozens of tiny scenes. |
| `maxKeyframes` | 60 | One JPEG per scene; with more scenes, they're picked evenly from start to end. |
| `contactSheet` | true | One JPEG with up to 48 keyframes and their timecodes. |
| `maxMinutesPerVideo` | 120 | Only the first this many minutes are analysed and charged. |

### Output

One record per video. Real output from the example input (shortened):

```json
{
  "videoUrl": "https://api.apify.com/v2/key-value-stores/T5HtoeQYut1ufwkKC/records/short-cuts.mp4",
  "fileName": "short-cuts.mp4",
  "durationSeconds": 55,
  "analysedSeconds": 55,
  "width": 640,
  "height": 360,
  "fps": 25,
  "codec": "h264",
  "sceneCount": 5,
  "scenes": [
    {"index": 0, "start": 0, "end": 11, "duration": 11, "startTimecode": "0:00",
     "keyframeUrl": "https://api.apify.com/v2/key-value-stores/nV3tGrmsc3umTlfgs/records/short-cuts-64709a62aa-scene-0000.jpg"},
    {"index": 1, "start": 11, "end": 22, "duration": 11, "startTimecode": "0:11",
     "keyframeUrl": "https://api.apify.com/v2/key-value-stores/nV3tGrmsc3umTlfgs/records/short-cuts-64709a62aa-scene-0001.jpg"}
  ],
  "chapterMode": "visual",
  "chapters": [
    {"index": 0, "start": 0, "end": 11, "startTimecode": "0:00", "title": "Chapter 1", "summary": null},
    {"index": 1, "start": 11, "end": 22, "startTimecode": "0:11", "title": "Chapter 2", "summary": null}
  ],
  "youtubeChapters": "0:00 Chapter 1\n0:11 Chapter 2\n0:22 Chapter 3\n0:33 Chapter 4\n0:44 Chapter 5",
  "youtubeChaptersValid": true,
  "contactSheetUrl": "https://api.apify.com/v2/key-value-stores/nV3tGrmsc3umTlfgs/records/short-cuts-64709a62aa-contact-sheet.jpg",
  "scenesCsvUrl": "https://api.apify.com/v2/key-value-stores/nV3tGrmsc3umTlfgs/records/short-cuts-64709a62aa-scenes.csv",
  "billedMinutes": 1,
  "aiMinutes": 0,
  "warnings": [],
  "processingMs": 2328,
  "error": null
}
```

With AI chapters, a 2-minute narrated lecture got:

```json
{
  "chapterMode": "ai",
  "chapters": [
    {"index": 0, "start": 0, "end": 30.6, "startTimecode": "0:00", "title": "What is a scene cut", "summary": "…"},
    {"index": 1, "start": 30.6, "end": 57.72, "startTimecode": "0:30", "title": "Why chapters matter", "summary": "…"},
    {"index": 2, "start": 57.72, "end": 81.64, "startTimecode": "0:57", "title": "The contact sheet", "summary": "…"},
    {"index": 3, "start": 81.64, "end": 107.04, "startTimecode": "1:21", "title": "Pricing and limits", "summary": "…"}
  ],
  "youtubeChapters": "0:00 What is a scene cut\n0:30 Why chapters matter\n0:57 The contact sheet\n1:21 Pricing and limits",
  "youtubeChaptersValid": true,
  "aiMinutes": 2
}
```

Times are seconds from the start of the video. A video that can't be used gets a record with only `videoUrl` and `error` (for example "video not available (HTTP 404): is the link public?") and isn't charged. Keyframes, contact sheets and CSV files are in the run's key-value store.

### How accurate is it?

- **Cuts:** on a 1080p test video with a hard cut every 15 seconds, all 15 cuts were found at the exact frame, with no extra cuts. Videos larger than 1080p are analysed without their B-frames to halve the cost; there a cut can show up to 3 frames late.
- **AI chapters:** on a narrated lecture with 4 topics, every chapter started within 0.1 seconds of the real topic change, in each of 4 runs.
- **Hard cuts are its strength.** Slow fades and dissolves may be found a little late or not at all; lower the **Cut sensitivity** to catch more of them.

### How fast is it?

Measured on Apify with the default 2 GB memory: a 4-minute 1080p video took about 85 seconds, a 2-minute 720p lecture with AI chapters 15 to 50 seconds (mostly waiting for the AI), and the 55-second example 2 seconds. Most of the time goes into decoding the video, so lower resolutions are faster. Videos in one run are processed one after another.

### What it doesn't do

- Download from YouTube, TikTok, Vimeo, Instagram or other page links: link the video file.
- Cut the video into clips or export an edit list (EDL/XML) for an editor: use the scene times or the CSV.
- Recognise objects, faces or text in the frames.

### Use it with AI agents (MCP)

```
https://mcp.apify.com?tools=bossless/video-scene-chapters
```

Ask your assistant to "make YouTube chapters for this video", and it runs this actor and reads back the chapters.

### Use the API from code

```bash
curl -X POST "https://api.apify.com/v2/acts/bossless~video-scene-chapters/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"videoUrls": ["https://example.com/videos/demo.mp4"], "chapters": "visual"}'
```

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("bossless/video-scene-chapters").call(run_input={
    "videoUrls": ["https://example.com/videos/demo.mp4"],
    "chapters": "ai",
})
for video in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(video["youtubeChapters"])
```

### FAQ

**Do I need an OpenAI or other API key?** No. Scene detection and AI chapters are included in the price.

**Why are my YouTube chapters marked as not valid?** YouTube shows chapters only when the first starts at 0:00, there are at least 3, and each is 10 seconds or longer. A short video or one with few cuts may not have room for 3; lower **Shortest chapter** or use AI chapters.

**Which languages work for AI chapters?** Most major languages. Titles and summaries are written in the language spoken in the video, or in the one you choose.

**What happens with a private or broken link?** It's skipped with a clear message and not charged. So is a download that takes longer than 15 minutes. A run where every link was wrong still succeeds, with a message saying what to check.

**Is my data stored or used for training?** Videos are downloaded only for the run and deleted when it ends. Results are saved in your own Apify storage. For AI chapters, the video's audio goes to an AI model on Google Cloud (Vertex AI). Google's terms say it won't use this data to train or fine-tune its models; it may cache requests for up to 24 hours and log them for abuse monitoring.

**Is this an official YouTube tool?** No. This is an independent tool and is not affiliated with or endorsed by YouTube, Google or any video platform.

### Credits

Scene detection uses [PySceneDetect](https://www.scenedetect.com) (BSD 3-Clause) and FFmpeg.

### Related tools

- [Speaker Diarization & Transcription](https://apify.com/bossless/speaker-diarization): who spoke when for any audio or video file, with SRT and VTT subtitles.
- [Call Recording Transcription & AI Call Analysis](https://apify.com/bossless/call-transcription-analyzer): transcripts, summaries and QA scorecards for call recordings.

# Actor input Schema

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

Links to video files (MP4, MOV, WebM, MKV, AVI...): direct files from your website or cloud storage, or Google Drive / Dropbox file links shared as 'Anyone with the link'. One per line, up to 200 per run. YouTube, TikTok or Vimeo page links don't work: link the video file itself.

## `chapters` (type: `string`):

Visual chapters start at the strongest scene cuts and are titled Chapter 1, 2, 3. AI chapters listen to the narration, start where the topic changes (always at a cut or a pause) and get real titles and one-sentence summaries; they cost extra per minute (see Pricing) and need an audio track.

## `minChapterSeconds` (type: `integer`):

Chapters are at least this long. YouTube needs 10 seconds or more.

## `maxChapters` (type: `integer`):

The most chapters a video is split into.

## `chapterLanguage` (type: `string`):

The language of AI chapter titles and summaries. By default, the language spoken in the video.

## `sensitivity` (type: `number`):

How much a frame must differ from the frames around it to count as a cut (PySceneDetect AdaptiveDetector threshold). Lower finds more cuts, higher only hard cuts.

## `minSceneSeconds` (type: `number`):

Cuts closer together than this are merged, so flashes and fast montages don't become dozens of tiny scenes.

## `maxKeyframes` (type: `integer`):

One JPEG per scene, from the middle of the scene. With more scenes than this, they are picked evenly from start to end.

## `contactSheet` (type: `boolean`):

One JPEG showing up to 48 keyframes in a grid with their timecodes.

## `maxMinutesPerVideo` (type: `integer`):

Only the first this many minutes of each video are analysed and charged.

## Actor input object example

```json
{
  "videoUrls": [
    "https://api.apify.com/v2/key-value-stores/T5HtoeQYut1ufwkKC/records/short-cuts.mp4"
  ],
  "chapters": "visual",
  "minChapterSeconds": 60,
  "maxChapters": 12,
  "chapterLanguage": "",
  "sensitivity": 3,
  "minSceneSeconds": 0.6,
  "maxKeyframes": 60,
  "contactSheet": true,
  "maxMinutesPerVideo": 120
}
```

# Actor output Schema

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

No description

## `files` (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 = {
    "videoUrls": [
        "https://api.apify.com/v2/key-value-stores/T5HtoeQYut1ufwkKC/records/short-cuts.mp4"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bossless/video-scene-chapters").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://api.apify.com/v2/key-value-stores/T5HtoeQYut1ufwkKC/records/short-cuts.mp4"] }

# Run the Actor and wait for it to finish
run = client.actor("bossless/video-scene-chapters").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://api.apify.com/v2/key-value-stores/T5HtoeQYut1ufwkKC/records/short-cuts.mp4"
  ]
}' |
apify call bossless/video-scene-chapters --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bossless/video-scene-chapters"
        }
    }
}
```

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/Pr91wk8uZ6sTBxI1T/builds/Nz8PsVg2NYfaCzmVI/openapi.json
