0

I'm doing multiple operations with FFMPEG. I have 5 files.

  1. intro_image.jpg: This is an image of any resolution but will be jpeg.
  2. intro_audio.mp3: This audio is static input of duration 7 seconds.
  3. outro_image.jpg: This is an image of any resolution but will be jpeg.
  4. outro_audio.mp3: This audio is static input of duration 7 seconds.
  5. user_video.mp4: User video can be of any resolution but a minimum 480P and of any format like mp4, avi, mkv. the maximum duration of the video will be 1 minute only.

What I'm doing is merging all the videos in 480P with a black background.

Step 1: Merging intro_image.jpg and intro_audio.mp3 to create intro_video.mp4

ffmpeg -loop 1 -i #{params[:intro_image].path} -i #{params[:intro_audio].path} -vf 'scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:-1:-1:color=black' -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest #{dir}/#{intro_video_name}

Step 2: Merging outro_image.jpg and outro_audio.mp3 to create outro_video.mp4

ffmpeg -loop 1 -i #{params[:outro_image].path} -i #{params[:outro_audio].path} -vf 'scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:-1:-1:color=black' -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest #{dir}/#{outro_video_name}

Step 3: I check if audio is avaiable in the user_video.mp4. if not then:

ffmpeg -i #{params[:video].path} -f lavfi -i anullsrc -c:v copy -c:a aac -shortest  #{video_path}

Step 4: Trim users video according to the provided start_time & end_time.

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4

Step 5: Merge all three videos.

ffmpeg -y -i #{dir}/#{intro_video_name} -i #{video_path} -i #{dir}/#{outro_video_name} -filter_complex '[0:v]scale=640x480,setsar=1[v0];[1:v]scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:-1:-1:color=black,setsar=1[v1];[2:v]scale=640x480,setsar=1[v2];[v0][0:a][v1][1:a][v2][2:a]concat=n=3:v=1:a=1' -ab 48000 -ac 2 -ar 22050 -s 640x480 -vcodec libx264 -crf 27 -preset ultrafast -vsync vfr #{dir}/#{final_video_name}

all these steps take around 40 seconds if the total file size is 10 MB. I'm looking for a way to optimize these commands without losing video quality.

1 Answers1

1

For proper concatenation all inputs must have the same attributes, so use multiple filters to make them all the same before concatenation:

ffmpeg -loop 1 -t 7 -framerate 25 -i intro_image.jpg -i intro_audio.mp3 -loop 1 -t 7 -framerate 25 -i outro_image.jpg -i outro_audio.mp3 -i user_video.mp4 -filter_complex "[0:v]scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:-1:-1:color=black,format=yuv420p,setsar=1[introv];[2:v]scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:-1:-1:color=black,format=yuv420p,setsar=1[outrov];[4:v]scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:-1:-1:color=black,format=yuv420p,fps=25,setsar=1[userv];[1:a]aformat=r=44100:cl=stereo[introa];[4:a]aformat=r=44100:cl=stereo[usera];[3:a]aformat=r=44100:cl=stereo[outroa];[introv][introa][userv][usera][outrov][outroa]concat=n=3:v=1:a=1[v][a]" -map "[v]" -map "[a]" -movflags +faststart output.mp4
  • scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:-1:-1:color=black - scale and pad filters to make image/video fit into 640x480 as shown in Resizing videos with ffmpeg to fit into static size

  • format=yuv420p - format filter to make chroma subsampling the same. Alternatively you can use just one instance of format filter on the output from concat.

  • setsar=1 - setsar filter to make aspect ratio the same. concat filter requires all segments to have the same aspect ratio.

  • fps=25 - fps filter to set frame rate of the user video to match the frame rate of the images. Because your inputs are arbitrary you need to use fps filter to set a specific frame rate.

  • aformat=r=44100:cl=stereo - aformat filter to make all audio have the same sample rate and channel layout.

  • [introv][introa][userv][usera][outrov][outroa]concat=n=3:v=1:a=1[v][a] concat filter to concatenate/join all of the segments into a single output.

llogan
  • 63,280