Skip to content

Instantly share code, notes, and snippets.

@irfanykywz
Last active December 6, 2024 02:14
Show Gist options
  • Save irfanykywz/d9ae2ae0987dc4346730426ec47fd32e to your computer and use it in GitHub Desktop.
Save irfanykywz/d9ae2ae0987dc4346730426ec47fd32e to your computer and use it in GitHub Desktop.
[ffmpeg] xfade+audio+scale
import itertools
import subprocess
import ffmpeg
def gen_filter(segments):
"""
https://stackoverflow.com/questions/63553906/merging-multiple-video-files-with-ffmpeg-and-xfade-filter
"""
video_fades = ""
audio_fades = ""
settb = ""
last_fade_output = "0:v"
last_audio_output = "0:a"
fade_duration = 0.3
video_length = 0
file_lengths = [0] * len(segments)
width = "720"
height = "1280"
scaler = f",scale=w={width}:h={height}:force_original_aspect_ratio=1,pad={width}:{height}:-1:-1"
for i in range(len(segments)):
settb += f"[%d]settb=AVTB,setsar=sar=1,fps=30{scaler}[%d:v];" % (i, i)
for i in range(len(segments) - 1):
file_lengths[i] = float(ffmpeg.probe(segments[i])['format']['duration'])
video_length += file_lengths[i]
next_fade_output = "v%d%d" % (i, i + 1)
xfade_offset = video_length - fade_duration * (i + 1)
video_fades += "[%s][%d:v]xfade=transition=zoomin:duration=%f:offset=%f%s%s" % \
(last_fade_output, i + 1, fade_duration, xfade_offset,
'[' + next_fade_output + '];' if (i) < len(segments) - 2 else "",
"" if (i) < len(segments) - 2 else ",format=yuv420p[video];")
last_fade_output = next_fade_output
next_audio_output = "a%d%d" % (i, i + 1)
afade_offset = (fade_duration * 2)
audio_fades += "[%s][%d:a]acrossfade=d=%f%s" % \
(last_audio_output, i + 1, afade_offset,
'[' + next_audio_output + '];' if (i) < len(segments) - 2 else "[audio]")
last_audio_output = next_audio_output
setab = ""
for i in range(len(segments)):
if i == 0:
continue
setab += f"[%d]adelay=delays={int(fade_duration * 1000)}:all=1[%d:a];" % (i, i)
return settb + setab + video_fades + audio_fades
input_file1 = 'D:\\Users\\WIN11\\Videos\\dd\\1.mp4'
input_file2 = 'D:\\Users\\WIN11\\Videos\\dd\\2.mp4'
input_file3 = 'D:\\Users\\WIN11\\Videos\\dd\\3.mp4'
output_file = 'D:\\Users\\WIN11\\Videos\\output5.mp4'
input_files = [input_file1, input_file2, input_file3]
filter_complex = gen_filter(input_files)
# print(filter_complex)
# exit()
files_input = [['-i', f] for f in input_files]
# Assemble the FFMPEG command arguments
ffmpeg_args = [
'ffmpeg',
*itertools.chain(*files_input),
'-filter_complex', filter_complex,
'-map', '[video]',
'-map', '[audio]',
'-y',
output_file
]
subprocess.run(ffmpeg_args)
# reference
# https://trac.ffmpeg.org/wiki/Xfade
# https://gist.github.com/royshil/369e175960718b5a03e40f279b131788
# https://stackoverflow.com/questions/63553906/merging-multiple-video-files-with-ffmpeg-and-xfade-filter/63570355#63570355
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment