# PySceneDetect: finding scene cuts in video with Python and OpenCV

> PySceneDetect is a Python library and command line tool that locates scene cuts and transitions in a video and can hand the resulting scene list to ffmpeg or mkvmerge to split the file. It is aimed at engineers who need cut detection inside a pipeline rather than inside an editor.

**Breakthrough/PySceneDetect** — :movie_camera: Python and OpenCV-based scene cut/transition detection program & library.

- Repository: https://github.com/Breakthrough/PySceneDetect
- Website: https://www.scenedetect.com/
- Stars: 5,212 · Forks: 523
- Language: Python
- License: BSD-3-Clause
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/breakthrough-pyscenedetect

## What PySceneDetect actually computes, and who needs it

PySceneDetect answers one question about a video file: which frames begin a new scene. The output is a scene list, a sequence of start and end positions, each carrying both a timecode and a frame number. That is the whole product surface. Everything else in the repository exists to make that list easier to consume.

The audience is narrow and fairly technical. If you are building a media pipeline and need to know where the cuts are before you do something else with the footage, this is the kind of tool you want. The Python API returns ordinary objects you can iterate over, and the CLI writes the same information to stdout or a file. The README frames it as a detection program and library, and the topic list on the repository is consistent with that: analysis, image-processing, opencv, video-processing.

It is not an editor plugin. The search questions people ask about scene edit detection in Premiere Pro, DaVinci Resolve and Final Cut Pro are about features built into those applications, and the PySceneDetect repository documents no integration with any of them. If your job is to press a button inside an NLE, this project is the wrong shape. If your job is to run detection over ten thousand files on a build machine, it is the right one.

## How detection works: detectors, a SceneManager, and a scene list

The architecture visible in the README is a small pipeline. You open a video, create a SceneManager, register one or more detectors on it, run detection, then read the scene list back out. Detectors are pluggable: the README names ContentDetector, AdaptiveDetector and ThresholdDetector.

ContentDetector is the default choice and takes a threshold parameter, shown as 27.0 in the README's advanced example. AdaptiveDetector is described as a two-pass variant that handles fast camera movement better, which tells you the trade-off it is making: more work, fewer false cuts from a panning shot. ThresholdDetector is for fade out and fade in events, so it is looking for a different signal than a hard cut. Choosing between them is the main tuning decision in a real deployment, and the README does not claim one is universally correct.

The scene list is the contract between detection and everything downstream. Each scene is a pair, and the README's iteration example calls get_timecode() and frame_num on both ends. Timecode and frame number are both exposed because they serve different consumers: ffmpeg wants times, frame-accurate work wants frame numbers. That is a small design decision that saves you from doing arithmetic on your own.

Splitting is deliberately separate. split_video_ffmpeg takes the video path and the scene list and shells out to ffmpeg, with mkvmerge also supported. Detection itself does not require either tool. Only the split step does, and the README states that requirement plainly.

## Installing PySceneDetect and running a first split

The quick install path is a single pip command. The package name on PyPI is scenedetect, and the README shows the upgrade flag alongside it.

```bash
pip install scenedetect --upgrade
```

That gives you the CLI and the Python API, but not the external splitters. The README states that ffmpeg or mkvmerge is required for video splitting support, so install one of them before you try to cut anything.

The fastest first use is the CLI against a local file. This splits the input on each fast cut and writes the pieces out.

```bash
scenedetect -i video.mp4 split-video
```

If you only want still frames from each detected scene rather than the video pieces, the README gives a second command for that.

```bash
scenedetect -i video.mp4 save-images
```

A useful sanity check before processing a long file is to skip the opening seconds, which the README demonstrates with the time subcommand and a duration string.

```bash
scenedetect -i video.mp4 time -s 10s
```

If you would rather not install anything, the README points at an official container image that bundles the dependencies, including ffmpeg and mkvmerge. The mount pattern is the part worth copying exactly, because input and output paths have to be expressed inside the container.

