107 lines
2.7 KiB
Python
107 lines
2.7 KiB
Python
|
|
from ffprobe import FFProbe
|
|
import ffmpeg
|
|
import shutil
|
|
import json
|
|
import math
|
|
import os
|
|
def execute_trim_video(js_path, start_frame, end_frame, empty_video = False):
|
|
with open(js_path,'r') as jj:
|
|
data = json.load(jj)
|
|
|
|
movie_dir = os.path.dirname(js_path)
|
|
archive_dir = os.path.join(movie_dir, 'original') + '/'
|
|
|
|
|
|
if not os.path.exists(archive_dir):
|
|
os.mkdir(archive_dir)
|
|
|
|
rt_name = os.path.splitext(js_path)[0]
|
|
movie_path = rt_name+'.mp4'
|
|
movie_new_path = rt_name+'_trimmed.mp4'
|
|
js_new_path = rt_name + '_trimmed.json'
|
|
|
|
frame_pad = 5 #seconds
|
|
vid_info = FFProbe(movie_path)
|
|
vid_stream = vid_info.video[0]
|
|
|
|
framerate = vid_stream.framerate
|
|
duration = float(vid_stream.duration)
|
|
max_frames = duration * framerate
|
|
|
|
start_frame = max(0, start_frame - frame_pad * framerate)
|
|
end_frame = min( max_frames, end_frame + frame_pad * framerate)
|
|
|
|
start_time = start_frame / framerate
|
|
end_time = end_frame / framerate
|
|
|
|
|
|
|
|
to_keep = list()
|
|
for x in data:
|
|
json_frame_num = x['frame_number']
|
|
if isinstance(json_frame_num, str) and json_frame_num == 'thumbnail':
|
|
to_keep.append(x)
|
|
elif json_frame_num >=start_frame and json_frame_num <= end_frame:
|
|
x['frame_number_original'] = x['frame_number']
|
|
x['frame_number'] -= start_frame
|
|
|
|
to_keep.append(x)
|
|
|
|
|
|
trim_duration = end_time - start_time
|
|
|
|
if os.path.exists(movie_new_path):
|
|
os.remove(movie_new_path)
|
|
|
|
if not empty_video:
|
|
cmd = f'ffmpeg -ss {start_time} -i {movie_path} -ss 0 -t {trim_duration} -c copy -map 0 {movie_new_path}'
|
|
return_code = os.system(cmd)
|
|
|
|
with open(js_new_path,'w') as jnp:
|
|
json.dump(to_keep, jnp, indent=4)
|
|
|
|
if empty_video or return_code == 0:
|
|
|
|
shutil.move(movie_path, archive_dir)
|
|
shutil.move(js_path ,archive_dir)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def trim_video(jspath):
|
|
with open(jspath,'r') as jj:
|
|
data = json.load(jj)
|
|
|
|
start_frame = math.inf
|
|
end_frame = -math.inf
|
|
|
|
|
|
skip_trimming = False
|
|
empty_video = True
|
|
for x in data:
|
|
if len(x['boxes']) > 0:
|
|
json_frame_num = x['frame_number']
|
|
|
|
if isinstance(json_frame_num, str) and json_frame_num == 'thumbnail':
|
|
skip_trimming = True
|
|
elif max(x['scores']) > 0.05:
|
|
start_frame = min(start_frame, json_frame_num)
|
|
end_frame = max(end_frame, json_frame_num)
|
|
empty_video = False
|
|
|
|
|
|
|
|
if not skip_trimming:
|
|
execute_trim_video(jspath, start_frame, end_frame, empty_video = empty_video)
|
|
|
|
|
|
|
|
|
|
|
|
|