Last active
October 12, 2024 11:02
-
-
Save zmwangx/11275000 to your computer and use it in GitHub Desktop.
Script to generate thumbnails of a video and combine into one tile image. Uses FFmpeg and ImageMagick.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/zsh | |
# Script to generate thumbnails of a video and combine into one tile image. | |
# | |
# CAUTION: | |
# FFprobe might fail to extract duration info from a MKV container. Use | |
# ffmpeg -i video.mkv -c:v copy -c:a copy video.mp4 | |
# to swap to an MP4 container. | |
# | |
# Dependencies: | |
# 1. ffmpeg | |
# 2. ImageMagick | |
# | |
# Usage: | |
# ./thumbnails.sh NFRAMES TILE SIZE INPUT OUTPUT | |
# | |
# NFRAMES is the number of frames (thumbnails) to generate, e.g., 16; | |
# TILE is in the form "MxN" (where M * N should match NFRAMES), e.g., 4x4; | |
# SIZE is the length of the longer side of the output, e.g., 1920 if you want | |
# to get an 1920*1080 output image; | |
# INPUT is the path to the input file; | |
# OUTPUT is the path to the output file (make sure intermediate directories | |
# exist). | |
# | |
# Example: | |
# ./thumbnail.sh 16 4x4 1920 video.mp4 thumbnails.png | |
# | |
# Credit: | |
# http://goo.gl/vzXW1b (FFmpeg wiki: generate thumbnails) | |
# http://stackoverflow.com/q/7395343 (extract video length) | |
# http://apple.stackexchange.com/q/52879 (combine images) | |
if [[ $# != 5 ]]; then | |
echo "wrong number of arguments | |
Usage: | |
./thumbnails.sh NFRAMES TILE SIZE INPUT OUTPUT | |
NFRAMES is the number of frames (thumbnails) to generate, e.g., 16; | |
TILE is in the form 'MxN' (where M * N should match NFRAMES), e.g., 4x4; | |
SIZE is the length of the longer side of the output, e.g., 1920 if you want | |
to get an 1920*1080 output image; | |
INPUT is the path to the input file; | |
OUTPUT is the path to the output file (make sure intermediate directories | |
exist). | |
Example: | |
./thumbnail.sh 16 4x4 1920 video.mp4 thumbnails.png | |
" | |
return 1 | |
fi | |
NFRAMES=$1 | |
TILE=$2 | |
SIZE=$3 | |
INPUT=$4 | |
OUTPUT=$5 | |
DURATION=$(ffprobe -loglevel error -show_streams $INPUT | grep duration= | cut -f2 -d= | head -1) | |
FPS=$(echo "$NFRAMES / $DURATION" | bc -l) | |
OFFSET=$(echo "$DURATION / $NFRAMES / 2" | bc -l) | |
# generate thumbnails in the /tmp folder | |
TMPDIR=/tmp/thumbnails-${RANDOM}/ | |
mkdir $TMPDIR | |
ffmpeg -ss $OFFSET -i $INPUT -f image2 -vf fps=fps=$FPS ${TMPDIR}thumb%04d.jpg | |
montage ${TMPDIR}thumb*.jpg -background white -geometry +5+5 -tile $TILE ${TMPDIR}output.jpg | |
convert ${TMPDIR}output.jpg -resize ${SIZE}x${SIZE} $OUTPUT |
I'm having day off so I've removed all dependencies from ImageMagick: combining images, making white backgroud and adding text using only ffmpeg: https://github.com/romanwarlock/thumbnails/blob/master/thumbgen.sh
It turned out existing bc dependency NFRAMES=$(echo "scale=0;$X*$Y" | bc)
which I removed by using awk: NFRAMES=
echo | awk '{print (X*Y)}' X="$X" Y="$Y}}"``. Github doesn't show all the symbols correctly.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
First of all great job.
Script works for mkv, by calculating duration in seconds with
ffmpeg -i
(one long line):DURATION=$(ffmpeg -i "$4" 2>&1 | grep "Duration"| cut -d ' ' -f 4 | sed s/,// | sed 's@\..*@@g' | awk '{ split($1, A, ":"); split(A[3], B, "."); print 3600*A[1] + 60*A[2] + B[1] }')
I chose another approach in script, by making snapshots
ffmpeg ... -vframes 1 ...
...This way is really faster for small amount of thumbnails.
I debugged approach to using the script parameters, in the origianl script, space in filename is a problem: see how use
"$4"
in DURATION=....I changed usage to
. th.sh COLUMNS ROWS SIZE "INPUT"
, thusNFRAMES=$(echo "scale=0;$1*$2" | bc)
andTILE=$(echo "$1x$2")
I also added more stuff from imagemagick to put info about video (name, resolution, size, duration), though I had to edit
/etc/ImageMagick-6/policy.xml
by commenting all the policy to produce thumbnails