PySceneDetect 0.6.2 documentation

# PySceneDetect Documentation

This documentation covers the PySceneDetect command-line interface (the scenedetect command) and Python API (the scenedetect module). The latest release of PySceneDetect can be installed via pip install scenedetect[opencv]. Windows builds and source releases can be found at scenedetect.com/download. Note that PySceneDetect requires ffmpeg or mkvmerge for video splitting support.

Note

If you see any errors in the documentation, or want to suggest improvements, feel free to raise an issue on the PySceneDetect issue tracker.

The latest source code for PySceneDetect can be found on Github at github.com/Breakthrough/PySceneDetect.

## Table of Contents

### `scenedetect` Command Reference 🖥️

#### `scenedetect` 🎬 Command

PySceneDetect is a scene cut/transition detection program. PySceneDetect takes an input video, runs detection on it, and uses the resulting scene information to generate output. The syntax for using PySceneDetect is:

> `scenedetect -i video.mp4 [detector] [commands]`

For [detector] use detect-adaptive or detect-content to find fast cuts, and detect-threshold for fades in/out. If [detector] is not specified, a default detector will be used.

#### Examples

Split video wherever a new scene is detected:

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

Save scene list in CSV format with images at the start, middle, and end of each scene:

> `scenedetect -i video.mp4 list-scenes save-images`

Skip the first 10 seconds of the input video:

> `scenedetect -i video.mp4 time --start 10s detect-content`

Show summary of all options and commands:

> `scenedetect --help`

Global options (e.g. `-i/--input`, `-c/--config`) must be specified before any commands and their options. The order of commands is not strict, but each command must only be specified once.

#### Options

-i VIDEO, --input VIDEO

  [REQUIRED] Input video file. Image sequences and URLs are supported.

-o DIR, --output DIR

  Output directory for created files. If unset, working directory will be used. May be overriden by command options.

-c FILE, --config FILE

  Path to config file. See config file reference for details.

-s CSV, --stats CSV

  Stats file (.csv) to write frame metrics. Existing files will be overwritten. Used for tuning detection parameters and data analysis.

-f FPS, --framerate FPS

  Override framerate with value as frames/sec.

-m TIMECODE, --min-scene-len TIMECODE

  Minimum length of any scene. TIMECODE can be specified as number of frames (`-m=10`), time in seconds followed by “s” (`-m=2.5s`), or timecode (`-m=00:02:53.633`).

  Default: `0.6s`

--drop-short-scenes

  Drop scenes shorter than `-m/--min-scene-len`, instead of combining with neighbors.

--merge-last-scene

  Merge last scene with previous if shorter than `-m/--min-scene-len`.

-b BACKEND, --backend BACKEND

  Backend to use for video input. Backend options can be set using a config file (`-c/--config`). [available: opencv, pyav, moviepy]

  Default: `opencv`

-d N, --downscale N

  Integer factor to downscale video by before processing. If unset, value is selected based on resolution. Set `-d=1` to disable downscaling.

-fs N, --frame-skip N

  Skip N frames during processing. Reduces processing speed at expense of accuracy. `-fs=1` skips every other frame processing 50% of the video, `-fs=2` processes 33% of the video frames, `-fs=3` processes 25%, etc…

  Default: `0`

-v LEVEL, --verbosity LEVEL

  Amount of information to show. LEVEL must be one of: debug, info, warning, error, none. Overrides `-q/--quiet`.

  Default: `info`

-l FILE, --logfile FILE

  Save debug log to FILE. Appends to existing file if present.

-q, --quiet

  Suppress output to terminal/stdout. Equivalent to setting `--verbosity=none`.

##### `help`, `version`, and `about`

`scenedetect --help` will print PySceneDetect options, commands, and examples. You can also specify:

> - `scenedetect [command] --help` to show options and examples for a command or detector

> - `scenedetect help` command to print full reference of all options, commands, and examples

`scenedetect version` prints the version of PySceneDetect that is installed, as well as system dependencies.

`scenedetect about` prints PySceneDetect copyright, licensing, and redistribution information. This includes a list of all third-party software components that PySceneDetect uses or interacts with, as well as a reference to the license and copyright information for each component.

#### Detectors

##### `detect-adaptive`

Perform adaptive detection algorithm on input video.

Two-pass algorithm that first calculates frame scores with detect-content, and then applies a rolling average when processing the result. This can help mitigate false detections in situations such as camera movement.

###### Examples

> `scenedetect -i video.mp4 detect-adaptive`

> `scenedetect -i video.mp4 detect-adaptive --threshold 3.2`

###### Options

-t VAL, --threshold VAL

  Threshold (float) that frame score must exceed to trigger a cut. Refers to “adaptive_ratio” in stats file.

  Default: `3.0`

-c VAL, --min-content-val VAL

  Minimum threshold (float) that “content_val” must exceed to trigger a cut.

  Default: `15.0`

-d VAL, --min-delta-hsv VAL

  [DEPRECATED] Use `-c/--min-content-val` instead.

  Default: `15.0`

-f VAL, --frame-window VAL

  Size of window to detect deviations from mean. Represents how many frames before/after the current one to use for mean.

  Default: `2`

-w, --weights

  Weights of 4 components (“delta_hue”, “delta_sat”, “delta_lum”, “delta_edges”) used to calculate “content_val”.

  Default: `1.000, 1.000, 1.000, 0.000`

-l, --luma-only

  Only use luma (brightness) channel. Useful for greyscale videos. Equivalent to “–weights 0 0 1 0”.

-k N, --kernel-size N

  Size of kernel for expanding detected edges. Must be odd number >= 3. If unset, size is estimated using video resolution.

  Default: `auto`

-m TIMECODE, --min-scene-len TIMECODE

  Minimum length of any scene. Overrides global option `-m/--min-scene-len`. TIMECODE can be specified in frames (`-m=100`), in seconds with s suffix (`-m=3.5s`), or timecode (`-m=00:01:52.778`).

##### `detect-content`

Perform content detection algorithm on input video.

For each frame, a score from 0 to 255.0 is calculated which represents the difference in content between the current and previous frame (higher = more different). A cut is generated when a frame score exceeds `-t/--threshold`. Frame scores are saved under the “content_val” column in a statsfile.

Scores are calculated from several components which are also recorded in the statsfile:

> - delta_hue: Difference between pixel hue values of adjacent frames.

> - delta_sat: Difference between pixel saturation values of adjacent frames.

> - delta_lum: Difference between pixel luma (brightness) values of adjacent frames.

> - delta_edges: Difference between calculated edges of adjacent frames. Typically larger than other components, so threshold may need to be increased to compensate.

Once calculated, these components are multiplied by the specified `-w/--weights` to calculate the final frame score (“content_val”). Weights are set as a set of 4 numbers in the form (delta_hue, delta_sat, delta_lum, delta_edges). For example, “–weights 1.0 0.5 1.0 0.2 –threshold 32” is a good starting point for trying edge detection. The final sum is normalized by the weight of all components, so they need not equal 100%. Edge detection is disabled by default to improve performance.

###### Examples

> `scenedetect -i video.mp4 detect-content`

> `scenedetect -i video.mp4 detect-content --threshold 27.5`

###### Options

-t VAL, --threshold VAL

  Threshold (float) that frame score must exceed to trigger a cut. Refers to “content_val” in stats file.

  Default: `27.0`

-w HUE SAT LUM EDGE, --weights HUE SAT LUM EDGE

  Weights of 4 components used to calculate frame score from (delta_hue, delta_sat, delta_lum, delta_edges).

  Default: `1.000, 1.000, 1.000, 0.000`

-l, --luma-only

  Only use luma (brightness) channel. Useful for greyscale videos. Equivalent to setting “-w 0 0 1 0”.

-k N, --kernel-size N

  Size of kernel for expanding detected edges. Must be odd integer greater than or equal to 3. If unset, kernel size is estimated using video resolution.

  Default: `auto`

-m TIMECODE, --min-scene-len TIMECODE

  Minimum length of any scene. Overrides global option `-m/--min-scene-len`. TIMECODE can be specified in frames (`-m=100`), in seconds with s suffix (`-m=3.5s`), or timecode (`-m=00:01:52.778`).

##### `detect-threshold`

Perform threshold detection algorithm on input video.

Detects fade-in and fade-out events using average pixel values. Resulting cuts are placed between adjacent fade-out and fade-in events.

###### Examples

> `scenedetect -i video.mp4 detect-threshold`

> `scenedetect -i video.mp4 detect-threshold --threshold 15`

###### Options

-t VAL, --threshold VAL

  Threshold (integer) that frame score must exceed to start a new scene. Refers to “delta_rgb” in stats file.

  Default: `12.0`

-f PERCENT, --fade-bias PERCENT

  Percent (%) from -100 to 100 of timecode skew of cut placement. -100 indicates the start frame, +100 indicates the end frame, and 0 is the middle of both.

  Default: `0`

-l, --add-last-scene

  If set and video ends after a fade-out event, generate a final cut at the last fade-out position.

  Default: `True`

-m TIMECODE, --min-scene-len TIMECODE

  Minimum length of any scene. Overrides global option `-m/--min-scene-len`. TIMECODE can be specified in frames (`-m=100`), in seconds with s suffix (`-m=3.5s`), or timecode (`-m=00:01:52.778`).

#### Commands

##### `export-html`

Export scene list to HTML file. Requires save-images unless –no-images is specified.

###### Options

-f NAME, --filename NAME

  Filename format to use for the scene list HTML file. You can use the $VIDEO_NAME macro in the file name. Note that you may have to wrap the format name using single quotes.

  Default: `$VIDEO_NAME-Scenes.html`

--no-images

  Export the scene list including or excluding the saved images.

-w pixels, --image-width pixels

  Width in pixels of the images in the resulting HTML table.

-h pixels, --image-height pixels

  Height in pixels of the images in the resulting HTML table.

##### `list-scenes`

Create scene list CSV file (will be named $VIDEO_NAME-Scenes.csv by default).

###### Options

-o DIR, --output DIR

  Output directory to save videos to. Overrides global option `-o/--output` if set.

-f NAME, --filename NAME

  Filename format to use for the scene list CSV file. You can use the $VIDEO_NAME macro in the file name. Note that you may have to wrap the name using single quotes or use escape characters (e.g. `-f=$VIDEO_NAME-Scenes.csv`).

  Default: `$VIDEO_NAME-Scenes.csv`

-n, --no-output-file

  Only print scene list.

-q, --quiet

  Suppress printing scene list.

-s, --skip-cuts

  Skip cutting list as first row in the CSV file. Set for RFC 4180 compliant output.

##### `load-scenes`

Load scenes from CSV instead of detecting. Can be used with CSV generated by list-scenes. Scenes are loaded using the specified column as cut locations (frame number or timecode).

###### Examples

> `scenedetect -i video.mp4 load-scenes -i scenes.csv`

> `scenedetect -i video.mp4 load-scenes -i scenes.csv --start-col-name "Start Timecode"`

###### Options

-i FILE, --input FILE

  Scene list to read cut information from.

-c STRING, --start-col-name STRING

  Name of column used to mark scene cuts.

  Default: `"Start Frame"`

##### `save-images`

Create images for each detected scene.

Images can be resized

###### Examples

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

> `scenedetect -i video.mp4 save-images --width 1024`

> `scenedetect -i video.mp4 save-images --filename \$SCENE_NUMBER-img\$IMAGE_NUMBER`

###### Options

-o DIR, --output DIR

  Output directory for images. Overrides global option `-o/--output` if set.

-f NAME, --filename NAME

  Filename format without extension to use when saving images. You can use the $VIDEO_NAME, $SCENE_NUMBER, $IMAGE_NUMBER, and $FRAME_NUMBER macros in the file name. You may have to use escape characters (e.g. `-f=$SCENE_NUMBER-Image-$IMAGE_NUMBER`) or single quotes.

  Default: `$VIDEO_NAME-Scene-$SCENE_NUMBER-$IMAGE_NUMBER`

-n N, --num-images N

  Number of images to generate per scene. Will always include start/end frame, unless `-n=1`, in which case the image will be the frame at the mid-point of the scene.

  Default: `3`

-j, --jpeg

  Set output format to JPEG (default).

-w, --webp

  Set output format to WebP

-q Q, --quality Q

  JPEG/WebP encoding quality, from 0-100 (higher indicates better quality). For WebP, 100 indicates lossless.

  Default: `JPEG: 95, WebP: 100`

-p, --png

  Set output format to PNG.

-c C, --compression C

  PNG compression rate, from 0-9. Higher values produce smaller files but result in longer compression time. This setting does not affect image quality, only file size.

  Default: `3`

-m N, --frame-margin N

  Number of frames to ignore at beginning/end of scenes when saving images. Controls temporal padding on scene boundaries.

  Default: `3`

-s S, --scale S

  Factor to scale images by. Ignored if `-W/--width` or `-H/--height` is set.

-H H, --height H

  Height (pixels) of images.

-W W, --width W

  Width (pixels) of images.

##### `split-video`

Split input video using ffmpeg or mkvmerge.

###### Examples

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

> `scenedetect -i video.mp4 split-video --copy`

> `scenedetect -i video.mp4 split-video --filename \$VIDEO_NAME-Clip-\$SCENE_NUMBER`

###### Options

-o DIR, --output DIR

  Output directory to save videos to. Overrides global option `-o/--output` if set.

