How to combine multiple FFmpeg filters into single command?

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?

John,

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.

For example,
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.mp4 indicates the input file, in this case, input.mp4.

  • -filter_complex is used to target the complex filter graph.

  • [0:v] refers to the video stream from the first input (index 0).

  • filter1=option1:option2 shows 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:option4 shows 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.mp4 is the name of the output file.

And you can also use the filters twice in different commands and complex filters in ffmpeg.
I hope this may help you! Ask if you need further guidance.

Thanks

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!

Sure!
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.
[index_of_stream:type_of_stream]filter_1_name=param1=value1:param2=value2[output_of_filter_1];[output_of_filter_1]filter_2_name[final_output]

For your use case, the filter chain would look like the following.
[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]

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