After you create a video, one of the most common things you want to do with it is grab thumbnails.
Thumbnails have many uses:
- Use them as the poster for your video player.
- Analyze them for content moderation, use AI to generate tags to associate with the video
- When rendering a list of videos for users to browse
- Sharing on social media with the og:image tag
Extract a single thumbnail at a specific timestamp
Here's a breakdown of the command:
- -i input_video.mp4: Specifies the input video file.
- -vf "select='gte(t,9)',scale=320:-1": Applies the thumbnail filter and scales the output image to width 320 pixels while preserving the aspect ratio. Adjust the resolution as needed. gte(t,9) is selecting the 9 second mark to extract the thumbnail. For one minute you would use gte(t,60), you can also be more prices, for example 7.5 seconds: gte(t,7.5)
- -frames:v 1: Extracts only one frame (you can adjust this to extract more frames).
- thumbnail.png: The name of the output image file.
Extract a multiple thumbnails at regular intervals
If you want to extract multiple thumbnails at regular intervals, you can modify the command to include a timestamp pattern and specify fps=1 to get 1 thumbnail per second:
- -vsync vfr: Ensures variable frame rate for correct frame extraction.
- -vf "fps=1,scale=320:-1": Tells FFmpeg to produce 1 frame per second and to scale the thumbnail to 320 pixels wide
- -q:v 2: Sets the quality of the output thumbnails (lower values mean higher quality).
- thumb%04d.png: Specifies the output file name pattern where %04d will be replaced by a sequence number (e.g., thumb0001.png, thumb0002.png, etc.).
Extract 1 thumbnail per I-frame or keyframe
The most time and resource efficient way to extract multiple thumbnails from a video would be to extract each I-frame (or keyframe) from the video.
Here's a breakdown of the command:
- select='eq(pict_type,I)' selects only I-frames. eq(pict_type,I) checks if the frame is an I-frame
This will output an image for every single I-frame of the video, which might be a lot. You could modify this command to only select every 10th I-frame with another filter:
Extract 1 thumbnail for every 10th I-frame or keyframe
This command is nearly the same but adds select='not(mod(n,10))' which will take the previously selected I-frames and select every 10th one.
In the select='not(mod(n,10))' command
- n is the frame number
- mod(n,10) is the remainder when n is divided by 10
- not(mod(n,10)) is true when the remainder is 0 (i.e. for every 10th frame)
Benefits and drawbacks of extracting I-frame thumbnails
If you're doing the I-frame approach, there are some benefits and drawbacks to be aware of. Weather you choose this direction or not depends on if your particular use case is sensitive to the limitations of this approach.
Benefits
- Efficiency: I-frames are complete images that don't depend on any other frames, which means ffmpeg can grab them quickly without a lot of computation.
- Quality: I-frames typically have the best quality in a video stream because they are self-contained
- Representativeness: I-frames often occur at scene changes or significant moments in the video, making them good candidates for a set of images that will represent the content contained in the video.
Drawbacks
- The spacing between I-frames can be irregular and unpredictable
- Some videos, especially videos optimized for streaming might have very few I-frames, which limits the number of thumbnails that you get.
Extracting thumbnails with Mux
If you have videos hosted with the Mux Video API you can extract thumbnails, gifs and storyboards on-demand with the image API.