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 overridden 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 (-m=2.5
), 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 (--start=100.0
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]
# By default, list-scenes will create a CSV file. Enable this option
# to suppress creating the CSV file.
#no-output-file = no
# Folder to output scene list. Overrides [global] output option.
#output = /usr/tmp/images
# Filename format to use when saving scene list. $VIDEO_NAME can be used to
# represent the name of the video being processed.
#filename = $VIDEO_NAME-Scenes.csv
# Display a table with the start/end boundaries for each scene (yes/no).
#display-scenes = yes
# Display list of cut points generated from scene boundaries (yes/no).
#display-cuts = yes
# Format to use for list of cut points (frames, seconds, timecode).
#cut-format = timecode
# Skip writing cut points as the first row in the CSV file (yes/no).
# Set for RFC 4180 compliance.
#skip-cuts = no
# Suppress all display output of list-scenes command.
# Overrides `display-scenes` and `display-cuts`.
#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
.
Note that the scenedetect command output is generated as a post-processing step, after scene detection completes. Most commands require the ability for the input to be replayed, and preferably it should also support seeking. Network streams and other input types are supported with certain backends, however integration with live streams requires use of the Python API.
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.
MoviePy¶
MoviePy launches ffmpeg as a subprocess, and can be used with various types of inputs. If the input supports seeking it should work fine with most operations, for example, image sequences or AviSynth scripts.
Warning
The MoviePy backend is still under development and is not included with current Windows distribution. To enable MoviePy support, you must install PySceneDetect using python and pip.
This backend can be used by specifying -b moviepy
via command line, or setting backend = moviepy
under the [global]
section of your config file.
scenedetect
Python Module 🐍¶
scenedetect
🎬 Package¶
Overview¶
The scenedetect API is easy to integrate with most application workflows, while also being highly extensible. See the Quickstart and Example sections below for some common use cases and integrations. The scenedetect package contains several modules:
scenedetect.scene_manager 🎞️: The
SceneManager
acts as a way to coordinate detecting scenes (via SceneDetector instances) on video frames (via VideoStream instances). This module also contains functionality to export information about scenes in various formats:save_images
to save images for each scene,write_scene_list
to save scene/cut info as CSV, andwrite_scene_list_html
to export scenes in viewable HTML format.scenedetect.detectors 🕵️: 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 🎥: Video input is handled through the
VideoStream
interface. Implementations for common video libraries are provided inscenedetect.backends
:
OpenCV:
VideoStreamCv2
PyAV:
VideoStreamAv
MoviePy:
VideoStreamMoviePy
scenedetect.video_splitter ✂️: Contains
split_video_ffmpeg
andsplit_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
interface which detection algorithms must implement.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 seconds123.45
(float), or number of frames200
(int).end_time (str | float | int | None) – Starting point in video, in the form of a timecode
HH:MM:SS[.nnn]
(str), number of seconds123.45
(float), or number of frames200
(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:
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.
The difference is calculated in the HSV color space, and compared against a set threshold to determine when a fast cut has occurred.
- 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)¶
Process the next frame. frame_num is assumed to be sequential.
- Parameters:
frame_num (int) – Frame number of frame that is being passed. Can start from any value but must remain sequential.
frame_img (numpy.ndarray or None) – Video frame corresponding to frame_img.
- 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)¶
Process the next frame. frame_num is assumed to be sequential.
- Parameters:
frame_num (int) – Frame number of frame that is being passed. Can start from any value but must remain sequential.
frame_img (numpy.ndarray or None) – Video frame corresponding to frame_img.
- 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]
- 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)¶
Process the next frame. frame_num is assumed to be sequential.
- Parameters:
frame_num (int) – Frame number of frame that is being passed. Can start from any value but must remain sequential.
frame_img (numpy.ndarray or None) – Video frame corresponding to frame_img.
- 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] = {'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 np.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 (np.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¶
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]¶
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 np.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 (np.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.
- 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 np.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 (np.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.
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()
orget_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 default 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.
- class scenedetect.video_splitter.SceneMetadata(index, start, end)¶
Information about the scene being extracted.
- Parameters:
index (int) –
start (FrameTimecode) –
end (FrameTimecode) –
- end: FrameTimecode¶
Last frame.
- index: int¶
0-based index of this scene.
- start: FrameTimecode¶
First frame.
- class scenedetect.video_splitter.VideoMetadata(name, path, total_scenes)¶
Information about the video being split.
- Parameters:
name (str) –
path (Path) –
total_scenes (int) –
- name: str¶
Expected name of the video. May differ from path.
- path: Path¶
Path to the input file.
- total_scenes: int¶
Total number of scenes that will be written.
- scenedetect.video_splitter.default_formatter(template)¶
Formats filenames using a template string which allows the following variables:
$VIDEO_NAME, $SCENE_NUMBER, $START_TIME, $END_TIME, $START_FRAME, $END_FRAME
- Parameters:
template (str) –
- Return type:
Callable[[VideoMetadata, SceneMetadata], AnyStr]
- 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_dir=None, 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, formatter=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[ty.Tuple[FrameTimecode, FrameTimecode]]) – List of scenes (pairs of FrameTimecodes) denoting the start/end frames of each scene.
output_dir (Path | None) – Directory to output videos. If not set, output will be in working directory.
output_file_template (str) – Template to use for generating output filenames. The following variables will be replaced in the template for each scene: $VIDEO_NAME, $SCENE_NUMBER, $START_TIME, $END_TIME, $START_FRAME, $END_FRAME
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.
formatter (Callable[[VideoMetadata, SceneMetadata], AnyStr] | None) – Custom formatter callback. Overrides output_file_template.
- Returns:
Return code of invoking ffmpeg (0 on success). If scene_list is empty, will still return 0, but no commands will be invoked.
- Return type:
int
- scenedetect.video_splitter.split_video_mkvmerge(input_video_path, scene_list, output_dir=None, 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_dir (Path | None) – Directory to output videos. If not set, output will be in working directory.
output_file_template (str) – Template to use for generating output files. Note that mkvmerge always adds the suffix “-$SCENE_NUMBER” to the output paths. Only the $VIDEO_NAME variable is supported by this function.
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.
- Return type:
int
- 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 = None¶
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¶
[DEPRECATED - DO NOT USE] No longer used.
- exception scenedetect.stats_manager.FrameMetricRegistered¶
[DEPRECATED - DO NOT USE] No longer used.
- 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.
- 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:
Timecode as str in the form “HH:MM:SS[.nnn]” (“01:23:45” or “01:23:45.678”)
Number of seconds as float, or str in form “SSSS.nnnn” (“45.678”)
Exact number of frames as int, or str in form NNNNN (456 or “456”)
- 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:
- scenedetect.frame_timecode.MAX_FPS_DELTA: float = 1e-05¶
Maximum amount two framerates can differ by for equality testing.
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 the next frame. frame_num is assumed to be sequential.
- Parameters:
frame_num (int) – Frame number of frame that is being passed. Can start from any value but must remain sequential.
frame_img (numpy.ndarray or None) – Video frame corresponding to frame_img.
- 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]
- Returns:
List of frame numbers of cuts to be added to the cutting list.
- 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 inherit 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 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 np.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 (np.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 theVideoStream
object instead.