If I have a .mp4
video file with black boarders on the top, bottom, and/or sides, How can I trim these boarders off with python?
I do not want to replace the boarders with anything, I just want to trim the video.
For example, if I run magically_trim_black_boarders_from_vid(in_vid)
on a video that looks like the frame below, the video's height would not change, but its width would be reduced.
Thanks!
We my use cropdetect filter as described in the following post.
Within Python we may execute FFmpeg as subprocess twice - first time with cropdetect
filter for finding the black borders, and second time for cropping the borders.
The output of cropdetect
filter is as a lines of text, that should be parsed:
#[Parsed_cropdetect_0 @ 00000232c2705e00] x1:69 x2:551 y1:0 y2:309 w:480 h:304 x:72 y:4 pts:512 t:0.040000 crop=480:304:72:4
#[Parsed_cropdetect_0 @ 00000232c2705e00] x1:69 x2:551 y1:0 y2:309 w:480 h:304 x:72 y:4 pts:1024 t:0.080000 crop=480:304:72:4
...
Suggested stages:
Execute FFmpeg as subprocess with cropdetect
filter, and storing the (stderr
) output in cropdetect_output
string:
cropdetect_output = sp.run(['ffmpeg', '-hide_banner', '-i', in_video_file, '-vf', 'cropdetect=skip=0', '-t', '1', '-f', 'null', 'pipe:'], stderr=sp.PIPE, universal_newlines=True).stderr
Find the substring, that starts with "crop=" and ends by new line using re.search regular expression searching:
crop_str = re.search('crop=.*', cropdetect_output).group(0) # crop=480:304:72:4
Execute FFmpeg using crop filter with the crop=
arguments found above.
sp.run(['ffmpeg', '-hide_banner', '-i', in_video_file, '-vf', crop_str+',setsar=1', out_video_file])
Code sample:
import subprocess as sp
import re
in_video_file = 'wnkaa.mp4'
out_video_file = 'cropped_wnkaa.mp4'
# ffmpeg -hide_banner -i wnkaa.mp4 -vf cropdetect=skip=0 -t 1 -f null
cropdetect_output = sp.run(['ffmpeg', '-hide_banner', '-i', in_video_file, '-vf', 'cropdetect=skip=0', '-t', '1', '-f', 'null', 'pipe:'], stderr=sp.PIPE, universal_newlines=True).stderr
# Return: crop=480:304:72:4
crop_str = re.search('crop=.*', cropdetect_output).group(0) # Find the first match of "crop=", and return all characters from "crop=" up to new line.
# ffmpeg -hide_banner -i wnkaa.mp4 -vf crop=480:304:72:4,setsar=1 cropped_wnkaa.mp4
sp.run(['ffmpeg', '-hide_banner', '-i', in_video_file, '-vf', crop_str+',setsar=1', out_video_file])
Note:
The above command uses default codec arguments (it's just an example).
We may add encoding arguments like '-vcodec', 'libx264', '-crf', '20', '-pix_fmt', 'yuv420p'
...