I have a video file and I want to crop some portion of the video, apply to a pad, and scale it to a particular dimension. I can do this using three FFmpeg commands each time using a specific filter but I want to do it in a single FFmpeg command, is there any way?
Combining multiple filters into a single FFmpeg command is very simple, you must be using the
-vf option provided by FFmpeg for your individual filters, but to combine them into a single command you have to create a filter chain and use it with the
-filter_complex option provided by FFmpeg.
ffmpeg -i input.mp4 -filter_complex "[0:v]filter1=option1:option2[outv];[0:a]filter2=option3:option4[outa]" -map "[outv]" -map "[outa]" output.mp4
-i input.mp4indicates the input file, in this case,
-filter_complexis used to target the complex filter graph.
[0:v]refers to the video stream from the first input (index 0).
filter1=option1:option2shows the first filter you wish to apply to the video stream.
[outv]is the name given to the output video stream from the filter.
[0:a]refers to the audio stream from the first input (index 0).
filter2=option3:option4shows the second filter you want to apply to the audio stream.
[outa]is the name given to the output audio stream from the filter.
-map "[outv]" and -map "[outa]"specify which output streams to include in the final output file.
output.mp4is the name of the output file.
Can you tell me how can I use this option mentioned above? I tried this on my system but it did not work properly maybe I am missing something!
FFmpeg filter chain works in a very simple way just like a normal programming language, you get a hold particular stream (video/audio/subtitle), apply some operation (filter) on it, and store the output stream in a variable that can be referenced later in filter chain anywhere or can be passed to video codec for transcoding purpose.
Usually, these filter chains follow syntax like the given below.
For your use case, the filter chain would look like the following.
You can just put the filter chain constructed in the above example into the FFmpeg command like the following.
ffmpeg -i input.mp4 -filter_complex “[0:v]crop=x=0:y=0:w=500:h=500[cropped_stream];[cropped_stream]pad=width=500:height=500:x=0:y=40:color=black[padded_stream];[padded_stream]scale=w=300:h=300[scaled_stream]” -map “[scaled_stream]” -c:v libx264 -f mp4 output.mp4