Merge pull request #1102 from seefood/ira-gifski

GIF plugin: Added FPS auto-detection
pull/1103/head
Nils Winkler 2017-12-01 08:28:02 +01:00 committed by GitHub
commit 2df93544ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 39 additions and 22 deletions

View File

@ -5,6 +5,7 @@ about-plugin 'video to gif helper functions'
# Renamed gifify to v2gif to go avoid clobbering https://github.com/jclem/gifify # Renamed gifify to v2gif to go avoid clobbering https://github.com/jclem/gifify
# Requirements (Mac OS X using Homebrew): brew install ffmpeg giflossy imagemagick # Requirements (Mac OS X using Homebrew): brew install ffmpeg giflossy imagemagick
# Requirements on Ubuntu: sudo apt install ffmpeg imagemagick ; plus install https://github.com/pornel/giflossy # Requirements on Ubuntu: sudo apt install ffmpeg imagemagick ; plus install https://github.com/pornel/giflossy
# Optional: install mediainfo for autodetection of original video FPS.
# Optional: if lossy is not important, Ubuntu has gifsicle packaged for apt-get, instead of giflossy # Optional: if lossy is not important, Ubuntu has gifsicle packaged for apt-get, instead of giflossy
# Optional: gifski (from `brew install gifski` or github.com/ImageOptim/gifski) # Optional: gifski (from `brew install gifski` or github.com/ImageOptim/gifski)
# for high quality huge files. # for high quality huge files.
@ -17,7 +18,7 @@ function v2gif {
param '4: -h ; Optional: high quality using gifski (installed seperately) - overrides "--lossy" above!' param '4: -h ; Optional: high quality using gifski (installed seperately) - overrides "--lossy" above!'
param '5: -d ; Optional: delete the original video file if succeeded' param '5: -d ; Optional: delete the original video file if succeeded'
param '6: -t ; Optional: Tag the result with quality stamp for comparison use' param '6: -t ; Optional: Tag the result with quality stamp for comparison use'
param '7: -f <num> ; Optional: Change number of frames per second (default 10)' param '7: -f <num> ; Optional: Change number of frames per second (default 10 or original FPS if mediainfo installed)'
param '8: -a <num> ; Optional: Alert if resulting file is over <num> kilobytes (default is 5000, 0 turns off)' param '8: -a <num> ; Optional: Alert if resulting file is over <num> kilobytes (default is 5000, 0 turns off)'
example '$ v2gif foo.mov' example '$ v2gif foo.mov'
example '$ v2gif foo.mov -w 600' example '$ v2gif foo.mov -w 600'
@ -26,17 +27,19 @@ function v2gif {
example '$ v2gif -thw 600 *.avi *.mov' example '$ v2gif -thw 600 *.avi *.mov'
# Parse the options # Parse the options
args=$(getopt -l "alert:" -l "lossy:" -l "width:" -l del,delete -l high -l tag -l "fps:" -o "a:l:w:f:dht" -- "$@") local args=$(getopt -l "alert:" -l "lossy:" -l "width:" -l del,delete -l high -l tag -l "fps:" -o "a:l:w:f:dht" -- "$@")
use_gifski="" local use_gifski=""
del_after="" local del_after=""
maxsize="" local maxsize=""
lossiness="" local lossiness=""
maxwidthski="" local maxwidthski=""
giftagopt="" local giftagopt=""
giftag="" local giftag=""
fps=10 local defaultfps=10
alert=5000 local infps=""
local fps=""
local alert=5000
eval set -- "$args" eval set -- "$args"
while [ $# -ge 1 ]; do while [ $# -ge 1 ]; do
case "$1" in case "$1" in
@ -47,7 +50,7 @@ function v2gif {
;; ;;
-d|--del|--delete) -d|--del|--delete)
# Delete after # Delete after
del_after=true del_after="true"
shift shift
;; ;;
-h|--high) -h|--high)
@ -88,7 +91,7 @@ function v2gif {
done done
# Done Parsing, all that's left are the filenames # Done Parsing, all that's left are the filenames
movies="$*" local movies="$*"
if [[ -z "$movies" ]]; then if [[ -z "$movies" ]]; then
echo "$(tput setaf 1)No input files given. Example: v2gif file [file...] [-w <max width (pixels)>] [-l <lossy level>] < $(tput sgr 0)" echo "$(tput setaf 1)No input files given. Example: v2gif file [file...] [-w <max width (pixels)>] [-l <lossy level>] < $(tput sgr 0)"
@ -101,32 +104,46 @@ function v2gif {
for file in $movies ; do for file in $movies ; do
output_file="${file%.*}${giftag}.gif" local output_file="${file%.*}${giftag}.gif"
echo "$(tput setaf 2)Creating $output_file ...$(tput sgr 0)" # Set FPS to match the video if possible, otherwise fallback to default.
if [[ "$infps" ]] ; then
fps=$infps
else
fps=$defaultfps
if [[ -x /usr/bin/mediainfo ]] ; then
if /usr/bin/mediainfo "$file" | grep -q "Frame rate mode *: Variable" ; then
fps=$(/usr/bin/mediainfo "$file" | grep "Minimum frame rate" |sed 's/.*: \([0-9.]\+\) .*/\1/' | head -1)
else
fps=$(/usr/bin/mediainfo "$file" | grep "Frame rate " |sed 's/.*: \([0-9.]\+\) .*/\1/' | head -1)
fi
fi
fi
echo "$(tput setaf 2)Creating '$output_file' at $fps FPS ...$(tput sgr 0)"
if [[ "$use_gifski" = "true" ]] ; then if [[ "$use_gifski" = "true" ]] ; then
# I trust @pornel to do his own resizing optimization choices # I trust @pornel to do his own resizing optimization choices
ffmpeg -loglevel panic -i $file -r $fps -vcodec png v2gif-tmp-%05d.png && \ ffmpeg -loglevel panic -i "$file" -r $fps -vcodec png v2gif-tmp-%05d.png && \
gifski $maxwidthski --fps $fps -o $output_file v2gif-tmp-*.png || return 2 gifski $maxwidthski --fps $(printf "%.0f" $fps) -o "$output_file" v2gif-tmp-*.png || return 2
else else
ffmpeg -loglevel panic -i $file $maxsize -r $fps -vcodec png v2gif-tmp-%05d.png && \ ffmpeg -loglevel panic -i "$file" $maxsize -r $fps -vcodec png v2gif-tmp-%05d.png && \
convert +dither -layers Optimize v2gif-tmp-*.png GIF:- | \ convert +dither -layers Optimize v2gif-tmp-*.png GIF:- | \
gifsicle $lossiness --no-warnings --colors 256 --delay=$((100/fps)) --loop --optimize=3 --multifile - > $output_file || return 2 gifsicle $lossiness --no-warnings --colors 256 --delay=$(echo "100/$fps"|bc) --loop --optimize=3 --multifile - > "$output_file" || return 2
fi fi
rm v2gif-tmp-*.png rm v2gif-tmp-*.png
# Checking if the file is bigger than Twitter likes and warn # Checking if the file is bigger than Twitter likes and warn
if [[ $alert -gt 0 ]] ; then if [[ $alert -gt 0 ]] ; then
out_size=$(wc --bytes < $output_file) local out_size=$(wc --bytes < "$output_file")
if [[ $out_size -gt $(( alert * 1000 )) ]] ; then if [[ $out_size -gt $(( alert * 1000 )) ]] ; then
echo "$(tput setaf 3)Warning: $output_file is $((out_size/1000))kb, keeping $file even if --del requested.$(tput sgr 0)" echo "$(tput setaf 3)Warning: '$output_file' is $((out_size/1000))kb, keeping '$file' even if --del requested.$(tput sgr 0)"
del_after="" del_after=""
fi fi
fi fi
[[ "$del_after" = "true" ]] && rm $file [[ "$del_after" = "true" ]] && rm "$file"
done done