-f NAME, --filename NAME

  File name format to use when saving videos, with or without extension. You can use $VIDEO_NAME and $SCENE_NUMBER macros in the filename. You may have to wrap the format in single quotes or use escape characters to avoid variable expansion (e.g. `-f=$VIDEO_NAME-Scene-$SCENE_NUMBER`).

  Default: `$VIDEO_NAME-Scene-$SCENE_NUMBER`

-q, --quiet

  Hide output from external video splitting tool.

-c, --copy

  Copy instead of re-encode. Faster but less precise. Equivalent to: `--args="-map 0 -c:v copy -c:a copy"`

-hq, --high-quality

  Encode video with higher quality, overrides -f option if present. Equivalent to: `--rate-factor=17` `--preset=slow`

-crf RATE, --rate-factor RATE

  Video encoding quality (x264 constant rate factor), from 0-100, where lower is higher quality (larger output). 0 indicates lossless.

  Default: `22`

-p LEVEL, --preset LEVEL

  Video compression quality (x264 preset). Can be one of: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow. Faster modes take less time but output may be larger.

  Default: `veryfast`

-a ARGS, --args ARGS

  Override codec arguments passed to FFmpeg when splitting scenes. Use double quotes (”) around arguments. Must specify at least audio/video codec.

  Default: `"-map 0 -c:v libx264 -preset veryfast -crf 22 -c:a aac"`

-m, --mkvmerge

  Split video using mkvmerge. Faster than re-encoding, but less precise. If set, options other than `-f/--filename`, `-q/--quiet` and `-o/--output` will be ignored. Note that mkvmerge automatically appends the $SCENE_NUMBER suffix.

##### `time`

Set start/end/duration of input video.

Values can be specified as frames (NNNN), seconds (NNNN.NNs), or timecode (HH:MM:SS.nnn). For example, to process only the first minute of a video:

> `scenedetect -i video.mp4 time --end 00:01:00`

> `scenedetect -i video.mp4 time --duration 60s`

Note that –end and –duration are mutually exclusive (i.e. only one of the two can be set). Lastly, the following is an example using absolute frame numbers to process frames 0 through 1000:

> `scenedetect -i video.mp4 time --start 0 --end 1000`

###### Options

-s TIMECODE, --start TIMECODE

  Time in video to start detection. TIMECODE can be specified as number of frames (`--start=100` for frame 100), time in seconds followed by “s” (`--start=100s` for 100 seconds), or timecode (`--start=00:01:40` for 1m40s).

-d TIMECODE, --duration TIMECODE

  Maximum time in video to process. TIMECODE format is the same as other arguments. Mutually exclusive with `-e/--end`.

-e TIMECODE, --end TIMECODE

  Time in video to end detecting scenes. TIMECODE format is the same as other arguments. Mutually exclusive with `-d/--duration`

#### Configuration File

A configuration file path can be specified using the `-c`/`--config` argument. PySceneDetect also looks for a config file named scenedetect.cfg in one of the following locations:

> - Windows:

>     - `C:/Users/%USERNAME%/AppData/Local/PySceneDetect/scenedetect.cfg`

> - Linux:

>     - `~/.config/PySceneDetect/scenedetect.cfg`

>     - `$XDG_CONFIG_HOME/scenedetect.cfg`

> - Mac:

>     - `~/Library/Preferences/PySceneDetect/scenedetect.cfg`

Run scenedetect –help to see the exact path on your system which will be used. Values set on the command line take precedence over those set in the config file. Most (but not all) command line parameters can be set using a configuration file, and some options can only be set using a config file. See the Template below for a `scenedetect.cfg` file that describes each option, which you can use to create a new config file. Note that lines starting with a `#` are comments and will be ignored.

The syntax of a configuration file is:

    [command]
    option_a = value
    #comment
    option_b = 1

##### Example

    [global]
    default-detector = detect-content
    min-scene-len = 0.8s

    [detect-content]
    threshold = 26

    [split-video]
    # Use higher quality encoding
    preset = slow
    rate-factor = 17
    filename = $VIDEO_NAME-Clip-$SCENE_NUMBER

    [save-images]
    format = jpeg
    quality = 80
    num-images = 3

##### Template

This template shows every possible configuration option and default values. It can be used as a `scenedetect.cfg` file. You can also download it from Github.

    #
    # This file contains every possible PySceneDetect config option.
    #
    # A config file path can be specified via the -c/--config option, or by
    # creating a `scenedetect.cfg` file the following location:
    #
    #   Windows: C:/Users/%USERNAME%/AppData/Local/PySceneDetect/scenedetect.cfg
    #
    #   Linux:   ~/.config/PySceneDetect/scenedetect.cfg
    #            $XDG_CONFIG_HOME/scenedetect.cfg
    #
    #   Mac:     ~/Library/Preferences/PySceneDetect/scenedetect.cfg
    #
    # Run `scenedetect --help` to see the exact path on your system which will be
    # used (it will be listed under the help text for the -c/--config option).
    #

    #
    # GLOBAL OPTIONS
    #

    [global]
    # Output directory for written files. If unset, defaults to working directory.
    #output = /usr/tmp/scenedetect/

    # Default detector to use, must be one of: detect-adaptive, detect-content, detect-threshold.
    #default-detector = detect-adaptive

    # Video backend interface, must be one of: opencv, pyav.
    #backend = opencv

    # Downscale frame using a ratio of N. Set to 1 for no downscaling. If unset, applied
    # automatically based on input video resolution. Must be an integer value.
    #downscale = 1

    # Method to use for downscaling (nearest, linear, cubic, area, lanczos4).
    #downscale-method = linear

    # Minimum length of a given scene (shorter scenes will be merged).
    #min-scene-len = 0.6s

    # Merge last scene if it is shorter than min-scene-len (yes/no)
    #merge-last-scene = no

    # Drop scenes shorter than min-scene-len instead of merging (yes/no)
    #drop-short-scenes = no

    # Verbosity of console output (debug, info, warning, error, or none).
    # Set to none for the same behavior as specifying -q/--quiet.
    #verbosity = debug

    # Amount of frames to skip between performing scene detection. Not recommended.
    #frame-skip = 0

    #
    # DETECTOR OPTIONS
    #

    [detect-content]
    # Sensitivity threshold from 0 to 255. Lower values are more sensitive.
    #threshold = 27

    # Weight to place on each component when calculating frame score (the value
    # `threshold` is compared against). The components are in the order
    # (delta_hue, delta_sat, delta_lum, delta_edges). Description of components:
    #  - delta_hue:    Difference between hue values of adjacent frames
    #  - delta_sat:    Difference between saturation values of adjacent frames
    #  - delta_lum:    Difference between luma/brightness values of adjacent frames
    #  - delta_edges:  Difference between calculated edges of adjacent frames
    # The score of each frame ('content_val' in the statsfile) is calculated as
    # the weighted sum of all components.
    #weights = 1.0 1.0 1.0 0.0

    # Discard colour information and only use luminance (yes/no).
    # If yes, overrides weights with (0.0, 0.0, 1.0, 0.0).
    #luma-only = no

    # Size of kernel for expanding detected edges. Must be odd integer greater
    # than or equal to 3. If None, automatically set using video resolution.
    #kernel-size = -1

    # Minimum length of a given scene (overrides [global] option).
    #min-scene-len = 0.6s

    [detect-threshold]
    # Average pixel intensity from 0-255 at which a fade event is triggered.
    #threshold = 12

    # Percent from -100.0 to 100.0 of timecode skew for where cuts should be placed.
    # -100 indicates start frame, +100 indicates end frame, and 0 is the center.
    #fade-bias 0

    # Generate a scene from the end of the last fade out to the end of the video.
    #add-last-scene = yes

    # Discard colour information and only use luminance (yes/no).
    #luma-only = no

    # Minimum length of a given scene (overrides [global] option).
    #min-scene-len = 0.6s

    [detect-adaptive]
    # Frame score threshold, refers to the `adaptive_ratio` metric in stats file.
    #threshold = 3

    # Minimum threshold that `content_val` metric from detect-content must exceed.
    #min-content-val = 15

    # Window size (number of frames) before and after each frame to average together.
    #frame-window = 2

    # Minimum length of a given scene (overrides [global] option).
    #min-scene-len = 0.6s

    # The following parameters are the those used to calculate `content_val`.
    # See [detect-content] for detailed descriptions of these parameters.
    #weights = 1.0, 1.0, 1.0, 0.0
    #luma-only = no
    #kernel-size = -1

    #
    # COMMAND OPTIONS
    #

    [split-video]
    # Folder to output videos. Overrides [global] output option.
    #output = /usr/tmp/encoded

    # Filename template to use as output.
    #filename = $VIDEO_NAME-Scene-$SCENE_NUMBER

    # Suppress output from split tool.
    #quiet = no

    # Use higher bitrate for better output quality (y/n), equivalent to setting
    # rate-factor = 17 and preset = slow.
    #high-quality = no

    # Use codec copying instead of encoding. Significantly faster, but can result
    # in inaccurate splits due to keyframe positioning.
    #copy = no

    # Use mkvmerge for copying instead of encoding. Has the same drawbacks as copy = yes.
    #mkvmerge = no

    # x264 rate-factor, higher indicates lower quality / smaller filesize.
    # 0 = lossless, 17 = visually identical, 22 = default.
    #rate-factor = 22

    # One of the ffmpeg x264 presets (e.g. veryfast, fast, medium, slow, slower).
    #preset = veryfast

    # Arguments to specify to ffmpeg for encoding. Quotes are not required.
    #args = -map 0 -c:v libx264 -preset veryfast -crf 22 -c:a aac

    [save-images]
    # Folder to output videos. Overrides [global] output option.
    #output = /usr/tmp/images

    # Filename format of created images. Can use $VIDEO_NAME, $SCENE_NUMBER,
    # and $IMAGE_NUMBER in the name. Extension not required.
    #filename = $VIDEO_NAME-Scene-$SCENE_NUMBER-$IMAGE_NUMBER

    # Number of images to generate for each scene.
    #num-images = 3

    # Image format (jpeg, png, webp).
    #format = jpeg

    # Image quality (jpeg/webp). Default is 95 for jpeg, 100 for webp
    #quality = 95

    # Compression amount for png images (0 to 9). Does not affect quality.
    #compression = 3

    # Number of frames to skip at beginning/end of scene.
    #frame-margin = 1

    # Factor to resize images by (0.5 = half, 1.0 = same, 2.0 = double).
    #scale = 1.0

    # Override image height and/or width. Mutually exclusive with scale.
    #height = 0
    #width = 0

    # Method to use for image scaling (nearest, linear, cubic, area, lanczos4).
    #scale-method = linear

    [export-html]
    # Filename format of created HTML file. Can use $VIDEO_NAME in the name.
    #filename = $VIDEO_NAME-Scenes.html

    # Override <img> element width/height.
    #image-height = 0
    #image-width = 0

    # Do not generate <img> elements in resulting table (yes/no).
    #no-images = no

    [list-scenes]
    # Folder to output scene list. Overrides [global] output option.
    #output = /usr/tmp/images

    # Filename format of created scene list. Can use $VIDEO_NAME in the name.
    #filename = $VIDEO_NAME-Scenes.csv

    # Skip the cutting list as the first row in the CSV file (yes/no).
    # Set this option if compliance with RFC 4180 is required.
    #skip-cuts = no

    # Output only to command-line, don't write file (yes/no).
    #no-output-file = no

    # Suppress printing of scene list.
    #quiet = no

    [load-scenes]
    # Name of column used to mark scene cut points.
    #start-col-name = Start Frame

    #
    # BACKEND OPTIONS
    #

    [backend-opencv]
    # Number of times to keep reading frames after one fails to decode.
    # If set to 0, processing will stop on the first decode failure.
    #max-decode-attempts = 5

    [backend-pyav]
    # Threading mode to use (none, slice, frame, auto). Slice mode is the
    # PyAV default, and auto/frame are the fastest.
    #threading-mode = auto

    # Suppress ffmpeg log output. Default is `no`.
    #
    # WARNING: When threading-mode is set to auto/frame, setting
    # `suppress-output = yes` can cause the the program to not exit properly
    # on Linux/OSX (press Ctrl+C to quit if this occurs).
    #suppress-output = no

#### Backends

PySceneDetect supports multiple backends for video input. Some can be configured by using a config file. Installed backends can be verified by running `scenedetect version --all`.

##### OpenCV

[Default] The OpenCV backend (usually opencv-python) uses OpenCV’s `VideoCapture` for video input. Can be used by specifying `-b opencv` via command line, or setting `backend = opencv` under the `[global]` section of your config file.

It is mostly reliable and fast, although can occasionally run into issues processing videos with multiple audio tracks or small amounts of frame corruption. You can use a custom version of the `cv2` package, or install either the opencv-python or opencv-python-headless packages from pip.

The OpenCV backend also supports image sequences as inputs (e.g. `frame%02d.jpg` if you want to load frame001.jpg, frame002.jpg, frame003.jpg…). Make sure to specify the framerate manually (`-f`/`--framerate`) to ensure accurate timing calculations.

##### PyAV

The PyAV backend (av package) is a more robust backend that handles multiple audio tracks and frame decode errors gracefully.

This backend can be used by specifying `-b pyav` via command line, or setting `backend = pyav` under the `[global]` section of your config file.

### `scenedetect` Python Module 🐍

#### `scenedetect` 🎬 Package

##### Overview

The scenedetect API is designed to be extensible and easy to integrate with most application workflows. Many use cases are covered by the Quickstart and Example sections below. The scenedetect package provides:

> - scenedetect.scene_manager 🎞️: The `SceneManager` class applies SceneDetector objects on video frames from a VideoStream. Also contains the `save_images` and `write_scene_list` / `write_scene_list_html` functions to export information about the detected scenes in various formats.

