In this tutorial, we will introduce how to split a video file into some separate clips by shot changes using python. You can learn how to do by our steps.
In order to get the shot changes in a video, we can use PySceneDetect. We can use pip to install it.
pip install --upgrade scenedetect[opencv]
How to get video scenes by detecting shot changes in PySceneDetect?
We can use detect() function to get video scenes.
Here is an example:
from scenedetect import detect, ContentDetector video_file = r'lsx_a2_0518_final.mp4' scene_list = detect(video_file, ContentDetector()) for i, scene in enumerate(scene_list): print('Scene %2d: Start %s / Frame %d, End %s / Frame %d' % ( i+1, scene.get_timecode(), scene.get_frames(), scene.get_timecode(), scene.get_frames(),))
In this code, video_file is a video file that we plan to detect shot changes. ContentDetector() is an instance that detects shot changes in a video. It is defined as:
def __init__( self, threshold: float = 27.0, min_scene_len: int = 15, weights: 'ContentDetector.Components' = DEFAULT_COMPONENT_WEIGHTS, luma_only: bool = False, kernel_size: Optional[int] = None, ):
threshold: Threshold the average change in pixel intensity must exceed to trigger a cut.
min_scene_len: Once a cut is detected, this many frames must pass before a new one can be added to the scene list.
We can set threshold and min_scene_len to change ContentDetector()
Run this code, we may see:
Scene 1: Start 00:00:00.000 / Frame 0, End 00:00:01.760 / Frame 44 Scene 2: Start 00:00:01.760 / Frame 44, End 00:00:09.240 / Frame 231 Scene 3: Start 00:00:09.240 / Frame 231, End 00:00:11.480 / Frame 287 Scene 4: Start 00:00:11.480 / Frame 287, End 00:00:14.080 / Frame 352 Scene 5: Start 00:00:14.080 / Frame 352, End 00:01:05.280 / Frame 1632 Scene 6: Start 00:01:05.280 / Frame 1632, End 00:01:11.200 / Frame 1780
How to get video clips based on shot changes?
After we have got the shot changes, we can use scene.get_timecode() and scene.get_timecode() to get clips by python moviepy. Here is the tutorial:
Finally, we may see these clips.
Here we use moviepy to create a function to extract clip.
def split_video(video_file, clip_video_file, start_time, end_time): clip = VideoFileClip(video_file) newclip = clip.subclip(start_time, end_time) newclip.write_videofile(clip_video_file) newclip.close() clip.close()
Then, we can get clip as follows:
split_video(video_file, str(i)+".mp4", scene.get_timecode(), scene.get_timecode())