Add any cuts detected with the current frame to the cutting list. Returns True if any new cuts were detected, False otherwise.
(
self,
position: FrameTimecode,
frame_im: np.ndarray,
callback: ty.Callable[[np.ndarray, FrameTimecode], None] | None = None,
)
| 380 | return [cut for cut in sorted(set(self._cutting_list))] |
| 381 | |
| 382 | def _process_frame( |
| 383 | self, |
| 384 | position: FrameTimecode, |
| 385 | frame_im: np.ndarray, |
| 386 | callback: ty.Callable[[np.ndarray, FrameTimecode], None] | None = None, |
| 387 | ) -> bool: |
| 388 | """Add any cuts detected with the current frame to the cutting list. Returns True if any new |
| 389 | cuts were detected, False otherwise.""" |
| 390 | new_cuts = False |
| 391 | # TODO(https://scenedetect.com/issues/283): This breaks with AdaptiveDetector as cuts differ |
| 392 | # from the frame number being processed. Allow detectors to specify the max frame lookahead |
| 393 | # they require (i.e. any event will never be more than N frames behind the current one). |
| 394 | self._frame_buffer.append((position, frame_im)) |
| 395 | # frame_buffer[-1] is current frame, -2 is one behind, etc |
| 396 | # so index based on cut frame should be [event_frame - (frame_num + 1)] |
| 397 | self._frame_buffer = self._frame_buffer[-(self._frame_buffer_size + 1) :] |
| 398 | for detector in self._detector_list: |
| 399 | cuts = detector.process_frame(position, frame_im) |
| 400 | self._cutting_list += cuts |
| 401 | new_cuts = bool(cuts) |
| 402 | if callback: |
| 403 | for cut in cuts: |
| 404 | for position, frame in self._frame_buffer: |
| 405 | if cut == position: |
| 406 | callback(frame, position) |
| 407 | return new_cuts |
| 408 | |
| 409 | def _post_process(self, timecode: FrameTimecode) -> None: |
| 410 | """Add remaining cuts to the cutting list, after processing the last frame.""" |
no test coverage detected