> - scenedetect.detectors 🕵️: Scene/shot detection algorithms:

>   > - `ContentDetector`: detects fast changes/cuts in video content.

>   > - `ThresholdDetector`: detects changes in video brightness/intensity.

>   > - `AdaptiveDetector`: similar to ContentDetector but may result in less false negatives during rapid camera movement.

> - scenedetect.video_stream 🎥: Contains `VideoStream` interface for video decoding using different backends (`scenedetect.backends`). Current supported backends:

>   > - OpenCV: `VideoStreamCv2`

>   > - PyAV: In Development

> - scenedetect.video_splitter ✂️: Contains `split_video_ffmpeg` and `split_video_mkvmerge` to split a video based on the detected scenes.

> - scenedetect.frame_timecode ⏱️: Contains `FrameTimecode` class for storing, converting, and performing arithmetic on timecodes with frame-accurate precision.

> - scenedetect.scene_detector 🌐: Contains `SceneDetector` base class for implementing scene detection algorithms.

> - scenedetect.stats_manager 🧮: Contains `StatsManager` class for caching frame metrics and loading/saving them to disk in CSV format for analysis. Also used as a persistent cache to make multiple passes on the same video significantly faster.

> - scenedetect.platform 🐱‍💻: Logging and utility functions.

Most types/functions are also available directly from the scenedetect package to make imports simpler.

Warning

The PySceneDetect API is still under development. It is recommended that you pin the scenedetect version in your requirements to below the next major release:

    scenedetect<0.7

##### Quickstart

To get started, the `scenedetect.detect()` function takes a path to a video and a scene detector object, and returns a list of start/end timecodes. For detecting fast cuts (shot changes), we use the `ContentDetector`:

    from scenedetect import detect, ContentDetector
    scene_list = detect('my_video.mp4', ContentDetector())

`scene_list` is now a list of `FrameTimecode` pairs representing the start/end of each scene (try calling `print(scene_list)`). Note that you can set `show_progress=True` when calling `detect` to display a progress bar with estimated time remaining.

Next, let’s print the scene list in a more readable format by iterating over it:

    for i, scene in enumerate(scene_list):
        print('Scene %2d: Start %s / Frame %d, End %s / Frame %d' % (
            i+1,
            scene[0].get_timecode(), scene[0].get_frames(),
            scene[1].get_timecode(), scene[1].get_frames(),))

Now that we know where each scene is, we can also split the input video automatically using ffmpeg (mkvmerge is also supported):

    from scenedetect import detect, ContentDetector, split_video_ffmpeg
    scene_list = detect('my_video.mp4', ContentDetector())
    split_video_ffmpeg('my_video.mp4', scene_list)

This is just a small snippet of what PySceneDetect offers. The library is very modular, and can integrate with most application workflows easily.

In the next example, we show how the library components can be used to create a more customizable scene cut/shot detection pipeline. Additional demonstrations/recipes can be found in the tests/test_api.py file.

##### Example

In this example, we create a function `find_scenes()` which will load a video, detect the scenes, and return a list of tuples containing the (start, end) timecodes of each detected scene. Note that you can modify the threshold argument to modify the sensitivity of the `ContentDetector`, or use other detection algorithms (e.g. `ThresholdDetector`, `AdaptiveDetector`).

    from scenedetect import SceneManager, open_video, ContentDetector

    def find_scenes(video_path, threshold=27.0):
        video = open_video(video_path)
        scene_manager = SceneManager()
        scene_manager.add_detector(
            ContentDetector(threshold=threshold))
        # Detect all scenes in video from current position to end.
        scene_manager.detect_scenes(video)
        # `get_scene_list` returns a list of start/end timecode pairs
        # for each scene that was found.
        return scene_manager.get_scene_list()

Using a `SceneManager` directly allows tweaking the Parameters passed to `detect_scenes` including setting a limit to the number of frames to process, which is useful for live streams/camera devices. You can also combine detection algorithms or create new ones from scratch.

For a more advanced example of using the PySceneDetect API to with a stats file (to save per-frame metrics to disk and/or speed up multiple passes of the same video), take a look at the example in the SceneManager reference.

In addition to module-level examples, demonstrations of some common use cases can be found in the tests/test_api.py file.

##### Functions

The `scenedetect` module comes with helper functions to simplify common use cases. `detect()` can be used to perform scene detection on a video by path. `open_video()` can be used to open a video for a `SceneManager`.

scenedetect.detect(video_path, detector, stats_file_path=None, show_progress=False, start_time=None, end_time=None, start_in_scene=False)

  Perform scene detection on a given video path using the specified detector.

  Parameters:

    - video_path (str) – Path to input video (absolute or relative to working directory).

    - detector (SceneDetector) – A SceneDetector instance (see `scenedetect.detectors` for a full list of detectors).

    - stats_file_path (str | None) – Path to save per-frame metrics to for statistical analysis or to determine a better threshold value.

    - show_progress (bool) – Show a progress bar with estimated time remaining. Default is False.

    - start_time (str | float | int | None) – Starting point in video, in the form of a timecode `HH:MM:SS[.nnn]` (str), number of seconds `123.45` (float), or number of frames `200` (int).

    - end_time (str | float | int | None) – Starting point in video, in the form of a timecode `HH:MM:SS[.nnn]` (str), number of seconds `123.45` (float), or number of frames `200` (int).

    - start_in_scene (bool) – Assume the video begins in a scene. This means that when detecting fast cuts with ContentDetector, if no cuts are found, the resulting scene list will contain a single scene spanning the entire video (instead of no scenes). When detecting fades with ThresholdDetector, the beginning portion of the video will always be included until the first fade-out event is detected.

  Returns:

    List of scenes (pairs of `FrameTimecode` objects).

  Raises:

    - VideoOpenFailure – video_path could not be opened.

    - StatsFileCorrupt – stats_file_path is an invalid stats file

    - ValueError – start_time or end_time are incorrectly formatted.

    - TypeError – start_time or end_time are invalid types.

  Return type:

    List[Tuple[FrameTimecode, FrameTimecode]]

scenedetect.open_video(path, framerate=None, backend='opencv', **kwargs)

  Open a video at the given path. If backend is specified but not available on the current system, OpenCV (VideoStreamCv2) will be used as a fallback.

  Parameters:

    - path (str) – Path to video file to open.

    - framerate (float | None) – Overrides detected framerate if set.

    - backend (str) – Name of specific backend to use, if possible. See `scenedetect.backends.AVAILABLE_BACKENDS` for backends available on the current system. If the backend fails to open the video, OpenCV will be used as a fallback.

    - kwargs – Optional named arguments to pass to the specified backend constructor for overriding backend-specific options.

  Returns:

    Backend object created with the specified video path.

  Raises:

    VideoOpenFailure – Constructing the VideoStream fails. If multiple backends have been attempted, the error from the first backend will be returned.

  Return type:

    VideoStream

##### Module Reference

###### Detection Algorithms

`scenedetect.detectors` Module

This module contains the following scene detection algorithms:

> - `ContentDetector`:

>     Detects shot changes by considering pixel changes in the HSV colorspace.

> - `ThresholdDetector`:

>     Detects transitions below a set pixel intensity (cuts or fades to black).

> - `AdaptiveDetector`:

>     Two-pass version of ContentDetector that handles fast camera movement better in some cases.

Detection algorithms are created by implementing the `SceneDetector` interface. Detectors are typically attached to a `SceneManager` when processing videos, however they can also be used to process frames directly.

`ContentDetector` compares the difference in content between adjacent frames against a set threshold/score, which if exceeded, triggers a scene cut.

This detector is available from the command-line as the detect-content command.

class scenedetect.detectors.content_detector.ContentDetector(threshold=27.0, min_scene_len=15, weights=Components(delta_hue=1.0, delta_sat=1.0, delta_lum=1.0, delta_edges=0.0), luma_only=False, kernel_size=None)

  Detects fast cuts using changes in colour and intensity between frames.

  Since the difference between frames is used, unlike the ThresholdDetector, only fast cuts are detected with this method. To detect slow fades between content scenes still using HSV information, use the DissolveDetector.

  Parameters:

    - threshold (float) – Threshold the average change in pixel intensity must exceed to trigger a cut.

    - min_scene_len (int) – Once a cut is detected, this many frames must pass before a new one can be added to the scene list.

    - weights (ContentDetector.Components) – Weight to place on each component when calculating frame score (content_val in a statsfile, the value threshold is compared against).

    - luma_only (bool) – If True, only considers changes in the luminance channel of the video. Equivalent to specifying weights as `ContentDetector.LUMA_ONLY`. Overrides weights if both are set.

    - kernel_size (int | None) – Size of kernel for expanding detected edges. Must be odd integer greater than or equal to 3. If None, automatically set using video resolution.

  class Components(delta_hue=1.0, delta_sat=1.0, delta_lum=1.0, delta_edges=0.0)

    Components that make up a frame’s score, and their default values.

    Create new instance of Components(delta_hue, delta_sat, delta_lum, delta_edges)

    Parameters:

      - delta_hue (float) –

      - delta_sat (float) –

      - delta_lum (float) –

      - delta_edges (float) –

    delta_edges: float

      Difference between calculated edges of adjacent frames.

      Edge differences are typically larger than the other components, so the detection threshold may need to be adjusted accordingly.

    delta_hue: float

      Difference between pixel hue values of adjacent frames.

    delta_lum: float

      Difference between pixel luma (brightness) values of adjacent frames.

    delta_sat: float

      Difference between pixel saturation values of adjacent frames.

  get_metrics()

    Get Metrics: Get a list of all metric names/keys used by the detector.

    Returns:

      List of strings of frame metric key names that will be used by the detector when a StatsManager is passed to process_frame.

  is_processing_required(frame_num)

    [DEPRECATED] DO NOT USE

    Test if all calculations for a given frame are already done.

    Returns:

      False if the SceneDetector has assigned _metric_keys, and the stats_manager property is set to a valid StatsManager object containing the required frame metrics/calculations for the given frame - thus, not needing the frame to perform scene detection.

      True otherwise (i.e. the frame_img passed to process_frame is required to be passed to process_frame for the given frame_num).

  process_frame(frame_num, frame_img)

    Similar to ThresholdDetector, but using the HSV colour space DIFFERENCE instead of single-frame RGB/grayscale intensity (thus cannot detect slow fades with this method).

    Parameters:

      - frame_num (int) – Frame number of frame that is being passed.

      - frame_img (ndarray) – Decoded frame image (numpy.ndarray) to perform scene detection on. Can be None only if the self.is_processing_required() method (inhereted from the base SceneDetector class) returns True.

    Returns:

      List of frames where scene cuts have been detected. There may be 0 or more frames in the list, and not necessarily the same as frame_num.

    Return type:

      List[int]

  DEFAULT_COMPONENT_WEIGHTS = Components(delta_hue=1.0, delta_sat=1.0, delta_lum=1.0, delta_edges=0.0)

    Default component weights. Actual default values are specified in `Components` to allow adding new components without breaking existing usage.

  FRAME_SCORE_KEY = 'content_val'

    Key in statsfile representing the final frame score after weighed by specified components.

  LUMA_ONLY_WEIGHTS = Components(delta_hue=0.0, delta_sat=0.0, delta_lum=1.0, delta_edges=0.0)

    Component weights to use if luma_only is set.

  METRIC_KEYS = ['content_val', 'delta_hue', 'delta_sat', 'delta_lum', 'delta_edges']

    All statsfile keys this detector produces.

`AdaptiveDetector` compares the difference in content between adjacent frames similar to ContentDetector except the threshold isn’t fixed, but is a rolling average of adjacent frame changes. This can help mitigate false detections in situations such as fast camera motions.

This detector is available from the command-line as the detect-adaptive command.

class scenedetect.detectors.adaptive_detector.AdaptiveDetector(adaptive_threshold=3.0, min_scene_len=15, window_width=2, min_content_val=15.0, weights=Components(delta_hue=1.0, delta_sat=1.0, delta_lum=1.0, delta_edges=0.0), luma_only=False, kernel_size=None, video_manager=None, min_delta_hsv=None)

  Two-pass detector that calculates frame scores with ContentDetector, and then applies a rolling average when processing the result that can help mitigate false detections in situations such as camera movement.

  Parameters:

    - adaptive_threshold (float) – Threshold (float) that score ratio must exceed to trigger a new scene (see frame metric adaptive_ratio in stats file).

    - min_scene_len (int) – Minimum length of any scene.

    - window_width (int) – Size of window (number of frames) before and after each frame to average together in order to detect deviations from the mean. Must be at least 1.

    - min_content_val (float) – Minimum threshold (float) that the content_val must exceed in order to register as a new scene. This is calculated the same way that detect-content calculates frame score based on weights/luma_only/kernel_size.

    - weights (Components) – Weight to place on each component when calculating frame score (content_val in a statsfile, the value threshold is compared against). If omitted, the default ContentDetector weights are used.

    - luma_only (bool) – If True, only considers changes in the luminance channel of the video. Equivalent to specifying weights as `ContentDetector.LUMA_ONLY`. Overrides weights if both are set.

    - kernel_size (int | None) – Size of kernel to use for post edge detection filtering. If None, automatically set based on video resolution.

    - video_manager – [DEPRECATED] DO NOT USE. For backwards compatibility only.

    - min_delta_hsv (float | None) – [DEPRECATED] DO NOT USE. Use min_content_val instead.

  get_content_val(frame_num)

    Returns the average content change for a frame.

    Parameters:

      frame_num (int) –

    Return type:

      float | None

  get_metrics()

    Combines base ContentDetector metric keys with the AdaptiveDetector one.

    Return type:

      List[str]

  post_process(_unused_frame_num)

    Not required for AdaptiveDetector.

    Parameters:

      _unused_frame_num (int) –

  process_frame(frame_num, frame_img)

    Similar to ThresholdDetector, but using the HSV colour space DIFFERENCE instead of single-frame RGB/grayscale intensity (thus cannot detect slow fades with this method).

    Parameters:

      - frame_num (int) – Frame number of frame that is being passed.

      - frame_img (ndarray | None) – Decoded frame image (numpy.ndarray) to perform scene detection on. Can be None only if the self.is_processing_required() method (inhereted from the base SceneDetector class) returns True.

    Returns:

      Empty list

    Return type:

      List[int]

  stats_manager_required()

    Not required for AdaptiveDetector.

    Return type:

      bool

  property event_buffer_length: int

    Number of frames any detected cuts will be behind the current frame due to buffering.

