Scene Manager

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.

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.SceneManager(stats_manager=None)

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

Parameters:

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

add_detector(detector)

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

Parameters:

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

Return type:

None

clear()

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

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

Return type:

None

clear_detectors()

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

Return type:

None

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

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

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

Parameters:
  • video (VideoStream) – 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:

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

get_num_detectors()

Get number of registered scene detectors added via add_detector.

Return type:

int

get_scene_list(start_in_scene=False)

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

Parameters:

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 crop: Tuple[int, int, int, int] | None

Portion of the frame to crop. Tuple of 4 ints in the form (X0, Y0, X1, Y1) where X0, Y0 describes one point and X1, Y1 is another which describe a rectangle inside of the frame. Coordinates start from 0 and are inclusive. For example, with a 100x100 pixel video, (0, 0, 99, 99) covers the entire frame.

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)

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 (List[FrameTimecode]) – List of FrameTimecode objects where scene cuts/breaks occur.

  • 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.

  • 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.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.MAX_FRAME_SIZE_ERRORS: int = 16

Maximum number of frame size error messages that can be logged.

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

Template to use for progress bar.