The SceneManager facilitates detection of scenes (:meth:`detect_scenes`) on a video (:class:`VideoStream `) using a detector (:meth:`add_detector`). Video decoding is done in parallel in a background thread.
| 188 | |
| 189 | |
| 190 | class SceneManager: |
| 191 | """The SceneManager facilitates detection of scenes (:meth:`detect_scenes`) on a video |
| 192 | (:class:`VideoStream <scenedetect.video_stream.VideoStream>`) using a detector |
| 193 | (:meth:`add_detector`). Video decoding is done in parallel in a background thread. |
| 194 | """ |
| 195 | |
| 196 | def __init__( |
| 197 | self, |
| 198 | stats_manager: StatsManager | None = None, |
| 199 | ): |
| 200 | """ |
| 201 | Arguments: |
| 202 | stats_manager: :class:`StatsManager` to bind to this `SceneManager`. Can be |
| 203 | accessed via the `stats_manager` property of the resulting object to save to disk. |
| 204 | """ |
| 205 | self._cutting_list: list[FrameTimecode] = [] |
| 206 | self._detector_list: list[SceneDetector] = [] |
| 207 | # TODO(v1.0): This class should own a StatsManager instead of taking an optional one. |
| 208 | # Expose a new `stats_manager` @property from the SceneManager, and either change the |
| 209 | # `stats_manager` argument to to `store_stats: bool=False`, or lazy-init one. |
| 210 | |
| 211 | # TODO(v1.0): This class should own a VideoStream as well, instead of passing one |
| 212 | # to the detect_scenes method. If concatenation is required, it can be implemented as |
| 213 | # a generic VideoStream wrapper. |
| 214 | self._stats_manager: StatsManager | None = stats_manager |
| 215 | |
| 216 | # Position of video that was first passed to detect_scenes. |
| 217 | self._start_pos: FrameTimecode | None = None |
| 218 | # Position of video on the last frame processed by detect_scenes. |
| 219 | self._last_pos: FrameTimecode | None = None |
| 220 | # Size of the decoded frames. |
| 221 | self._frame_size: tuple[int, int] | None = None |
| 222 | self._frame_size_errors: int = 0 |
| 223 | self._base_timecode: FrameTimecode | None = None |
| 224 | self._downscale: int = 1 |
| 225 | self._auto_downscale: bool = True |
| 226 | # Interpolation method to use when downscaling. Defaults to linear interpolation |
| 227 | # as a good balance between quality and performance. |
| 228 | self._interpolation: Interpolation = Interpolation.LINEAR |
| 229 | # Set by decode thread when an exception occurs. |
| 230 | self._exception_info = None |
| 231 | self._stop = threading.Event() |
| 232 | |
| 233 | self._frame_buffer: list[tuple[FrameTimecode, np.ndarray]] = [] |
| 234 | self._frame_buffer_size = 0 |
| 235 | self._crop = None |
| 236 | |
| 237 | @property |
| 238 | def interpolation(self) -> Interpolation: |
| 239 | """Interpolation method to use when downscaling frames. Must be one of cv2.INTER_*.""" |
| 240 | return self._interpolation |
| 241 | |
| 242 | @interpolation.setter |
| 243 | def interpolation(self, value: Interpolation): |
| 244 | self._interpolation = value |
| 245 | |
| 246 | @property |
| 247 | def stats_manager(self) -> StatsManager | None: |
no outgoing calls