2525"""
2626
2727import typing as ty
28+ from abc import ABC , abstractmethod
2829from enum import Enum
2930
3031import numpy
3334from scenedetect .stats_manager import StatsManager
3435
3536
36- class SceneDetector :
37+ class SceneDetector ( ABC ) :
3738 """Base class to inherit from when implementing a scene detection algorithm.
3839
3940 This API is not yet stable and subject to change.
4041 """
4142
42- # TODO(v0.7): Make this a proper abstract base class.
43+ def __init__ (self ):
44+ self ._stats_manager : ty .Optional [StatsManager ] = None
4345
44- # TODO(v0.7): This should be a property.
45- stats_manager : ty .Optional [StatsManager ] = None
46- """Optional :class:`StatsManager <scenedetect.stats_manager.StatsManager>` to
47- use for caching frame metrics to and from."""
48-
49- def stats_manager_required (self ) -> bool :
50- """Stats Manager Required: Prototype indicating if detector requires stats.
51-
52- Returns:
53- True if a StatsManager is required for the detector, False otherwise.
54- """
55- return False
56-
57- def get_metrics (self ) -> ty .List [str ]:
58- """Returns a list of all metric names/keys used by this detector.
59-
60- Returns:
61- List of strings of frame metric key names that will be used by
62- the detector when a StatsManager is passed to process_frame.
63- """
64- return []
46+ # Required Methods
6547
48+ @abstractmethod
6649 def process_frame (
6750 self , timecode : FrameTimecode , frame_img : numpy .ndarray
6851 ) -> ty .List [FrameTimecode ]:
@@ -75,7 +58,8 @@ def process_frame(
7558 Returns:
7659 List of timecodes where scene cuts have been detected, if any.
7760 """
78- return []
61+
62+ # Optional Methods
7963
8064 def post_process (self , timecode : int ) -> ty .List [FrameTimecode ]:
8165 """Called after there are no more frames to process.
@@ -95,6 +79,30 @@ def event_buffer_length(self) -> int:
9579 """
9680 return 0
9781
82+ # Frame Stats/Metrics
83+
84+ @property
85+ def stats_manager (self ) -> ty .Optional [StatsManager ]:
86+ """Optional :class:`StatsManager <scenedetect.stats_manager.StatsManager>` to use for
87+ storing frame metrics. When this detector is added to a parent
88+ :class:`SceneManager <scenedetect.scene_manager.SceneManager>`, then this is set to the
89+ same :class:`StatsManager <scenedetect.stats_manager.StatsManager>` of the parent - but
90+ only if it has one itself."""
91+ return self ._stats_manager
92+
93+ @stats_manager .setter
94+ def stats_manager (self , value : ty .Optional [StatsManager ]):
95+ self ._stats_manager = value
96+
97+ def get_metrics (self ) -> ty .List [str ]:
98+ """Returns a list of all metric names/keys used by this detector.
99+
100+ Returns:
101+ List of strings of frame metric key names that will be used by
102+ the detector when a StatsManager is passed to process_frame.
103+ """
104+ return []
105+
98106
99107class FlashFilter :
100108 """Filters fast-cuts to enforce minimum scene length."""
0 commit comments