`ThresholdDetector` uses a set intensity as a threshold to detect cuts, which are triggered when the average pixel intensity exceeds or falls below this threshold.

This detector is available from the command-line as the detect-threshold command.

class scenedetect.detectors.threshold_detector.ThresholdDetector(threshold=12, min_scene_len=15, fade_bias=0.0, add_final_scene=False, method=Method.FLOOR, block_size=None)

  Detects fast cuts/slow fades in from and out to a given threshold level.

  Detects both fast cuts and slow fades so long as an appropriate threshold is chosen (especially taking into account the minimum grey/black level).

  Parameters:

    - threshold (float) – 8-bit intensity value that each pixel value (R, G, and B) must be <= to in order to trigger a fade in/out.

    - min_scene_len (int) – FrameTimecode object or integer greater than 0 of the minimum length, in frames, of a scene (or subsequent scene cut).

    - fade_bias (float) – Float between -1.0 and +1.0 representing the percentage of timecode skew for the start of a scene (-1.0 causing a cut at the fade-to-black, 0.0 in the middle, and +1.0 causing the cut to be right at the position where the threshold is passed).

    - add_final_scene (bool) – Boolean indicating if the video ends on a fade-out to generate an additional scene at this timecode.

    - method (Method) – How to treat threshold when detecting fade events.

    - block_size – [DEPRECATED] DO NOT USE. For backwards compatibility.

  class Method(value)

    Method for ThresholdDetector to use when comparing frame brightness to the threshold.

    CEILING = 1

      Fade out happens when frame brightness rises above threshold.

    FLOOR = 0

      Fade out happens when frame brightness falls below threshold.

  get_metrics()

    Get Metrics: Get a list of all metric names/keys used by the detector.

    Returns:

      List of strings of frame metric key names that will be used by the detector when a StatsManager is passed to process_frame.

    Return type:

      List[str]

  post_process(frame_num)

    Writes a final scene cut if the last detected fade was a fade-out.

    Only writes the scene cut if add_final_scene is true, and the last fade that was detected was a fade-out. There is no bias applied to this cut (since there is no corresponding fade-in) so it will be located at the exact frame where the fade-out crossed the detection threshold.

    Parameters:

      frame_num (int) –

  process_frame(frame_num, frame_img)
    Parameters:

      - frame_num (int) – Frame number of frame that is being passed.

      - frame_img (numpy.ndarray or None) – Decoded frame image (numpy.ndarray) to perform scene detection with. Can be None only if the self.is_processing_required() method (inhereted from the base SceneDetector class) returns True.

    Returns:

      List of frames where scene cuts have been detected. There may be 0 or more frames in the list, and not necessarily the same as frame_num.

    Return type:

      List[int]

###### Backends

`scenedetect.backends` Module

This module contains `VideoStream` implementations backed by various Python multimedia libraries. In addition to creating backend objects directly, `scenedetect.open_video()` can be used to open a video with a specified backend, falling back to OpenCV if not available.

All backends available on the current system can be found via `AVAILABLE_BACKENDS`.

If you already have a cv2.VideoCapture object you want to use for scene detection, you can use a `VideoCaptureAdapter` instead of a backend. This is useful when working with devices or streams, for example.

###### Video Files

Assuming we have a file video.mp4 in our working directory, we can load it and perform scene detection on it using `open_video()`:

    from scenedetect import open_video
    video = open_video('video.mp4')

An optional backend from `AVAILABLE_BACKENDS` can be passed to `open_video()` (e.g. backend=’opencv’). Additional keyword arguments passed to `open_video()` will be forwarded to the backend constructor. If the specified backend is unavailable, or loading the video fails, `opencv` will be tried as a fallback.

Lastly, to use a specific backend directly:

    # Manually importing and constructing a backend:
    from scenedetect.backends.opencv import VideoStreamCv2
    video = VideoStreamCv2('video.mp4')

In both examples above, the resulting `video` can be used with `SceneManager.detect_scenes()`.

###### Devices / Cameras / Pipes

You can use an existing cv2.VideoCapture object with the PySceneDetect API using a `VideoCaptureAdapter`. For example, to use a `SceneManager` with a webcam device:

    from scenedetect import SceneManager, ContentDetector
    from scenedetect.backends import VideoCaptureAdapter
    # Open device ID 2.
    cap = cv2.VideoCapture(2)
    video = VideoCaptureAdapter(cap)
    total_frames = 1000
    scene_manager = SceneManager()
    scene_manager.add_detector(ContentDetector())
    scene_manager.detect_scenes(video=video, duration=total_frames)

When working with live inputs, note that you can pass a callback to `detect_scenes()` to be called on every scene detection event. See the `SceneManager` examples for details.

scenedetect.backends.AVAILABLE_BACKENDS: Dict[str, Type] = {'moviepy': <class 'scenedetect.backends.moviepy.VideoStreamMoviePy'>, 'opencv': <class 'scenedetect.backends.opencv.VideoStreamCv2'>, 'pyav': <class 'scenedetect.backends.pyav.VideoStreamAv'>}

  All available backends that `scenedetect.open_video()` can consider for the backend parameter. These backends must support construction with the following signature:

  > BackendType(path: str, framerate: Optional[float])

`VideoStreamCv2` is backed by the OpenCV VideoCapture object. This is the default backend. Works with video files, image sequences, and network streams/URLs.

For wrapping input devices or pipes, there is also `VideoCaptureAdapter` which can be constructed from an existing cv2.VideoCapture. This allows performing scene detection on inputs which do not support seeking.

class scenedetect.backends.opencv.VideoCaptureAdapter(cap, framerate=None, max_read_attempts=5)

  Adapter for existing VideoCapture objects. Unlike VideoStreamCv2, this class supports VideoCaptures which may not support seeking.

  Create from an existing OpenCV VideoCapture object. Used for webcams, live streams, pipes, or other inputs which may not support seeking.

  Parameters:

    - cap (VideoCapture) – The cv2.VideoCapture object to wrap. Must already be opened and ready to have cap.read() called on it.

    - framerate (float | None) – If set, overrides the detected framerate.

    - max_read_attempts (int) – Number of attempts to continue decoding the video after a frame fails to decode. This allows processing videos that have a few corrupted frames or metadata (in which case accuracy of detection algorithms may be lower). Once this limit is passed, decoding will stop and emit an error.

  Raises:

    ValueError – capture is not open, framerate or max_read_attempts is invalid

  read(decode=True, advance=True)

    Read and decode the next frame as a numpy.ndarray. Returns False when video ends, or the maximum number of decode attempts has passed.

    Parameters:

      - decode (bool) – Decode and return the frame.

      - advance (bool) – Seek to the next frame. If False, will return the current (last) frame.

    Returns:

      If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video. If decode = False, a bool indicating if advancing to the the next frame succeeded.

    Return type:

      ndarray | bool

  reset()

    Not supported.

  seek(target)

    The underlying VideoCapture is assumed to not support seeking.

    Parameters:

      target (FrameTimecode | float | int) –

  BACKEND_NAME = 'opencv_adapter'

    Unique name used to identify this backend.

  property aspect_ratio: float

    Display/pixel aspect ratio as a float (1.0 represents square pixels).

  property capture: VideoCapture

    Returns reference to underlying VideoCapture object. Use with caution.

    Prefer to use this property only to take ownership of the underlying cv2.VideoCapture object backing this object. Using the read/grab methods through this property are unsupported and will leave this object in an inconsistent state.

  property duration: FrameTimecode | None

    Always None, as the underlying VideoCapture is assumed to not have a known duration.

  property frame_number: int

    Current position within stream in frames as an int.

    1 indicates the first frame was just decoded by the last call to read with advance=True, whereas 0 indicates that no frames have been read.

    This method will always return 0 if no frames have been read.

  property frame_rate: float

    Framerate in frames/sec.

  property frame_size: Tuple[int, int]

    Reported size of each video frame in pixels as a tuple of (width, height).

  property is_seekable: bool

    Always False, as the underlying VideoCapture is assumed to not support seeking.

  property name: str

    Always ‘CAP_ADAPTER’.

  property path: str

    Always ‘CAP_ADAPTER’.

  property position: FrameTimecode

    Current position within stream as FrameTimecode. Use the `position_ms()` if an accurate duration of elapsed time is required, as position is currently based off of the number of frames, and may not be accurate for devicesor live streams.

    This method will always return 0 (e.g. be equal to base_timecode) if no frames have been read.

  property position_ms: float

    Current position within stream as a float of the presentation time in milliseconds. The first frame has a time of 0.0 ms.

    This method will always return 0.0 if no frames have been read.

