From e119f264354e8272067036574bd2222f34b07d2e Mon Sep 17 00:00:00 2001 From: ryan Date: Wed, 6 Dec 2023 15:45:16 -0800 Subject: [PATCH] initial commit --- trim.py | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 trim.py diff --git a/trim.py b/trim.py new file mode 100755 index 0000000..ad71e77 --- /dev/null +++ b/trim.py @@ -0,0 +1,104 @@ +#!/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();