PySceneDetect icon indicating copy to clipboard operation
PySceneDetect copied to clipboard

Ability to set fade bias to BOTH -1 and 1?

Open Gnishimura opened this issue 5 years ago • 3 comments

Pyscenedetect has been working great for me until I ran into some video where commercial content was taken out, leaving just a black screen for minutes at a time. Under these situations PSD will still only make one cut (under default fade bias 0.0 it will cut at the middle, leaving a chunk of black screen on the end of scene 1 and the beginning of scene 2).

My question is: Is there any simple way to change this behavior so that BOTH the fade out to black AND the fade in to content are counted as cuts (resulting in 3 scenes, with the middle "scene" being the entire time that the screen is blank)?

I know I could process the video twice, once with fade bias at -1 and a second time with fade bias at +1 but since it's taking me ~15 minutes to process a 1 hr long video, I really don't want to have to do two runs.

Lastly, thank you so much for this incredible open source resource, it's amazing!

Gnishimura avatar Jan 30 '20 18:01 Gnishimura

I am not sure about the command line interface, but using the python api, it is possible to use multiple detectors simultaneously. You could create multiple detectors with different threshold parameters and analyze the video in a single pass.

If you model your script off of the example in the docs, you would just need to define multiple detectors and then just add them with a call to scene_manager.add_detector(your_detector_here) for each of them.

Edit: I previously included a basic outline of how this works in #84 for reference.

wjs018 avatar Jan 31 '20 03:01 wjs018

Thanks for the tip - this will be very helpful. I tried implementing the two detectors with different fade biases, and it does indeed capture the black screens, but there's still an issue:

Even when I set the min_scene_len on both detectors to 60 frames (or ~2 secs), I am getting the creation of tiny scenes that last only 20 frames or so. Does this behavior make sense? Other than min_scene_len, I don't see a place where I can prevent the creation of these tiny scenes.

After inspecting the source code and I tried to make this change to the ThresholdDetector() class and run only one detector, but this didn't work either.

  `
    min_frame_for_black = 60
    if self.last_frame_avg is not None:
        if self.last_fade['type'] == 'in' and self.frame_under_threshold(frame_img):
            # Just faded out of a scene, wait for next fade in.
            self.last_fade['type'] = 'out'
            self.last_fade['frame'] = frame_num            
     
        elif self.last_fade['type'] == 'out' and not self.frame_under_threshold(frame_img):
            if (frame_num - self.last_scene_cut) >= self.min_scene_len:
            # Only add the scene if min_scene_len frames have passed.
                if (frame_num - self.last_fade['frame']) < min_frame_for_black:
                    # Do the normal thing if fade to black section is very small
                    f_out = self.last_fade['frame']
                    f_split = int((frame_num + f_out + int(self.fade_bias * (frame_num - f_out))) / 2)
                    cut_list.append(f_split)
                    self.last_scene_cut = frame_num
                    self.last_fade['type'] = 'in'     
                else:
                    # Add both fade in and fade out frames to the cut list if the black section is long
                    f_out = self.last_fade['frame']
                    cut_list.extend([f_out, frame_num])
                    self.last_scene_cut = frame_num              
            self.last_fade['frame'] = frame_num
    else:
        self.last_fade['frame'] = 0
        if self.frame_under_threshold(frame_img):
            self.last_fade['type'] = 'out'
        else:
            self.last_fade['type'] = 'in'
    # Before returning, we keep track of the last frame average (can also
    # be used to compute fades independently of the last fade type).
    self.last_frame_avg = frame_avg
    return cut_list

`

Any ideas of how I can get rid of those small scenes? Thanks for your help.

Gnishimura avatar Feb 05 '20 21:02 Gnishimura

For what it's worth, I tried this out using the cli and it worked just fine. I made an altered version of the Goldeneye clip from the docs examples that includes several sections where it fades to black for long periods and then fades back to the content. This was simply a matter of listing the detect-threshold command twice with different fade biases.

scenedetect -i goldeneye_fades.mp4 -s stats.csv detect-threshold -f -100 detect-threshold -f 100 split-video

This successfully isolates the black sections from the sections with content.

wjs018 avatar Jan 21 '21 20:01 wjs018