```bash
docker run --rm -v "$(pwd):/files" ghcr.io/breakthrough/pyscenedetect -i /files/video.mp4 split-video -o /files
```

The Python entry point is a single function call. The README's first example returns a list of scenes for the file.

```python
from scenedetect import detect, ContentDetector

scene_list = detect("my_video.mp4", ContentDetector())
```

When you need control over the threshold and want the split in the same script, the README's longer example builds the pipeline by hand. Note that it registers the detector on a SceneManager rather than passing it to detect().

```python
from scenedetect import open_video, SceneManager, split_video_ffmpeg
from scenedetect.detectors import ContentDetector


def split_video_into_scenes(video_path, threshold=27.0):
    video = open_video(video_path)
    scene_manager = SceneManager()
    scene_manager.add_detector(ContentDetector(threshold=threshold))
    scene_manager.detect_scenes(video, show_progress=True)
    scene_list = scene_manager.get_scene_list()
    split_video_ffmpeg(video_path, scene_list, show_progress=True)
```

What you should see after a successful run is a printed progress display during detection, then either new video files or extracted images next to your input, depending on the subcommand. If the split step produces nothing, check that ffmpeg or mkvmerge is on PATH before you look at the detector settings.

## Where the threshold model breaks down

The honest limitation is that this is a threshold-based method over frame content, not a learned model of what a shot is. ContentDetector compares frames against a numeric threshold, and the README's own example exposes 27.0 as a value you are expected to change. That means accuracy is a tuning problem on your material, not a property of the tool.

The failure modes follow from that. Fast camera movement is called out explicitly by the README, which is why AdaptiveDetector exists as a two-pass alternative. If your footage is full of handheld motion, whip pans or drone shots, the default detector will report cuts that are not cuts, and you will spend time on threshold tuning rather than on your pipeline. Fades and dissolves are a different signal again, handled by ThresholdDetector rather than by the content detector, so a project that needs both hard cuts and gradual transitions has to think about which detector is registered and when.

There is also a hard dependency boundary that is easy to forget during design. Detection runs in Python with OpenCV. Splitting does not: it shells out to ffmpeg or mkvmerge. The README states this requirement, and it means a container or machine that can detect cuts may still be unable to produce them. If your deployment target is a minimal image, that is a real constraint, not a footnote.

Finally, the project is not a shot classifier. It tells you where scenes begin and end. It does not tell you what is in them, and nothing in the README suggests otherwise.

## PySceneDetect compared with ffmpeg scene detection and TransNetV2

The most common comparison is against ffmpeg's own scene detection. ffmpeg can emit scene change metadata through its filters, and it is already installed in most media pipelines, so the obvious question is why add a Python dependency. The difference is in what you get back. ffmpeg's approach is a filter that marks frames as it decodes, and extracting a structured scene list with start and end pairs takes additional work. PySceneDetect's output is that structured list directly, with timecodes and frame numbers per scene, and it is produced by a library you can call from Python with a detector object you can swap. The trade-off runs the other way too: ffmpeg is one fewer moving part, and if you are already running an ffmpeg filter graph, adding scenedetect means adding Python, OpenCV and a second pass over the file.

TransNetV2 is the other comparison people search for, and the difference in approach is fundamental. TransNetV2 is a trained neural network for shot boundary detection. PySceneDetect's detectors are threshold-based heuristics over frame content. That means PySceneDetect has no model weights to download, no GPU requirement, and behaviour you can reason about from a single numeric parameter. It also means it has no learned notion of a shot boundary, which is exactly what a neural approach buys you on difficult material. If your footage defeats threshold tuning and you can afford a model in the loop, the neural route is the one to evaluate. If you want a dependency-light step that runs on CPU and whose output you can explain to someone, PySceneDetect is the simpler choice.

The repository does publish benchmark results at scenedetect.com/benchmarks, with a benchmark report in the repository covering datasets and methodology. That is the place to look for accuracy and speed numbers rather than taking any general claim on faith.

## Packaging, licence and the cost of upgrading

The licence is BSD-3-Clause, stated in the README and in pyproject.toml. That is a permissive licence, and the repository also ships a THIRD-PARTY.md for the dependencies, which is where you should look before shipping a product, since OpenCV and the media backends carry their own terms. None of that is legal advice; read the files.

The packaging deserves attention because it is not a single artifact. The repository root pyproject.toml builds scenedetect-core, described as the detection pipeline with minimal dependencies and no CLI. The Dockerfile makes the split explicit: it copies packaging/variants/pyproject-scenedetect-headless.toml over the root pyproject.toml before installing, and the comment says the root file builds the core library only. So the package you install from PyPI as scenedetect and the package the repository root builds are not the same thing, which matters if you are vendoring or building from source.

OpenCV is a deliberate omission from the declared dependencies. The pyproject comment states that OpenCV is required at runtime but intentionally not declared, because any of the four opencv-python variants satisfies the library for development installs. That is a reasonable choice for a library and an easy source of confusion for a user, since a missing OpenCV shows up at import or first decode rather than at install time.

The Python floor is 3.10, and the classifiers list 3.10 through 3.13. The Dockerfile pins python:3.11.11-slim as its base and installs ffmpeg and mkvtoolnix from Debian packages, then installs the headless variant with the pyav and moviepy extras. It also pins pillow==12.3.0 with a comment citing a moviepy cap and CVEs fixed in 12.3.0, to be dropped once moviepy lifts the cap. That is the kind of detail that tells you upgrade cost is not zero: the container image is carrying a version pin that exists because of an upstream constraint.

On maintenance, the last push to the repository was on 2026-09-21, and the most recent release listed is v0.7.1 from 2026-07-22. The release cadence visible in the recent releases is roughly one notable version per year, with v0.6.7 in 2025, v0.7 in May 2026 and v0.7.1 in July 2026. Plan upgrades around that rhythm rather than expecting continuous churn.

## Conclusion

Adopt PySceneDetect if you need cut detection as a library call inside an existing Python pipeline, or as a CLI step you can run from a container image. Do not adopt it if you need shot boundaries on highly stylised material and cannot tune a threshold, or if you need an editor-integrated workflow, since the repository documents no Resolve, Premiere or Final Cut integration. Before committing, verify two things on your own footage: which detector (ContentDetector, AdaptiveDetector or ThresholdDetector) matches your cut style, and whether ffmpeg or mkvmerge is actually present on the machine, because the split step fails without them.

## FAQ

### How do I install PySceneDetect?

Install it from PyPI with pip install scenedetect --upgrade. The README notes that ffmpeg or mkvmerge is still required for video splitting support, and that Windows MSI and portable ZIP builds are available from the download page.

### How do I use PySceneDetect to split a video into scenes?

The CLI does it in one command: scenedetect -i video.mp4 split-video. In Python, detect the scene list first and then pass it to split_video_ffmpeg along with the video path.

### How do I use PySceneDetect from Python?

The README's shortest example is from scenedetect import detect, ContentDetector followed by detect("my_video.mp4", ContentDetector()), which returns a list of scenes. For control over the detector and threshold, build a SceneManager, add a detector to it, run detect_scenes, and read the scene list back.

### How does PySceneDetect compare with other scene detection tools?

PySceneDetect's detectors are threshold-based heuristics over frame content, while a neural approach such as TransNetV2 uses a trained model for shot boundary detection. The repository publishes benchmark results at scenedetect.com/benchmarks, with a benchmark report covering datasets and methodology.

## Sources

- [Breakthrough/PySceneDetect on GitHub](https://github.com/Breakthrough/PySceneDetect)
- [License: BSD-3-Clause](https://github.com/Breakthrough/PySceneDetect/blob/main/LICENSE)
- [Project website](https://www.scenedetect.com/)
- [README](https://github.com/Breakthrough/PySceneDetect/blob/main/README.md)
- [Releases](https://github.com/Breakthrough/PySceneDetect/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/breakthrough-pyscenedetect
