Skip to content

Instantly share code, notes, and snippets.

@cb109
Created April 23, 2024 07:48
Show Gist options
  • Save cb109/053c88551005676a7e4f2dfa7e091c31 to your computer and use it in GitHub Desktop.
Save cb109/053c88551005676a7e4f2dfa7e091c31 to your computer and use it in GitHub Desktop.
Overlay a simple growing/moving progressbar on the bottom of a video using ffmpeg
import subprocess
def add_progressbar_on_top_of_video(
input_video_filepath: str,
output_video_filepath: str,
width: int,
height: int,
duration: float,
fps: float = 25.0,
progressbar_height: int = 8,
progressbar_color: str = "#ffffff",
):
"""Overlay a simple filled rect progressbar moving over the screen."""
px_width_per_frame: float = width / duration / fps
options = [
"ffmpeg",
# First input is our original [video]
"-i",
input_video_filepath,
# Second input exists just to draw on it like on a [canvas]. We
# need to pass a color here and transparency isn't applicable,
# so it doesn't really matter, we'll crop it away later anyway.
"-f",
"lavfi",
"-i",
f"color=black:duration={duration}:rate={fps}:size={width}x{height}",
# Creation of the progressbar consists of multiple steps:
"-filter_complex",
(
# Assign input node aliases.
f"""
[0:v]null[video];
[1:v]null[canvas];
"""
# Draw full-width progressbar onto the canvas at the bottom.
f"""
[canvas]
drawbox=
w={width}:
h={progressbar_height}:
x=0:
y={height - progressbar_height}:
color={progressbar_color}@1.0:
thickness=fill
[progressbar];
"""
# Crop away the black parts, which moves the progressbar to the top.
f"""
[progressbar]
crop=
w={width}:
h={progressbar_height}:
y={height - progressbar_height}
[progressbar];
"""
# Overlay both, moving the progressbar back to the bottom.
f"""
[video][progressbar]
overlay=
x=-{width}+(n*{px_width_per_frame}):
y={height - progressbar_height}:
shortest=1
[out]
"""
)
# Remove the whitespace that helped readability above, but can't
# be executed.
.replace(" ", "")
.replace("\n", ""),
"-map",
"[out]",
# Write results to disk.
"-y",
output_video_filepath,
]
subprocess.call(options, stderr=subprocess.STDOUT)
# add_progressbar_on_top_of_video("input_video.mp4", "output_video.mp4", 1920, 1080, duration=5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment