Skip to content

Instantly share code, notes, and snippets.

@tokejepsen
Created January 4, 2021 15:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tokejepsen/551afac5728e36bda4c7a9e71087d860 to your computer and use it in GitHub Desktop.
Save tokejepsen/551afac5728e36bda4c7a9e71087d860 to your computer and use it in GitHub Desktop.
ffmpeg concat filter
import subprocess
import os
chunk_frames = 25
chunk_amount = 3
framerate = 25
duration = chunk_frames / framerate
def validation():
output = subprocess.check_output(
[
"ffprobe", "-v", "error", "-count_frames",
"-select_streams", "v:0",
"-show_entries", "stream=nb_read_frames",
"-of", "default=nokey=1:noprint_wrappers=1",
"temp.mov"
],
cwd=directory
)
frames = int(output)
expected_frames = chunk_frames * chunk_amount
msg = f"Frames: {frames}\nExpected frames: {expected_frames}"
assert frames == expected_frames, msg
# Generate videos.
ffmpeg_args = [
"ffmpeg", "-y", "-v", "9", "-loglevel", "99",
"-f", "lavfi",
"-i", f"testsrc=duration={duration}:size=960x540:rate={framerate}",
"-f", "lavfi",
"-i", f"sine=frequency=1000:duration={duration}",
"-pix_fmt", "yuv420p"
]
directory = os.path.join(os.path.dirname(__file__))
video_files = []
for count in range(0, chunk_amount):
path = os.path.join(directory, f"temp{count}.mov").replace("\\", "/")
args = ffmpeg_args + [os.path.basename(path)]
print(subprocess.list2cmdline(args))
subprocess.call(args, cwd=directory)
video_files.append(path)
# Concatenation of video only.
ffmpeg_args = ["ffmpeg", "-y", "-v", "9", "-loglevel", "99"]
for f in video_files:
ffmpeg_args.extend(["-i", f])
ffmpeg_args.append("-filter_complex")
files_count = len(video_files)
filter = ""
for count in range(0, files_count):
filter += f"[{count}:0] "
filter += f"concat=n={files_count}:v=1:a=0 [v]"
ffmpeg_args.append(filter)
ffmpeg_args.extend(["-map", "[v]", "temp.mov"])
print(subprocess.list2cmdline(ffmpeg_args))
subprocess.call(ffmpeg_args, cwd=directory)
# Validation.
validation()
# Concatenation of video and audio.
ffmpeg_args = ["ffmpeg", "-y", "-v", "9", "-loglevel", "99"]
for f in video_files:
ffmpeg_args.extend(["-i", f])
ffmpeg_args.append("-filter_complex")
files_count = len(video_files)
filter = ""
for count in range(0, files_count):
filter += f"[{count}:0] [{count}:1]"
filter += f"concat=n={files_count}:v=1:a=1 [v] [a]"
ffmpeg_args.append(filter)
ffmpeg_args.extend(["-map", "[v]", "-map", "[a]", "temp.mov"])
print(subprocess.list2cmdline(ffmpeg_args))
subprocess.call(ffmpeg_args, cwd=directory)
# Validation.
validation()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment