SceneManager

scenedetect.scene_manager Module

This module implements the SceneManager object, which is used to coordinate SceneDetectors and frame sources (VideoStream). This includes creating a cut list (see SceneManager.get_cut_list()) and event list (see SceneManager.get_event_list()) of all changes in scene, which is used to generate a final list of scenes (see SceneManager.get_scene_list()) in the form of a list of start/end FrameTimecode objects at each scene boundary. Decoding of video frames is performed in a separate thread to improve parallelism.

The FrameTimecode objects and tuples thereof returned by get_cut_list and get_scene_list, respectively, can be sorted if for some reason the scene (or cut) list becomes unsorted. The SceneManager also facilitates passing a scenedetect.stats_manager.StatsManager, if any is defined, to the associated scenedetect.scene_detector.SceneDetector objects for caching of frame metrics.

This speeds up subsequent calls to the SceneManager.detect_scenes() method that process the same frames with the same detection algorithm, even if different threshold values (or other algorithm options) are used.

Usage Example

In the code example below, we create a function find_scenes() which performs the following actions:

  • loads a video file by path (str) using scenedetect.open_video()

  • loads/saves a stats file for the video to {video_path}.stats.csv using a StatsManager

  • performs content-aware scene detection on the video using a ContentDetector bound to a SceneManager

  • print() out a table of detected scenes to the terminal/console

  • returns a list of tuples of FrameTimecode objects of the start and end times for each detected scene

This example is a modified version of the api_test.py file, and shows complete usage of a SceneManager object to perform content-aware scene detection using the ContentDetector, printing a list of scenes, then saving the calculated per-frame metrics to disk:

import os

from scenedetect import open_video, ContentDetector, SceneManager, StatsManager

def find_scenes(video_path):
    # type: (str) -> List[Tuple[FrameTimecode, FrameTimecode]]

    video_stream = open_video(video_path)
    stats_manager = StatsManager()
    # Construct our SceneManager and pass it our StatsManager.
    scene_manager = SceneManager(stats_manager)

    # Add ContentDetector algorithm (each detector's constructor
    # takes various options, e.g. threshold).
    scene_manager.add_detector(ContentDetector())

    # Save calculated metrics for each frame to {VIDEO_PATH}.stats.csv.
    stats_file_path = '%s.stats.csv' % video_path

    # Perform scene detection.
    scene_manager.detect_scenes(video=video_stream)
    scene_list = scene_manager.get_scene_list()
    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(),))

    # Store the frame metrics we calculated for the next time the program runs.
    stats_manager.save_to_csv(csv_file=stats_file_path, base_timecode=base_timecode)

    return scene_list

The statsfile can be used to find a better threshold for certain inputs, or perform further statistical analysis. The use of a StatsManager also allows certain detectors to operate faster on subsequent passes by caching calculations. Statsfiles can be persisted on disk and loaded again, which helps avoid unnecessary calculations in applications where multiple passes are expected (e.g. interactively selecting a threshold).

SceneManager Class

class scenedetect.scene_manager.SceneManager(stats_manager=None)

The SceneManager facilitates detection of scenes via the detect_scenes() method, given a video source (VideoStream), and SceneDetector algorithms added via the add_detector() method. Scene detection is performed in parallel with decoding the video by reading frames from the VideoStream in a background thread.

Parameters

stats_manager (Optional[StatsManager]) – StatsManager to bind to this SceneManager. Can be accessed via the stats_manager property of the resulting object to load from or save to a file on disk.

add_detector(detector)

Adds/registers 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

property auto_downscale: bool

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

Overrides downscale if set.

clear()

Clears 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()

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

Blocks until all frames in the video have been processed. Results can be obtained by calling either the get_scene_list() or get_cut_list() methods. Video decoding is performed in a background thread to allow scene detection and frame decoding to happen in parallel.

Parameters
  • video (Optional[VideoStream]) – VideoStream obtained from either scenedetect.open_video, or by creating one directly (e.g. scenedetect.backends.opencv.VideoStreamCv2).

  • duration (Optional[FrameTimecode]) – Maximum amount of frames to detect. If not specified, stream will be processed until end. Cannot be specified if end_time is set.

  • end_time (Optional[FrameTimecode]) – Last frame number to process. If not specified, stream will be processed until end. 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 (Optional[Callable[[ndarray, int], None]]) – If set, called after each scene/event detected.

  • frame_source (Optional[VideoStream]) – [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.

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.

get_cut_list(base_timecode=None)

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

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.

Parameters

base_timecode (Optional[FrameTimecode]) –

Return type

List[FrameTimecode]

get_event_list(base_timecode=None)

Returns a list of FrameTimecode pairs of the detected scenes by all sparse detectors.

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.

Returns

List of pairs of FrameTimecode objects denoting the detected scenes.

Parameters

base_timecode (Optional[FrameTimecode]) –

Return type

List[Tuple[FrameTimecode, FrameTimecode]]

get_num_detectors()

Gets number of registered scene detectors added via add_detector.

Return type

int

get_scene_list(base_timecode=None, start_in_scene=False)

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

The scene list is generated by combining the results of all sparse detectors with those from dense ones (i.e. combining the results of get_cut_list() and get_event_list()).

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.

Parameters
  • base_timecode (Optional[FrameTimecode]) –

  • start_in_scene (bool) –

Return type

List[Tuple[FrameTimecode, FrameTimecode]]

property stats_manager: Optional[scenedetect.stats_manager.StatsManager]

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

scene_manager Functions

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, 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 (Optional[str]) – Directory to output the images into. If not set, the output is created in the working directory.

  • show_progress (Optional[bool]) – If True, shows a progress bar if tqdm is installed.

  • scale (Optional[float]) – 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 (Optional[int]) – 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 (Optional[int]) – 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.

  • 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 (Optional[Iterable[FrameTimecode]]) – 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.get_scenes_from_cuts(cut_list, base_timecode, 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 (Iterable[FrameTimecode]) – List of FrameTimecode objects where scene cuts/breaks occur.

  • base_timecode (FrameTimecode) – 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.

  • start_pos (Union[int, FrameTimecode]) –

  • end_pos (Union[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]]