Extract video frame as image

Let's just say i was trying to learn how to better use ffmpeg, and started asking myself "What are the things i needed when working with video content?".

And this is one of the things that came to mind. A simple way to extract one video frame from a video file and exporting that as a usable image file (usually PNG).

Very useful for making thumbnails from video content, showing specific moments.

Here are some ways on how i managed to do exactly that.

Using ffmpeg to extract a single frame from a specific time point in the video

#!/usr/bin/env bash

INPUT_FILEPATH="${1}"
FRAME_TIME="${2}"
OUTPUT_FILEPATH="${3:-${INPUT_FILEPATH//.*/.png}}"

ffmpeg \
-i "${INPUT_FILEPATH}" \
-ss "${FRAME_TIME}" \
-frames:v 1 \
"${OUTPUT_FILEPATH}"

The Bash script takes 3 arguments in total, with the last being optional:

  • The 1. one is the filepath to the video file.
  • The 2. one is the starting time, from which to extract the video frame. The expected input format is HH:MM:SS, meaning hours, minutes and seconds with exactly two digits.
  • The 3. is the output filepath. If not set, will use the input filepath and replace the file extension/suffix with .png.

Using MoviePy to extract a single frame from a specific time point in the video

This approach uses the MoviePy Python3 library, which is pretty good for scripting general purpose video editing.

Here is a Python3 script for storing a video frame as a PNG image file from a specific timepoint.

#!./venv/bin/python3
from pathlib import Path

from moviepy import VideoFileClip


def save_frame(input_filepath, at_time) -> None:
    input_filepath = Path(input_filepath)

    with VideoFileClip(input_filepath) as source_clip:
        source_clip.save_frame(
            clip_output_filepath.with_suffix(".png"),
            t=at_time,
        )


save_frame(
    input_filepath="./test.mp4",
    at_time=(0, 11),
)

links

social