2019-12-23, 06:04 AM
Made this bash script (can be used on Windows with the Git Bash that comes with the Git installer) for creating thumbnails.
Difference to other thumbnail creating possibilities is that this one uses scene detection, so it's suited well for shorter videos like trailers when you want to get every distinct shot.
It's not perfect - you get blank frames for example during short flashes and it won't recognize faded changes usually, but I'm happy with it.
Requirements
- Ability to run .sh scripts. So either run in Linux or install a bash for Windows (for example Git Bash that comes with the Git installer)
- ffmpeg in the PATH.
- That's it!
How to use
1. Replace "Trailer.mkv" with the file you want to create thumbnails for
2. Set "columns" to how many columns of thumbnails you want to be displayed side-by-side
3. Set "columnwidth" to the width in pixels an individual thumbnail should have
4. Set "maxrows" to a high enough estimated number to fit in all thumbnails (from your experience and experiments) and then add 10. It's a bit awkwardly done, but ffmpeg needs you to set the amount of thumbnail tiles in advance, hence this script has a second cropping stage.
5. Set "scenedetect" to a value depending on your content. Lower values make it more sensitive. However darker scenes require higher sensitivity. It's a bit dumb, but I don't know a better way. For dark videos I recommend values around 0.2 and for bright content around 0.4.
6. Adjust JPEG quality if you want, but I don't know if it actually makes a difference for ffmpeg. Might replace this with a better JPEG compressor but I wanted this to work with the only dependency being ffmpeg.
7. Double click the script and wait for it to finish. Can take a little while.
The script will always create both .png and .jpg formats. Just keep the one you prefer.
Script (save as somefile.sh):
Difference to other thumbnail creating possibilities is that this one uses scene detection, so it's suited well for shorter videos like trailers when you want to get every distinct shot.
It's not perfect - you get blank frames for example during short flashes and it won't recognize faded changes usually, but I'm happy with it.
Requirements
- Ability to run .sh scripts. So either run in Linux or install a bash for Windows (for example Git Bash that comes with the Git installer)
- ffmpeg in the PATH.
- That's it!
How to use
1. Replace "Trailer.mkv" with the file you want to create thumbnails for
2. Set "columns" to how many columns of thumbnails you want to be displayed side-by-side
3. Set "columnwidth" to the width in pixels an individual thumbnail should have
4. Set "maxrows" to a high enough estimated number to fit in all thumbnails (from your experience and experiments) and then add 10. It's a bit awkwardly done, but ffmpeg needs you to set the amount of thumbnail tiles in advance, hence this script has a second cropping stage.
5. Set "scenedetect" to a value depending on your content. Lower values make it more sensitive. However darker scenes require higher sensitivity. It's a bit dumb, but I don't know a better way. For dark videos I recommend values around 0.2 and for bright content around 0.4.
6. Adjust JPEG quality if you want, but I don't know if it actually makes a difference for ffmpeg. Might replace this with a better JPEG compressor but I wanted this to work with the only dependency being ffmpeg.
7. Double click the script and wait for it to finish. Can take a little while.
The script will always create both .png and .jpg formats. Just keep the one you prefer.
Script (save as somefile.sh):
Code:
#!/bin/bash
inputfile="Trailer.mkv"
columns=4
columnwidth=640
maxrows=30
scenedetect=0.2 #Scene detection treshold. Lower = greater detection. Try around 0.2 for dark videos and 0.4 for normal videos
jpegquality=1 #JPEG quality from 1-31 with 31 being worst quality (not sure if this works!)
x="x"
tmpfile="$inputfile.tmp.bmp"
outputfile="$inputfile.png"
outputfilejpg="$inputfile.jpg"
tiles="$columns$x$maxrows"
echo "Doing scene analysis: $inputfile ..."
ffmpeg -i "$inputfile" -vf select="gt(scene\,$scenedetect)",scale=$columnwidth:-1,tile=$tiles -hide_banner -frames:v 1 "$tmpfile" 2>/dev/null
echo "Generated temporary uncropped tile file $tmpfile ..."
cropvalue=`ffmpeg -loop 1 -r 1 -i "$tmpfile" -t 2 -r 1 -vf cropdetect=0:1:0 -f null - 2>&1 | awk '/crop/ { print $NF }' | tail -1`
echo "Calculated crop value: $cropvalue"
echo "Generating PNG file: $outputfile"
ffmpeg -i "$tmpfile" -vf $cropvalue -hide_banner "$outputfile" 2>/dev/null
echo "Generating JPG file: $outputfilejpg"
ffmpeg -i "$tmpfile" -vf $cropvalue -hide_banner -q:v $jpegquality "$outputfilejpg" 2>/dev/null
echo "Deleting temporary file: $tmpfile"
rm "$tmpfile"
read -rsp $'(Hopefully) done! Press any key to continue...\n' -n1 key