class scenedetect.backends.opencv.VideoStreamCv2(path=None, framerate=None, max_decode_attempts=5, path_or_device=None)

  OpenCV cv2.VideoCapture backend.

  Open a video file, image sequence, or network stream.

  Parameters:

    - path (AnyStr) – Path to the video. Can be a file, image sequence (‘folder/DSC_%04d.jpg’), or network stream.

    - framerate (float | None) – If set, overrides the detected framerate.

    - max_decode_attempts (int) – Number of attempts to continue decoding the video after a frame fails to decode. This allows processing videos that have a few corrupted frames or metadata (in which case accuracy of detection algorithms may be lower). Once this limit is passed, decoding will stop and emit an error.

    - path_or_device (bytes | str | int) – [DEPRECATED] Specify path for files, image sequences, or network streams/URLs. Use VideoCaptureAdapter for devices/pipes.

  Raises:

    - OSError – file could not be found or access was denied

    - VideoOpenFailure – video could not be opened (may be corrupted)

    - ValueError – specified framerate is invalid

  read(decode=True, advance=True)

    Read and decode the next frame as a numpy.ndarray. Returns False when video ends, or the maximum number of decode attempts has passed.

    Parameters:

      - decode (bool) – Decode and return the frame.

      - advance (bool) – Seek to the next frame. If False, will return the current (last) frame.

    Returns:

      If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video. If decode = False, a bool indicating if advancing to the the next frame succeeded.

    Return type:

      ndarray | bool

  reset()

    Close and re-open the VideoStream (should be equivalent to calling seek(0)).

  seek(target)

    Seek to the given timecode. If given as a frame number, represents the current seek pointer (e.g. if seeking to 0, the next frame decoded will be the first frame of the video).

    For 1-based indices (first frame is frame #1), the target frame number needs to be converted to 0-based by subtracting one. For example, if we want to seek to the first frame, we call seek(0) followed by read(). If we want to seek to the 5th frame, we call seek(4) followed by read(), at which point frame_number will be 5.

    Not supported if the VideoStream is a device/camera. Untested with web streams.

    Parameters:

      target (FrameTimecode | float | int) – Target position in video stream to seek to. If float, interpreted as time in seconds. If int, interpreted as frame number.

    Raises:

      - SeekError – An error occurs while seeking, or seeking is not supported.

      - ValueError – target is not a valid value (i.e. it is negative).

  BACKEND_NAME = 'opencv'

    Unique name used to identify this backend.

  property aspect_ratio: float

    Display/pixel aspect ratio as a float (1.0 represents square pixels).

  property capture: VideoCapture

    Returns reference to underlying VideoCapture object. Use with caution.

    Prefer to use this property only to take ownership of the underlying cv2.VideoCapture object backing this object. Seeking or using the read/grab methods through this property are unsupported and will leave this object in an inconsistent state.

  property duration: FrameTimecode | None

    Duration of the stream as a FrameTimecode, or None if non terminating.

  property frame_number: int

    Current position within stream in frames as an int.

    1 indicates the first frame was just decoded by the last call to read with advance=True, whereas 0 indicates that no frames have been read.

    This method will always return 0 if no frames have been read.

  property frame_rate: float

    Framerate in frames/sec.

  property frame_size: Tuple[int, int]

    Size of each video frame in pixels as a tuple of (width, height).

  property is_seekable: bool

    True if seek() is allowed, False otherwise.

    Always False if opening a device/webcam.

  property name: str

    Name of the video, without extension, or device.

  property path: bytes | str

    Video or device path.

  property position: FrameTimecode

    Current position within stream as FrameTimecode.

    This can be interpreted as presentation time stamp of the last frame which was decoded by calling read with advance=True.

    This method will always return 0 (e.g. be equal to base_timecode) if no frames have been read.

  property position_ms: float

    Current position within stream as a float of the presentation time in milliseconds. The first frame has a time of 0.0 ms.

    This method will always return 0.0 if no frames have been read.

`VideoStreamAv` provides an adapter for the PyAV av.InputContainer object.

Uses string identifier `'pyav'`.

class scenedetect.backends.pyav.VideoStreamAv(path_or_io, framerate=None, name=None, threading_mode=None, suppress_output=False)

  PyAV av.InputContainer backend.

  Open a video by path.

  Warning

  Using threading_mode with suppress_output = True can cause lockups in your application. See the PyAV documentation for details: https://pyav.org/docs/stable/overview/caveats.html#sub-interpeters

  Parameters:

    - path_or_io (AnyStr | BinaryIO) – Path to the video, or a file-like object.

    - framerate (float | None) – If set, overrides the detected framerate.

    - name (str | None) – Overrides the name property derived from the video path. Should be set if path_or_io is a file-like object.

    - threading_mode (str | None) – The PyAV video stream thread_type. See av.codec.context.ThreadType for valid threading modes (‘AUTO’, ‘FRAME’, ‘NONE’, and ‘SLICE’). If this mode is ‘AUTO’ or ‘FRAME’ and not all frames have been decoded, the video will be reopened if seekable, and the remaining frames decoded in single-threaded mode.

    - suppress_output (bool) – If False, ffmpeg output will be sent to stdout/stderr by calling av.logging.restore_default_callback() before any other library calls. If True the application may deadlock if threading_mode is set. See the PyAV documentation for details: https://pyav.org/docs/stable/overview/caveats.html#sub-interpeters

  Raises:

    - OSError – file could not be found or access was denied

    - VideoOpenFailure – video could not be opened (may be corrupted)

    - ValueError – specified framerate is invalid

  read(decode=True, advance=True)

    Read and decode the next frame as a numpy.ndarray. Returns False when video ends.

    Parameters:

      - decode (bool) – Decode and return the frame.

      - advance (bool) – Seek to the next frame. If False, will return the current (last) frame.

    Returns:

      If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video. If decode = False, a bool indicating if advancing to the the next frame succeeded.

    Return type:

      ndarray | bool

  reset()

    Close and re-open the VideoStream (should be equivalent to calling seek(0)).

  seek(target)

    Seek to the given timecode. If given as a frame number, represents the current seek pointer (e.g. if seeking to 0, the next frame decoded will be the first frame of the video).

    For 1-based indices (first frame is frame #1), the target frame number needs to be converted to 0-based by subtracting one. For example, if we want to seek to the first frame, we call seek(0) followed by read(). If we want to seek to the 5th frame, we call seek(4) followed by read(), at which point frame_number will be 5.

    May not be supported on all input codecs (see is_seekable).

    Parameters:

      target (FrameTimecode | float | int) – Target position in video stream to seek to. If float, interpreted as time in seconds. If int, interpreted as frame number.

    Raises:

      ValueError – target is not a valid value (i.e. it is negative).

    Return type:

      None

  BACKEND_NAME = 'pyav'

    Unique name used to identify this backend.

  property aspect_ratio: float

    Pixel aspect ratio as a float (1.0 represents square pixels).

  property duration: FrameTimecode

    Duration of the video as a FrameTimecode.

  property frame_number: int

    Current position within stream as the frame number.

    Will return 0 until the first frame is read.

  property frame_rate: float

    Frame rate in frames/sec.

  property frame_size: Tuple[int, int]

    Size of each video frame in pixels as a tuple of (width, height).

  property is_seekable: bool

    True if seek() is allowed, False otherwise.

  property name: bytes | str

    Name of the video, without extension.

  property path: bytes | str

    Video path.

  property position: FrameTimecode

    Current position within stream as FrameTimecode.

    This can be interpreted as presentation time stamp, thus frame 1 corresponds to the presentation time 0. Returns 0 even if frame_number is 1.

  property position_ms: float

    Current position within stream as a float of the presentation time in milliseconds. The first frame has a PTS of 0.

`VideoStreamMoviePy` provides an adapter for MoviePy’s FFMPEG_VideoReader.

Uses string identifier `'moviepy'`.

Warning

The MoviePy backend is still under development. Some features are not yet supported.

class scenedetect.backends.moviepy.VideoStreamMoviePy(path, framerate=None, print_infos=False)

  MoviePy FFMPEG_VideoReader backend.

  Open a video or device.

  Parameters:

    - path (AnyStr) – Path to video,.

    - framerate (float | None) – If set, overrides the detected framerate.

    - print_infos (bool) – If True, prints information about the opened video to stdout.

  Raises:

    - OSError – file could not be found, access was denied, or the video is corrupt

    - VideoOpenFailure – video could not be opened (may be corrupted)

  read(decode=True, advance=True)

    Read and decode the next frame as a numpy.ndarray. Returns False when video ends.

    Parameters:

      - decode (bool) – Decode and return the frame.

      - advance (bool) – Seek to the next frame. If False, will return the current (last) frame.

    Returns:

      If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video. If decode = False, a bool indicating if advancing to the the next frame succeeded.

    Return type:

      ndarray | bool

  reset()

    Close and re-open the VideoStream (should be equivalent to calling seek(0)).

  seek(target)

    Seek to the given timecode. If given as a frame number, represents the current seek pointer (e.g. if seeking to 0, the next frame decoded will be the first frame of the video).

    For 1-based indices (first frame is frame #1), the target frame number needs to be converted to 0-based by subtracting one. For example, if we want to seek to the first frame, we call seek(0) followed by read(). If we want to seek to the 5th frame, we call seek(4) followed by read(), at which point frame_number will be 5.

    Not supported if the VideoStream is a device/camera. Untested with web streams.

    Parameters:

      target (FrameTimecode | float | int) – Target position in video stream to seek to. If float, interpreted as time in seconds. If int, interpreted as frame number.

    Raises:

      - SeekError – An error occurs while seeking, or seeking is not supported.

      - ValueError – target is not a valid value (i.e. it is negative).

  BACKEND_NAME = 'moviepy'

    Unique name used to identify this backend.

  property aspect_ratio: float

    Display/pixel aspect ratio as a float (1.0 represents square pixels).

  property duration: FrameTimecode | None

    Duration of the stream as a FrameTimecode, or None if non terminating.

  property frame_number: int

    Current position within stream in frames as an int.

    1 indicates the first frame was just decoded by the last call to read with advance=True, whereas 0 indicates that no frames have been read.

    This method will always return 0 if no frames have been read.

  property frame_rate: float

    Framerate in frames/sec.

  property frame_size: Tuple[int, int]

    Size of each video frame in pixels as a tuple of (width, height).

  property is_seekable: bool

    True if seek() is allowed, False otherwise.

  property name: str

    Name of the video, without extension, or device.

  property path: bytes | str

    Video path.

  property position: FrameTimecode

    Current position within stream as FrameTimecode.

    This can be interpreted as presentation time stamp of the last frame which was decoded by calling read with advance=True.

    This method will always return 0 (e.g. be equal to base_timecode) if no frames have been read.

  property position_ms: float

    Current position within stream as a float of the presentation time in milliseconds. The first frame has a time of 0.0 ms.

    This method will always return 0.0 if no frames have been read.

###### SceneManager

`scenedetect.scene_manager` Module

This module implements `SceneManager`, coordinates running a `SceneDetector` over the frames of a video (`VideoStream`). Video decoding is done in a separate thread to improve performance.

This module also contains other helper functions (e.g. `save_images()`) which can be used to process the resulting scene list.

###### Usage

The following example shows basic usage of a `SceneManager`:

    from scenedetect import open_video, SceneManager, ContentDetector
    video = open_video(video_path)
    scene_manager = SceneManager()
    scene_manager.add_detector(ContentDetector())
    # Detect all scenes in video from current position to end.
    scene_manager.detect_scenes(video)
    # `get_scene_list` returns a list of start/end timecode pairs
    # for each scene that was found.
    scenes = scene_manager.get_scene_list()

An optional callback can also be invoked on each detected scene, for example:

    from scenedetect import open_video, SceneManager, ContentDetector

    # Callback to invoke on the first frame of every new scene detection.
    def on_new_scene(frame_img: numpy.ndarray, frame_num: int):
        print("New scene found at frame %d." % frame_num)

    video = open_video(test_video_file)
    scene_manager = SceneManager()
    scene_manager.add_detector(ContentDetector())
    scene_manager.detect_scenes(video=video, callback=on_new_scene)

To use a SceneManager with a webcam/device or existing cv2.VideoCapture device, use the `VideoCaptureAdapter` instead of open_video.

###### Storing Per-Frame Statistics

SceneManager can use an optional `StatsManager` to save frame statistics to disk:

    from scenedetect import open_video, ContentDetector, SceneManager, StatsManager
    video = open_video(test_video_file)
    scene_manager = SceneManager(stats_manager=StatsManager())
    scene_manager.add_detector(ContentDetector())
    scene_manager.detect_scenes(video=video)
    scene_list = scene_manager.get_scene_list()
    print_scenes(scene_list=scene_list)
    # Save per-frame statistics to disk.
    scene_manager.stats_manager.save_to_csv(csv_file=STATS_FILE_PATH)

The statsfile can be used to find a better threshold for certain inputs, or perform statistical analysis of the video.

class scenedetect.scene_manager.Interpolation(value)

  Interpolation method used for image resizing. Based on constants defined in OpenCV.

  AREA = 3

    Pixel area relation resampling. Provides moire’-free downscaling.

  CUBIC = 2

    Bicubic interpolation.

  LANCZOS4 = 4

    Lanczos interpolation over 8x8 neighborhood.

  LINEAR = 1

    Bilinear interpolation.

  NEAREST = 0

    Nearest neighbor interpolation.

class scenedetect.scene_manager.SceneManager(stats_manager=None)

  The SceneManager facilitates detection of scenes (`detect_scenes()`) on a video (`VideoStream`) using a detector (`add_detector()`). Video decoding is done in parallel in a background thread.

  Parameters:

    stats_manager (StatsManager | None) – `StatsManager` to bind to this SceneManager. Can be accessed via the stats_manager property of the resulting object to save to disk.

  add_detector(detector)

    Add/register a SceneDetector (e.g. ContentDetector, ThresholdDetector) to run when detect_scenes is called. The SceneManager owns the detector object, so a temporary may be passed.

    Parameters:

      detector (SceneDetector) – Scene detector to add to the SceneManager.

    Return type:

      None

  clear()

    Clear all cuts/scenes and resets the SceneManager’s position.

    Any statistics generated are still saved in the StatsManager object passed to the SceneManager’s constructor, and thus, subsequent calls to detect_scenes, using the same frame source seeked back to the original time (or beginning of the video) will use the cached frame metrics that were computed and saved in the previous call to detect_scenes.

    Return type:

      None

  clear_detectors()

    Remove all scene detectors added to the SceneManager via add_detector().

    Return type:

      None

  detect_scenes(video=None, duration=None, end_time=None, frame_skip=0, show_progress=False, callback=None, frame_source=None)

    Perform scene detection on the given video using the added SceneDetectors, returning the number of frames processed. Results can be obtained by calling `get_scene_list()` or `get_cut_list()`.

    Video decoding is performed in a background thread to allow scene detection and frame decoding to happen in parallel. Detection will continue until no more frames are left, the specified duration or end time has been reached, or `stop()` was called.

    Parameters:

      - video (VideoStream | None) – VideoStream obtained from either scenedetect.open_video, or by creating one directly (e.g. scenedetect.backends.opencv.VideoStreamCv2).

      - duration (FrameTimecode | None) – Amount of time to detect from current video position. Cannot be specified if end_time is set.

      - end_time (FrameTimecode | None) – Time to stop processing at. Cannot be specified if duration is set.

      - frame_skip (int) – Not recommended except for extremely high framerate videos. Number of frames to skip (i.e. process every 1 in N+1 frames, where N is frame_skip, processing only 1/N+1 percent of the video, speeding up the detection time at the expense of accuracy). frame_skip must be 0 (the default) when using a StatsManager.

      - show_progress (bool) – If True, and the `tqdm` module is available, displays a progress bar with the progress, framerate, and expected time to complete processing the video frame source.

      - callback (Callable[[ndarray, int], None] | None) – If set, called after each scene/event detected.

      - frame_source (VideoStream | None) – [DEPRECATED] DO NOT USE. For compatibility with previous version.

    Returns:

      Number of frames read and processed from the frame source.

    Return type:

      int

    Raises:

      ValueError – frame_skip must be 0 (the default) if the SceneManager was constructed with a StatsManager object.

  get_cut_list(base_timecode=None, show_warning=True)

    [DEPRECATED] Return a list of FrameTimecodes of the detected scene changes/cuts.

    Unlike get_scene_list, the cutting list returns a list of FrameTimecodes representing the point in the input video where a new scene was detected, and thus the frame where the input should be cut/split. The cutting list, in turn, is used to generate the scene list, noting that each scene is contiguous starting from the first frame and ending at the last frame detected.

    If only sparse detectors are used (e.g. MotionDetector), this will always be empty.

    Parameters:

      - base_timecode (FrameTimecode | None) – [DEPRECATED] DO NOT USE. For backwards compatibility only.

      - show_warning (bool) – If set to False, suppresses the error from being warned. In v0.7, this will have no effect and the error will become a Python warning.

    Returns:

      List of FrameTimecode objects denoting the points in time where a scene change was detected in the input video, which can also be passed to external tools for automated splitting of the input into individual scenes.

    Return type:

      List[FrameTimecode]

  get_event_list(base_timecode=None)

    [DEPRECATED] DO NOT USE.

    Get a list of start/end timecodes of sparse detection events.

    Unlike get_scene_list, the event list returns a list of FrameTimecodes representing the point in the input video where a new scene was detected only by sparse detectors, otherwise it is the same.

    Parameters:

      base_timecode (FrameTimecode | None) – [DEPRECATED] DO NOT USE. For backwards compatibility only.

    Returns:

      List of pairs of FrameTimecode objects denoting the detected scenes.

    Return type:

      List[Tuple[FrameTimecode, FrameTimecode]]

  get_num_detectors()

    Get number of registered scene detectors added via add_detector.

    Return type:

      int

  get_scene_list(base_timecode=None, start_in_scene=False)

    Return a list of tuples of start/end FrameTimecodes for each detected scene.

    Parameters:

      - base_timecode (FrameTimecode | None) – [DEPRECATED] DO NOT USE. For backwards compatibility.

      - start_in_scene (bool) – Assume the video begins in a scene. This means that when detecting fast cuts with ContentDetector, if no cuts are found, the resulting scene list will contain a single scene spanning the entire video (instead of no scenes). When detecting fades with ThresholdDetector, the beginning portion of the video will always be included until the first fade-out event is detected.

    Returns:

      List of tuples in the form (start_time, end_time), where both start_time and end_time are FrameTimecode objects representing the exact time/frame where each detected scene in the video begins and ends.

    Return type:

      List[Tuple[FrameTimecode, FrameTimecode]]

  stop()

    Stop the current `detect_scenes()` call, if any. Thread-safe.

    Return type:

      None

  property auto_downscale: bool

    If set to True, will automatically downscale based on video frame size.

    Overrides downscale if set.

  property downscale: int

    Factor to downscale each frame by. Will always be >= 1, where 1 indicates no scaling. Will be ignored if auto_downscale=True.

  property interpolation: Interpolation

    Interpolation method to use when downscaling frames. Must be one of cv2.INTER_*.

  property stats_manager: StatsManager | None

    Getter for the StatsManager associated with this SceneManager, if any.

scenedetect.scene_manager.compute_downscale_factor(frame_width, effective_width=256)

  Get the optimal default downscale factor based on a video’s resolution (currently only the width in pixels is considered).

  The resulting effective width of the video will be between frame_width and 1.5 * frame_width pixels (e.g. if frame_width is 200, the range of effective widths will be between 200 and 300).

  Parameters:

    - frame_width (int) – Actual width of the video frame in pixels.

    - effective_width (int) – Desired minimum width in pixels.

  Returns:

    The defalt downscale factor to use to achieve at least the target effective_width.

  Return type:

    int

scenedetect.scene_manager.get_scenes_from_cuts(cut_list, start_pos, end_pos, base_timecode=None)

  Returns a list of tuples of start/end FrameTimecodes for each scene based on a list of detected scene cuts/breaks.

  This function is called when using the `SceneManager.get_scene_list()` method. The scene list is generated from a cutting list (`SceneManager.get_cut_list()`), noting that each scene is contiguous, starting from the first to last frame of the input. If cut_list is empty, the resulting scene will span from start_pos to end_pos.

  Parameters:

    - cut_list (Iterable[FrameTimecode]) – List of FrameTimecode objects where scene cuts/breaks occur.

    - base_timecode (FrameTimecode | None) – The base_timecode of which all FrameTimecodes in the cut_list are based on.

    - num_frames – The number of frames, or FrameTimecode representing duration, of the video that was processed (used to generate last scene’s end time).

    - start_frame – The start frame or FrameTimecode of the cut list. Used to generate the first scene’s start time. base_timecode: [DEPRECATED] DO NOT USE. For backwards compatibility only.

    - start_pos (int | FrameTimecode) –

    - end_pos (int | FrameTimecode) –

  Returns:

    List of tuples in the form (start_time, end_time), where both start_time and end_time are FrameTimecode objects representing the exact time/frame where each scene occupies based on the input cut_list.

  Return type:

    List[Tuple[FrameTimecode, FrameTimecode]]

scenedetect.scene_manager.save_images(scene_list, video, num_images=3, frame_margin=1, image_extension='jpg', encoder_param=95, image_name_template='$VIDEO_NAME-Scene-$SCENE_NUMBER-$IMAGE_NUMBER', output_dir=None, show_progress=False, scale=None, height=None, width=None, interpolation=Interpolation.CUBIC, video_manager=None)

  Save a set number of images from each scene, given a list of scenes and the associated video/frame source.

  Parameters:

    - scene_list (List[Tuple[FrameTimecode, FrameTimecode]]) – A list of scenes (pairs of FrameTimecode objects) returned from calling a SceneManager’s detect_scenes() method.

    - video (VideoStream) – A VideoStream object corresponding to the scene list. Note that the video will be closed/re-opened and seeked through.

    - num_images (int) – Number of images to generate for each scene. Minimum is 1.

    - frame_margin (int) – Number of frames to pad each scene around the beginning and end (e.g. moves the first/last image into the scene by N frames). Can set to 0, but will result in some video files failing to extract the very last frame.

    - image_extension (str) – Type of image to save (must be one of ‘jpg’, ‘png’, or ‘webp’).

    - encoder_param (int) – Quality/compression efficiency, based on type of image: ‘jpg’ / ‘webp’: Quality 0-100, higher is better quality. 100 is lossless for webp. ‘png’: Compression from 1-9, where 9 achieves best filesize but is slower to encode.

    - image_name_template (str) – Template to use when creating the images on disk. Can use the macros $VIDEO_NAME, $SCENE_NUMBER, and $IMAGE_NUMBER. The image extension is applied automatically as per the argument image_extension.

    - output_dir (str | None) – Directory to output the images into. If not set, the output is created in the working directory.

    - show_progress (bool | None) – If True, shows a progress bar if tqdm is installed.

    - scale (float | None) – Optional factor by which to rescale saved images. A scaling factor of 1 would not result in rescaling. A value < 1 results in a smaller saved image, while a value > 1 results in an image larger than the original. This value is ignored if either the height or width values are specified.

    - height (int | None) – Optional value for the height of the saved images. Specifying both the height and width will resize images to an exact size, regardless of aspect ratio. Specifying only height will rescale the image to that number of pixels in height while preserving the aspect ratio.

    - width (int | None) – Optional value for the width of the saved images. Specifying both the width and height will resize images to an exact size, regardless of aspect ratio. Specifying only width will rescale the image to that number of pixels wide while preserving the aspect ratio.

    - interpolation (Interpolation) – Type of interpolation to use when resizing images.

    - video_manager – [DEPRECATED] DO NOT USE. For backwards compatibility only.

  Returns:

    [image_paths] }, where scene_num is the number of the scene in scene_list (starting from 1), and image_paths is a list of the paths to the newly saved/created images.

  Return type:

    Dictionary of the format { scene_num

  Raises:

    - ValueError – Raised if any arguments are invalid or out of range (e.g.

    - if num_images is negative). –

scenedetect.scene_manager.write_scene_list(output_csv_file, scene_list, include_cut_list=True, cut_list=None)

  Writes the given list of scenes to an output file handle in CSV format.

  Parameters:

    - output_csv_file (TextIO) – Handle to open file in write mode.

    - scene_list (Iterable[Tuple[FrameTimecode, FrameTimecode]]) – List of pairs of FrameTimecodes denoting each scene’s start/end FrameTimecode.

    - include_cut_list (bool) – Bool indicating if the first row should include the timecodes where each scene starts. Should be set to False if RFC 4180 compliant CSV output is required.

    - cut_list (Iterable[FrameTimecode] | None) – Optional list of FrameTimecode objects denoting the cut list (i.e. the frames in the video that need to be split to generate individual scenes). If not specified, the cut list is generated using the start times of each scene following the first one.

  Return type:

    None

scenedetect.scene_manager.write_scene_list_html(output_html_filename, scene_list, cut_list=None, css=None, css_class='mytable', image_filenames=None, image_width=None, image_height=None)

  Writes the given list of scenes to an output file handle in html format.

  Parameters:

    - output_html_filename – filename of output html file

    - scene_list – List of pairs of FrameTimecodes denoting each scene’s start/end FrameTimecode.

    - cut_list – Optional list of FrameTimecode objects denoting the cut list (i.e. the frames in the video that need to be split to generate individual scenes). If not passed, the start times of each scene (besides the 0th scene) is used instead.

    - css – String containing all the css information for the resulting html page.

    - css_class – String containing the named css class

    - image_filenames – dict where key i contains a list with n elements (filenames of the n saved images from that scene)

    - image_width – Optional desired width of images in table in pixels

    - image_height – Optional desired height of images in table in pixels

scenedetect.scene_manager.DEFAULT_MIN_WIDTH: int = 256

  The default minimum width a frame will be downscaled to when calculating a downscale factor.

scenedetect.scene_manager.MAX_FRAME_QUEUE_LENGTH: int = 4

  Maximum number of decoded frames which can be buffered while waiting to be processed.

scenedetect.scene_manager.PROGRESS_BAR_DESCRIPTION = 'Detected: %d | Progress'

  Template to use for progress bar.

###### Video Splitting

`scenedetect.video_splitter` Module

The scenedetect.video_splitter module contains functions to split existing videos into clips using ffmpeg or mkvmerge.

These programs can be obtained from following URLs (note that mkvmerge is a part mkvtoolnix):

> - FFmpeg: [ https://ffmpeg.org/download.html ]

> - mkvmerge: [ https://mkvtoolnix.download/downloads.html ]

If you are a Linux user, you can likely obtain the above programs from your package manager.

Once installed, ensure the program can be accessed system-wide by calling the mkvmerge or ffmpeg command from a terminal/command prompt. PySceneDetect will automatically use whichever program is available on the computer, depending on the specified command-line options.

scenedetect.video_splitter.is_ffmpeg_available()

  Is ffmpeg Available: Gracefully checks if ffmpeg command is available.

  Returns:

    True if ffmpeg can be invoked, False otherwise.

  Return type:

    bool

scenedetect.video_splitter.is_mkvmerge_available()

  Is mkvmerge Available: Gracefully checks if mkvmerge command is available.

  Returns:

    True if mkvmerge can be invoked, False otherwise.

  Return type:

    bool

scenedetect.video_splitter.split_video_ffmpeg(input_video_path, scene_list, output_file_template='$VIDEO_NAME-Scene-$SCENE_NUMBER.mp4', video_name=None, arg_override='-map 0 -c:v libx264 -preset veryfast -crf 22 -c:a aac', show_progress=False, show_output=False, suppress_output=None, hide_progress=None)

  Calls the ffmpeg command on the input video, generating a new video for each scene based on the start/end timecodes.

  Parameters:

    - input_video_path (str) – Path to the video to be split.

    - scene_list (List[Tuple[FrameTimecode, FrameTimecode]]) – List of scenes (pairs of FrameTimecodes) denoting the start/end frames of each scene.

    - output_file_template (str) – Template to use for generating the output filenames. Can use $VIDEO_NAME and $SCENE_NUMBER in this format, for example: $VIDEO_NAME - Scene $SCENE_NUMBER.mp4

    - video_name (str) – Name of the video to be substituted in output_file_template. If not passed will be calculated from input_video_path automatically.

    - arg_override (str) – Allows overriding the arguments passed to ffmpeg for encoding.

    - show_progress (bool) – If True, will show progress bar provided by tqdm (if installed).

    - show_output (bool) – If True, will show output from ffmpeg for first split.

    - suppress_output – [DEPRECATED] DO NOT USE. For backwards compatibility only.

    - hide_progress – [DEPRECATED] DO NOT USE. For backwards compatibility only.

  Returns:

    Return code of invoking ffmpeg (0 on success). If scene_list is empty, will still return 0, but no commands will be invoked.

scenedetect.video_splitter.split_video_mkvmerge(input_video_path, scene_list, output_file_template='$VIDEO_NAME.mkv', video_name=None, show_output=False, suppress_output=None)

  Calls the mkvmerge command on the input video, splitting it at the passed timecodes, where each scene is written in sequence from 001.

  Parameters:

    - input_video_path (str) – Path to the video to be split.

    - scene_list (Iterable[Tuple[FrameTimecode, FrameTimecode]]) – List of scenes as pairs of FrameTimecodes denoting the start/end times.

    - output_file_template (str) – Template to use for output files. Mkvmerge always adds the suffix “-$SCENE_NUMBER”. Can use $VIDEO_NAME as a template parameter (e.g. “$VIDEO_NAME.mkv”).

    - video_name (str) – Name of the video to be substituted in output_file_template for $VIDEO_NAME. If not specified, will be obtained from the filename.

    - show_output (bool) – If False, adds the –quiet flag when invoking mkvmerge..

    - suppress_output – [DEPRECATED] DO NOT USE. For backwards compatibility only.

  Returns:

    Return code of invoking mkvmerge (0 on success). If scene_list is empty, will still return 0, but no commands will be invoked.

scenedetect.video_splitter.DEFAULT_FFMPEG_ARGS = '-map 0 -c:v libx264 -preset veryfast -crf 22 -c:a aac'

  Default arguments passed to ffmpeg when invoking the split_video_ffmpeg function.

scenedetect.video_splitter.FFMPEG_PATH: str | None = 'ffmpeg'

  Relative path to the Ffmpeg binary on this system, if any (will be None if not available).

scenedetect.video_splitter.TimecodePair

  Named type for pairs of timecodes, which typically represents the start/end of a scene.

  alias of `Tuple`[`FrameTimecode`, `FrameTimecode`]

###### StatsManager

`scenedetect.stats_manager` Module

This module contains the `StatsManager` class, which provides a key-value store for each `SceneDetector` to write the metrics calculated for each frame. The `StatsManager` must be registered to a `SceneManager` upon construction.

The entire `StatsManager` can be `saved to` a human-readable CSV file, allowing for precise determination of the ideal threshold (or other detection parameters) for the given input.

exception scenedetect.stats_manager.FrameMetricNotRegistered(metric_key, message='Attempted to get/set frame metrics for unregistered metric key.')

  Raised when attempting to call get_metrics(…)/set_metrics(…) with a frame metric that does not exist, or has not been registered.

  Parameters:

    - metric_key (str) –

    - message (str) –

exception scenedetect.stats_manager.FrameMetricRegistered(metric_key, message='Attempted to re-register frame metric key.')

  Raised when attempting to register a frame metric key which has already been registered.

  Parameters:

    - metric_key (str) –

    - message (str) –

exception scenedetect.stats_manager.StatsFileCorrupt(message='Could not load frame metric data data from passed CSV file.')

  Raised when frame metrics/stats could not be loaded from a provided CSV file.

  Parameters:

    message (str) –

class scenedetect.stats_manager.StatsManager(base_timecode=None)

  Provides a key-value store for frame metrics/calculations which can be used for two-pass detection algorithms, as well as saving stats to a CSV file.

  Analyzing a statistics CSV file is also very useful for finding the optimal algorithm parameters for certain detection methods. Additionally, the data may be plotted by a graphing module (e.g. matplotlib) by obtaining the metric of interest for a series of frames by iteratively calling get_metrics(), after having called the detect_scenes(…) method on the SceneManager object which owns the given StatsManager instance.

  Only metrics consisting of float or int should be used currently.

  Initialize a new StatsManager.

  Parameters:

    base_timecode (FrameTimecode) – Timecode associated with this object. Must not be None (default value will be removed in a future release).

  get_metrics(frame_number, metric_keys)

    Return the requested statistics/metrics for a given frame.

    Parameters:

      - frame_number (int) – Frame number to retrieve metrics for.

      - metric_keys (List[str]) – A list of metric keys to look up.

    Returns:

      A list containing the requested frame metrics for the given frame number in the same order as the input list of metric keys. If a metric could not be found, None is returned for that particular metric.

    Return type:

      List[Any]

  is_save_required()

    Is Save Required: Checks if the stats have been updated since loading.

    Returns:

      True if there are frame metrics/statistics not yet written to disk, False otherwise.

    Return type:

      bool

  load_from_csv(csv_file)

    [DEPRECATED] DO NOT USE

    Load all metrics stored in a CSV file into the StatsManager instance. Will be removed in a future release after becoming a no-op.

    Parameters:

      csv_file (str | bytes | TextIO) – A file handle opened in read mode (e.g. open(’…’, ‘r’)) or a path as str.

    Returns:

      Number of frames/rows read from the CSV file, or None if the input file was blank or could not be found.

    Return type:

      int or None

    Raises:

      StatsFileCorrupt – Stats file is corrupt and can’t be loaded, or wrong file was specified.

  metrics_exist(frame_number, metric_keys)

    Metrics Exist: Checks if the given metrics/stats exist for the given frame.

    Returns:

      True if the given metric keys exist for the frame, False otherwise.

    Return type:

      bool

    Parameters:

      - frame_number (int) –

      - metric_keys (Iterable[str]) –

  register_metrics(metric_keys)

    Register a list of metric keys that will be used by the detector.

    Used to ensure that multiple detector keys don’t overlap.

    Raises:

      FrameMetricRegistered – A particular metric_key has already been registered/added to the StatsManager. Only if the StatsManager is being used for read-only access (i.e. all frames in the video have already been processed for the given metric_key in the exception) is this behavior desirable.

    Parameters:

      metric_keys (Iterable[str]) –

    Return type:

      None

  save_to_csv(csv_file, base_timecode=None, force_save=True)

    Save To CSV: Saves all frame metrics stored in the StatsManager to a CSV file.

    Parameters:

      - csv_file (str | bytes | TextIO) – A file handle opened in write mode (e.g. open(’…’, ‘w’)) or a path as str.

      - base_timecode (FrameTimecode | None) – [DEPRECATED] DO NOT USE. For backwards compatibility.

      - force_save – If True, writes metrics out even if an update is not required.

    Raises:

      OSError – If path cannot be opened or a write failure occurs.

    Return type:

      None

  set_metrics(frame_number, metric_kv_dict)

    Set Metrics: Sets the provided statistics/metrics for a given frame.

    Parameters:

      - frame_number (int) – Frame number to retrieve metrics for.

      - metric_kv_dict (Dict[str, Any]) – A dict mapping metric keys to the respective integer/floating-point metric values to set.

    Return type:

      None

  static valid_header(row)

    Check that the given CSV row is a valid header for a statsfile.

    Parameters:

      row (List[str]) – A row decoded from the CSV reader.

    Returns:

      True if row is a valid statsfile header, False otherwise.

    Return type:

      bool

scenedetect.stats_manager.COLUMN_NAME_FRAME_NUMBER = 'Frame Number'

  Name of column containing frame numbers in the statsfile CSV.

scenedetect.stats_manager.COLUMN_NAME_TIMECODE = 'Timecode'

  Name of column containing timecodes in the statsfile CSV.

###### FrameTimecode

`scenedetect.frame_timecode` Module

This module implements `FrameTimecode` which is used as a way for PySceneDetect to store frame-accurate timestamps of each cut. This is done by also specifying the video framerate with the timecode, allowing a frame number to be converted to/from a floating-point number of seconds, or string in the form “HH:MM:SS[.nnn]” where the [.nnn] part is optional.

See the following examples, or the `FrameTimecode constructor`.

###### Usage Examples

A `FrameTimecode` can be created by specifying a timecode (int for number of frames, float for number of seconds, or str in the form “HH:MM:SS” or “HH:MM:SS.nnn”) with a framerate:

    frames = FrameTimecode(timecode = 29, fps = 29.97)
    seconds_float = FrameTimecode(timecode = 10.0, fps = 10.0)
    timecode_str = FrameTimecode(timecode = "00:00:10.000", fps = 10.0)

Arithmetic/comparison operations with `FrameTimecode` objects is also possible, and the other operand can also be of the above types:

    x = FrameTimecode(timecode = "00:01:00.000", fps = 10.0)
    # Can add int (frames), float (seconds), or str (timecode).
    print(x + 10)
    print(x + 10.0)
    print(x + "00:10:00")
    # Same for all comparison operators.
    print((x + 10.0) == "00:01:10.000")

`FrameTimecode` objects can be added and subtracted, however the current implementation disallows negative values, and will clamp negative results to 0.

Warning

Be careful when subtracting `FrameTimecode` objects or adding negative amounts of frames/seconds. In the example below, `c` will be at frame 0 since `b > a`, but `d` will be at frame 5:

    a = FrameTimecode(5, 10.0)
    b = FrameTimecode(10, 10.0)
    c = a - b   # b > a, so c == 0
    d = b - a
    assert(c == 0)
    assert(d == 5)

class scenedetect.frame_timecode.FrameTimecode(timecode=None, fps=None)

  Object for frame-based timecodes, using the video framerate to compute back and forth between frame number and seconds/timecode.

  A timecode is valid only if it complies with one of the following three types/formats:

  > 1. Timecode as str in the form ‘HH:MM:SS[.nnn]’ (‘01:23:45’ or ‘01:23:45.678’)

  > 2. Number of seconds as float, or str in form ‘Ss’ or ‘S.SSSs’ (‘2s’ or ‘2.3456s’)

  > 3. Exact number of frames as int, or str in form NNNNN (123 or ‘123’)

  Parameters:

    - timecode (int | float | str | FrameTimecode) – A frame number (int), number of seconds (float), or timecode (str in the form ‘HH:MM:SS’ or ‘HH:MM:SS.nnn’).

    - fps (int | float | str | FrameTimecode) – The framerate or FrameTimecode to use as a time base for all arithmetic.

  Raises:

    - TypeError – Thrown if either timecode or fps are unsupported types.

    - ValueError – Thrown when specifying a negative timecode or framerate.

  equal_framerate(fps)

    Equal Framerate: Determines if the passed framerate is equal to that of this object.

    Parameters:

      fps – Framerate to compare against within the precision constant defined in this module (see `MAX_FPS_DELTA`).

    Returns:

      True if passed fps matches the FrameTimecode object’s framerate, False otherwise.

    Return type:

      bool

  get_framerate()

    Get Framerate: Returns the framerate used by the FrameTimecode object.

    Returns:

      Framerate of the current FrameTimecode object, in frames per second.

    Return type:

      float

  get_frames()

    Get the current time/position in number of frames. This is the equivalent of accessing the self.frame_num property (which, along with the specified framerate, forms the base for all of the other time measurement calculations, e.g. the `get_seconds()` method).

    If using to compare a `FrameTimecode` with a frame number, you can do so directly against the object (e.g. `FrameTimecode(10, 10.0) <= 10`).

    Returns:

      The current time in frames (the current frame number).

    Return type:

      int

  get_seconds()

    Get the frame’s position in number of seconds.

    If using to compare a `FrameTimecode` with a frame number, you can do so directly against the object (e.g. `FrameTimecode(10, 10.0) <= 1.0`).

    Returns:

      The current time/position in seconds.

    Return type:

      float

  get_timecode(precision=3, use_rounding=True)

    Get a formatted timecode string of the form HH:MM:SS[.nnn].

    Parameters:

      - precision (int) – The number of decimal places to include in the output `[.nnn]`.

      - use_rounding (bool) – Rounds the output to the desired precision. If False, the value will be truncated to the specified precision.

    Returns:

      The current time in the form `"HH:MM:SS[.nnn]"`.

    Return type:

      str

  previous_frame()

    Return a new FrameTimecode for the previous frame (or 0 if on frame 0).

    Return type:

      FrameTimecode

scenedetect.frame_timecode.MAX_FPS_DELTA: float = 1e-05

  Maximum amount two framerates can differ by for equality testing.

scenedetect.frame_timecode.TimecodeValue

  Named type for values representing timecodes. Must be in one of the following forms:

  1. Timecode as str in the form ‘HH:MM:SS[.nnn]’ (‘01:23:45’ or ‘01:23:45.678’)

  2. Number of seconds as float, or str in form ‘Ss’ or ‘S.SSSs’ (‘2s’ or ‘2.3456s’)

  3. Exact number of frames as int, or str in form NNNNN (123 or ‘123’)

  alias of `Union`[`int`, `float`, `str`]

###### SceneDetector

`scenedetect.scene_detector` Module

This module contains the `SceneDetector` interface, from which all scene detectors in `scenedetect.detectors` module are derived from.

The SceneDetector class represents the interface which detection algorithms are expected to provide in order to be compatible with PySceneDetect.

Warning

This API is still unstable, and changes and design improvements are planned for the v1.0 release. Instead of just timecodes, detection algorithms will also provide a specific type of event (in, out, cut, etc…).

class scenedetect.scene_detector.SceneDetector

  Base class to inherit from when implementing a scene detection algorithm.

  This API is not yet stable and subject to change.

  This represents a “dense” scene detector, which returns a list of frames where the next scene/shot begins in a video.

  Also see the implemented scene detectors in the scenedetect.detectors module to get an idea of how a particular detector can be created.

  get_metrics()

    Get Metrics: Get a list of all metric names/keys used by the detector.

    Returns:

      List of strings of frame metric key names that will be used by the detector when a StatsManager is passed to process_frame.

    Return type:

      List[str]

  is_processing_required(frame_num)

    [DEPRECATED] DO NOT USE

    Test if all calculations for a given frame are already done.

    Returns:

      False if the SceneDetector has assigned _metric_keys, and the stats_manager property is set to a valid StatsManager object containing the required frame metrics/calculations for the given frame - thus, not needing the frame to perform scene detection.

      True otherwise (i.e. the frame_img passed to process_frame is required to be passed to process_frame for the given frame_num).

    Parameters:

      frame_num (int) –

    Return type:

      bool

  post_process(frame_num)

    Post Process: Performs any processing after the last frame has been read.

    Prototype method, no actual detection.

    Returns:

      List of frame numbers of cuts to be added to the cutting list.

    Parameters:

      frame_num (int) –

    Return type:

      List[int]

  process_frame(frame_num, frame_img)

    Process Frame: Computes/stores metrics and detects any scene changes.

    Prototype method, no actual detection.

    Returns:

      List of frame numbers of cuts to be added to the cutting list.

    Parameters:

      - frame_num (int) –

      - frame_img (ndarray | None) –

    Return type:

      List[int]

  stats_manager_required()

    Stats Manager Required: Prototype indicating if detector requires stats.

    Returns:

      True if a StatsManager is required for the detector, False otherwise.

    Return type:

      bool

  property event_buffer_length: int

    The amount of frames a given event can be buffered for, in time. Represents maximum amount any event can be behind frame_number in the result of `process_frame()`.

  stats_manager: StatsManager | None = None

    Optional `StatsManager` to use for caching frame metrics to and from.

class scenedetect.scene_detector.SparseSceneDetector

  Base class to inheret from when implementing a sparse scene detection algorithm.

  This class will be removed in v1.0 and should not be used.

  Unlike dense detectors, sparse detectors detect “events” and return a pair of frames, as opposed to just a single cut.

  An example of a SparseSceneDetector is the MotionDetector.

  post_process(frame_num)

    Post Process: Performs any processing after the last frame has been read.

    Prototype method, no actual detection.

    Returns:

      List of frame pairs representing individual scenes to be added to the output scene list directly.

    Parameters:

      frame_num (int) –

    Return type:

      List[Tuple[int, int]]

  process_frame(frame_num, frame_img)

    Process Frame: Computes/stores metrics and detects any scene changes.

    Prototype method, no actual detection.

    Returns:

      List of frame pairs representing individual scenes to be added to the output scene list directly.

    Parameters:

      - frame_num (int) –

      - frame_img (ndarray) –

    Return type:

      List[Tuple[int, int]]

###### VideoStream

`scenedetect.video_stream` Module

This module contains the `VideoStream` class, which provides a library agnostic interface for video input. To open a video by path, use `scenedetect.open_video()`:

    from scenedetect import open_video
    video = open_video('video.mp4')
    while True:
        frame = video.read()
        if frame is False:
            break
    print("Read %d frames" % video.frame_number)

You can also optionally specify a framerate and a specific backend library to use. Unless specified, OpenCV will be used as the video backend. See `scenedetect.backends` for a detailed example.

New `VideoStream` implementations can be tested by adding it to the test suite in tests/test_video_stream.py.

exception scenedetect.video_stream.FrameRateUnavailable

  Exception instance to provide consistent error messaging across backends when the video frame rate is unavailable or cannot be calculated. Subclass of VideoOpenFailure.

  Parameters:

    message – Additional context the backend can provide for the open failure.

exception scenedetect.video_stream.SeekError

  Either an unrecoverable error happened while attempting to seek, or the underlying stream is not seekable (additional information will be provided when possible).

  The stream is guaranteed to be left in a valid state, but the position may be reset.

exception scenedetect.video_stream.VideoOpenFailure(message='Unknown backend error.')

  Raised by a backend if opening a video fails.

  Parameters:

    message (str) – Additional context the backend can provide for the open failure.

class scenedetect.video_stream.VideoStream

  Interface which all video backends must implement.

  abstract static BACKEND_NAME()

    Unique name used to identify this backend. Should be a static property in derived classes (BACKEND_NAME = ‘backend_identifier’).

    Return type:

      str

  abstract read(decode=True, advance=True)

    Read and decode the next frame as a numpy.ndarray. Returns False when video ends.

    Parameters:

      - decode (bool) – Decode and return the frame.

      - advance (bool) – Seek to the next frame. If False, will return the current (last) frame.

    Returns:

      If decode = True, the decoded frame (numpy.ndarray), or False (bool) if end of video. If decode = False, a bool indicating if advancing to the the next frame succeeded.

    Return type:

      ndarray | bool

  abstract reset()

    Close and re-open the VideoStream (equivalent to seeking back to beginning).

    Return type:

      None

  abstract seek(target)

    Seek to the given timecode. If given as a frame number, represents the current seek pointer (e.g. if seeking to 0, the next frame decoded will be the first frame of the video).

    For 1-based indices (first frame is frame #1), the target frame number needs to be converted to 0-based by subtracting one. For example, if we want to seek to the first frame, we call seek(0) followed by read(). If we want to seek to the 5th frame, we call seek(4) followed by read(), at which point frame_number will be 5.

    May not be supported on all backend types or inputs (e.g. cameras).

    Parameters:

      target (FrameTimecode | float | int) – Target position in video stream to seek to. If float, interpreted as time in seconds. If int, interpreted as frame number.

    Raises:

      - SeekError – An error occurs while seeking, or seeking is not supported.

      - ValueError – target is not a valid value (i.e. it is negative).

    Return type:

      None

  abstract property aspect_ratio: float

    Pixel aspect ratio as a float (1.0 represents square pixels).

  property base_timecode: FrameTimecode

    FrameTimecode object to use as a time base.

  abstract property duration: FrameTimecode | None

    Duration of the stream as a FrameTimecode, or None if non terminating.

  abstract property frame_number: int

    Current position within stream as the frame number.

    Will return 0 until the first frame is read.

  abstract property frame_rate: float

    Frame rate in frames/sec.

  abstract property frame_size: Tuple[int, int]

    Size of each video frame in pixels as a tuple of (width, height).

  abstract property is_seekable: bool

    True if seek() is allowed, False otherwise.

  abstract property name: bytes | str

    Name of the video, without extension, or device.

  abstract property path: bytes | str

    Video or device path.

  abstract property position: FrameTimecode

    Current position within stream as FrameTimecode.

    This can be interpreted as presentation time stamp, thus frame 1 corresponds to the presentation time 0. Returns 0 even if frame_number is 1.

  abstract property position_ms: float

    Current position within stream as a float of the presentation time in milliseconds. The first frame has a PTS of 0.

###### Platform & Logging

`scenedetect.platform` Module

This moduke contains all platform/library specific compatibility fixes, as well as some utility functions to handle logging and invoking external commands.

exception scenedetect.platform.CommandTooLong

  Raised if the length of a command line argument exceeds the limit allowed on Windows.

class scenedetect.platform.FakeTqdmLoggingRedirect(**kawrgs)

  Provides a no-op tqdm context manager for redirecting log messages.

  No-op.

class scenedetect.platform.FakeTqdmObject(**kawrgs)

  Provides a no-op tqdm-like object.

  No-op.

  close()

    No-op.

  set_description(desc=None, refresh=True)

    No-op.

  update(n=1)

    No-op.

class scenedetect.platform.Template(template)

  Template matcher used to replace instances of $TEMPLATES in filenames.

scenedetect.platform.get_and_create_path(file_path, output_directory=None)

  Get & Create Path: Gets and returns the full/absolute path to file_path in the specified output_directory if set, creating any required directories along the way.

  If file_path is already an absolute path, then output_directory is ignored.

  Parameters:

    - file_path (AnyStr) – File name to get path for. If file_path is an absolute path (e.g. starts at a drive/root), no modification of the path is performed, only ensuring that all output directories are created.

    - output_dir – An optional output directory to override the directory of file_path if it is relative to the working directory.

    - output_directory (AnyStr | None) –

  Returns:

    Full path to output file suitable for writing.

  Return type:

    AnyStr

scenedetect.platform.get_cv2_imwrite_params()

  Get OpenCV imwrite Params: Returns a dict of supported image formats and their associated quality/compression parameter index, or None if that format is not supported.

  Returns:

    Dictionary of supported image formats/extensions (‘jpg’, ‘png’, etc…) mapped to the respective OpenCV quality or compression parameter as {‘jpg’: cv2.IMWRITE_JPEG_QUALITY, ‘png’: cv2.IMWRITE_PNG_COMPRESSION, …}. Parameter will be None if not found on the current system library (e.g. {‘jpg’: None}).

  Return type:

    Dict[str, int | None]

scenedetect.platform.get_ffmpeg_path()

  Get path to ffmpeg if available on the current system. First looks at PATH, then checks if one is available from the imageio_ffmpeg package. Returns None if ffmpeg couldn’t be found.

  Return type:

    str | None

scenedetect.platform.get_ffmpeg_version()

  Get ffmpeg version identifier, or None if ffmpeg is not found. Uses get_ffmpeg_path().

  Return type:

    str | None

scenedetect.platform.get_file_name(file_path, include_extension=True)

  Return the file name that file_path refers to, optionally removing the extension.

  If include_extension is False, the result will always be a str.

  E.g. /tmp/foo.bar -> foo

  Parameters:

    file_path (AnyStr) –

  Return type:

    AnyStr

scenedetect.platform.get_mkvmerge_version()

  Get mkvmerge version identifier, or None if mkvmerge is not found in PATH.

  Return type:

    str | None

scenedetect.platform.get_system_version_info()

  Get the system’s operating system, Python, packages, and external tool versions. Useful for debugging or filing bug reports.

  Used for the scenedetect version -a command.

  Return type:

    str

scenedetect.platform.init_logger(log_level=20, show_stdout=False, log_file=None)

  Initializes logging for PySceneDetect. The logger instance used is named ‘pyscenedetect’. By default the logger has no handlers to suppress output. All existing log handlers are replaced every time this function is invoked.

  Parameters:

    - log_level (int) – Verbosity of log messages. Should be one of [logging.INFO, logging.DEBUG, logging.WARNING, logging.ERROR, logging.CRITICAL].

    - show_stdout (bool) – If True, add handler to show log messages on stdout (default: False).

    - log_file (str | None) – If set, add handler to dump debug log messages to given file path.

scenedetect.platform.invoke_command(args)

  Same as calling Python’s subprocess.call() method, but explicitly raises a different exception when the command length is too long.

  See https://github.com/Breakthrough/PySceneDetect/issues/164 for details.

  Parameters:

    args (List[str]) – List of strings to pass to subprocess.call().

  Returns:

    Return code of command.

  Raises:

    CommandTooLong – args exceeds built in command line length limit on Windows.

  Return type:

    int

##### Logging

PySceneDetect outputs messages to a logger named `pyscenedetect` which does not have any default handlers. You can use `scenedetect.init_logger` with `show_stdout=True` or specify a log file (verbosity can also be specified) to attach some common handlers, or use `logging.getLogger('pyscenedetect')` and attach log handlers manually.

##### Migrating From 0.5

PySceneDetect 0.6 introduces several breaking changes which are incompatible with 0.5. See Migration Guide for details on how to update your application. In addition, demonstrations of common use cases can be found in the tests/test_api.py file.

#### Migration Guide

This page details how to transition a program written using PySceneDetect 0.5 to the new 0.6 API. It is recommended to review the new Quickstart and Example sections first, as they should cover the majority of use cases. Also see tests/test_api.py for a set of demonstrations covering many high level use cases.

PySceneDetect v0.6 is a major step towards a more stable and simplified API. The biggest change to existing workflows is how video input is handled, and that Python 3.6 or above is now required.

This page covers commonly used APIs which require updates to work with v0.6. Note that this page is not an exhaustive set of changes. For a complete list of breaking API changes, see the changelog.

In some places, a backwards compatibility layer has been added to avoid breaking most applications upon release. This should not be relied upon, and will be removed in the future. You can call `scenedetect.platform.init_logger(show_stdout=True)` or attach a custom log handler to the `'pyscenedetect'` logger to help find these cases.

##### VideoManager Class

VideoManager has been deprecated and replaced with `scenedetect.backends`. For most applications, the `open_video` function should be used instead:

    from scenedetect import open_video
    video = open_video(video.mp4')

The resulting object can then be passed to a `SceneManager` when calling `detect_scenes`, or any other function/method that used to take a VideoManager, e.g.:

    from scenedetect import open_video, SceneManager, ContentDetector
    video = open_video('video.mp4')
    scene_manager = SceneManager()
    scene_manager.add_detector(ContentDetector(threshold=threshold))
    scene_manager.detect_scenes(video)
    print(scene_manager.get_scene_list())

See `scenedetect.backends` for examples of how to create specific backends. Where previously a list of paths was accepted, now only a single string should be provided.

###### Seeking and Start/End Times

Instead of setting the start time via the VideoManager, now `seek` to the starting time on the `VideoStream` object.

Instead of setting the duration or end time via the VideoManager, now set the duration or end_time parameters when calling `detect_scenes`.

    from scenedetect import open_video, SceneManager, ContentDetector
    video = open_video('video.mp4')
    # Can be seconds (float), frame # (int), or FrameTimecode
    start_time, end_time = 2.5, 5.0
    scene_manager = SceneManager()
    scene_manager.add_detector(ContentDetector(threshold=threshold))
    video.seek(start_time)
    # Note there is also a `duration` parameter that can also be set.
    # If neither `duration` nor `end_time` is provided, the video will
    # be processed from its current position until the end.
    scene_manager.detect_scenes(video, end_time=end_time)
    print(scene_manager.get_scene_list())

##### SceneManager Class

The first argument of the `detect_scenes` method has been renamed to video and should now be a `VideoStream` object (see above).

##### save_images Function

The second argument of `save_images` in `scenedetect.scene_manager` has been renamed from video_manager to video.

The downscale_factor parameter has been removed from `save_images` (use the scale parameter instead). To achieve the same result as the previous version, set scale to 1.0 / downscale_factor.

##### split_video_* Functions

The the `scenedetect.video_splitter` functions `split_video_ffmpeg` and `split_video_mkvmerge` now only accept a single path as the input (first) argument.

The suppress_output and hide_progress arguments to the `split_video_ffmpeg` and `split_video_mkvmerge` have been removed, and two new options have been added:

> - suppress_output is now show_output, default is False

> - hide_progress is now show_progress, default is False

This makes the API consistent with that of `SceneManager`.

##### StatsManager Class

The `save_to_csv` and `load_from_csv` methods now accept either a path or an open file handle.

The base_timecode argument has been removed from `save_to_csv`. It is no longer required.

##### AdaptiveDetector Class

The video_manager parameter has been removed and is no longer required when constructing an `AdaptiveDetector` object.

##### Other

###### ThresholdDetector Class

The block_size argument has been removed from the `ThresholdDetector` constructor. It is no longer required.

###### ContentDetector Class

The calculate_frame_score method of `ContentDetector` has been renamed to `_calculate_frame_score`. Use new global function `calculate_frame_score` to achieve the same result.

###### MINIMUM_FRAMES_PER_SECOND_* Constants

In `scenedetect.frame_timecode` the constants MINIMUM_FRAMES_PER_SECOND_FLOAT and MINIMUM_FRAMES_PER_SECOND_DELTA_FLOAT have been replaced with `MAX_FPS_DELTA`.

###### get_aspect_ratio Function

> The get_aspect_ratio function has been removed from scenedetect.platform. Use the `aspect_ratio` property from the `VideoStream` object instead.

### Indices and Tables

- Index

- Module Index

- Search Page