#!/usr/bin/env python3 import argparse import cv2 import moviepy.editor as mp MIN_INTERESTING_FRAMES = 20 MOVEMENT_THRESHOLD = 1000 def main(): # argparse parser = argparse.ArgumentParser() parser.add_argument('filename') args = parser.parse_args() # get video info vid = cv2.VideoCapture(args.filename) ret, colorFrame = vid.read() frame = cv2.cvtColor(colorFrame, cv2.COLOR_BGR2GRAY) fps = vid.get(cv2.CAP_PROP_FPS) fnum = int(vid.get(cv2.CAP_PROP_FRAME_COUNT)) dur = fnum // fps print("video stats: \n" f"fps: {fps}\n" f"frames: {fnum}\n" f"length: {int(dur//60):02}:{int(dur%60):02}\n") # prepare to find interesting segments print("finding interesting segments ...") i = 0 clips = [] startFrame = 0 inSegment = False # start a segment if we aren't already in one. def maybeStartSegment(i): nonlocal inSegment, startFrame if inSegment == False: inSegment = True startFrame = i print( f"found one! frame {i:8} to ... ", end="", flush=True) # end a segment if we are in one, and then save the # start and end frames if it was a long enough segment def maybeEndSegment(i): nonlocal inSegment if inSegment == True: inSegment = False if i - startFrame > MIN_INTERESTING_FRAMES: print( f"{i:6} ! ") clips.append((startFrame, i)) else: print( f"nvm, too short.") # loop through each frame while(True): i += 1; ret, colorFrame = vid.read() # if theres no more frames, break the loop & # maybe end the current segment if not ret: maybeEndSegment(i) break; # calculate the difference between the current & last frame # then run the Canny algorithm to find edges within the # diff. edges in the diff indicate that something is moving # in the frame. prev = frame frame = cv2.cvtColor(colorFrame, cv2.COLOR_BGR2GRAY) diff = cv2.subtract(frame, prev) edges = cv2.Canny(diff, 100, 200) # number of non zero (not true block) pixels in the edge frame. # large number indicates edges which indicates movment. nz = cv2.countNonZero(edges) if nz > MOVEMENT_THRESHOLD: maybeStartSegment(i) else: maybeEndSegment(i) # finished looping vid.release() print("done! time to chop up the video :) ") # convert the segment indicators from frame number to seconds def frame2second(f): return round(f / fps, 2) clipsSeconds = [ (frame2second(x),frame2second(y)) for (x,y) in clips ] print( clipsSeconds ) # slice that bitch up & export it! movie = mp.VideoFileClip(args.filename) clips = [ movie.subclip(s, e) for (s,e) in clipsSeconds ] trimmed = mp.concatenate_videoclips(clips) out_filename = args.filename.replace('.mp4', '') + '_trimmed.mp4' trimmed.write_videofile(out_filename) print("enjoy!") if __name__ == "__main__": main();