Skip to content

detect_scenes seems to fail when used with callback #416

Closed

Description

Description:

After running for about 1/3 of the video, the code throws the following unexpected exception. The same run works fine if the callback on detect_scenes is removed.

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[20], line 9
      6 def on_new_scene(frame_img: np.ndarray, frame_num: int):
      7     print(frame_num, video.duration.get_frames())
----> 9 scene_manager.detect_scenes(video, callback=on_new_scene)
     11 scene_manager.get_scene_list()

File ~/anaconda3/envs/jupyter/lib/python3.10/site-packages/scenedetect/scene_manager.py:889, in SceneManager.detect_scenes(self, video, duration, end_time, frame_skip, show_progress, callback, frame_source)
    887 if not next_frame is None:
    888     frame_im = next_frame
--> 889 new_cuts = self._process_frame(position.frame_num, frame_im, callback)
    890 if progress_bar is not None:
    891     if new_cuts:

File ~/anaconda3/envs/jupyter/lib/python3.10/site-packages/scenedetect/scene_manager.py:762, in SceneManager._process_frame(self, frame_num, frame_im, callback)
    760         for cut_frame_num in cuts:
    761             buffer_index = cut_frame_num - (frame_num + 1)
--> 762             callback(self._frame_buffer[buffer_index], cut_frame_num)
    763 for detector in self._sparse_detector_list:
    764     events = detector.process_frame(frame_num, frame_im)

IndexError: list index out of range

Example:

Include code samples that demonstrate the issue:

import scenedetect
import numpy as np

scene_manager = scenedetect.SceneManager()
scene_manager.add_detector(scenedetect.ContentDetector())

def on_new_scene(frame_img: np.ndarray, frame_num: int):
    print(frame_num, video.duration.get_frames())

scene_manager.detect_scenes(video, callback=on_new_scene)

scene_manager.get_scene_list()

Environment:

[PySceneDetect] PySceneDetect 0.6.4

System Info
------------------------------------------------------------
OS           Linux-5.15.0-119-generic-x86_64-with-glibc2.35
Python       3.10.14

Packages
------------------------------------------------------------
av           12.0.0
click        8.1.7
cv2          4.9.0
moviepy      Not Installed
numpy        1.26.4
platformdirs 3.10.0
scenedetect  0.6.4
tqdm         4.66.2

Tools
------------------------------------------------------------
ffmpeg       4.3
mkvmerge     Not Installed

Media/Files:

I cannot share the video file, but it is similar to this one: https://www.youtube.com/watch?app=desktop&v=2JIfwsv28Es

Activity

  1. added this to the 0.6.5 milestone on Sep 3, 2024
  2. Breakthrough commented on Sep 3, 2024

    @Breakthrough
    Owner

    Thanks for sharing this, there's definitely a bug here. Will look into this as soon as possible.

    I suspect the fix will be closely tied with resolving #408.

  3. Breakthrough commented on Sep 3, 2024

    @Breakthrough
    Owner

    Sorry this is unrelated to that actually. The issue is that with the new flash filter, ContentDetector isn't reporting the correct event buffer size. Will have this fixed for the next release, sorry for the troubles. In the meantime here's a few workarounds.

    Workarounds

    Use AdaptiveDetector instead:

    import scenedetect
    import numpy as np
    
    scene_manager = scenedetect.SceneManager()
    scene_manager.add_detector(scenedetect.AdaptiveDetector())
    
    def on_new_scene(frame_img: np.ndarray, frame_num: int):
        print(frame_num, video.duration.get_frames())
    
    scene_manager.detect_scenes(video, callback=on_new_scene)
    
    scene_manager.get_scene_list()

    Set flash filter mode to SUPPRESS:

    import scenedetect
    from scenedetect.scene_detector import FlashFilter
    import numpy as np
    
    scene_manager = scenedetect.SceneManager()
    scene_manager.add_detector(scenedetect.ContentDetector(filter_mode=FlashFilter.Mode.SUPPRESS))
    
    def on_new_scene(frame_img: np.ndarray, frame_num: int):
        print(frame_num, video.duration.get_frames())
    
    scene_manager.detect_scenes(video, callback=on_new_scene)
    
    scene_manager.get_scene_list()

    Root Cause

    This new filter was added as part of #35. The underlying issue is because ContentDetector doesn't override the event_buffer_length property, but this is required with the new filter mode.

    Thanks for the report!

  4. added a commit that references this issue on Sep 8, 2024
    44f2577
  5. added a commit that references this issue on Oct 18, 2024
    08eb26e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions