From 3a90bf18fbec190c1b504e683f4292509c27b19b Mon Sep 17 00:00:00 2001 From: Ira Abramov Date: Mon, 20 Nov 2017 19:38:46 +0200 Subject: [PATCH] New and improved/enhanced vid-to-gif function --- plugins/available/v2gif.plugin.bash | 118 ++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 plugins/available/v2gif.plugin.bash diff --git a/plugins/available/v2gif.plugin.bash b/plugins/available/v2gif.plugin.bash new file mode 100644 index 00000000..744895ca --- /dev/null +++ b/plugins/available/v2gif.plugin.bash @@ -0,0 +1,118 @@ +cite about-plugin +about-plugin 'video to gif helper functions' + +# From https://gist.github.com/SlexAxton/4989674#comment-1199058 +# 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 on Ubuntu: sudo apt install ffmpeg imagemagick ; plus install https://github.com/pornel/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) +# for high quality huge files. +function v2gif { + about 'Converts a .mov/.avi/.mp4 file into an into an animated GIF.' + group 'gif' + param '1: MOV/AVI/MP4 file name(s)' + param '2: -w ; Optional: max width in pixels' + param '3: -l ; Optional: extra lossy level for smaller files (80-200 make sense, needs giflossy instead of gifsicle)' + param '4: -h ; Optional: high quality using gifski (installed seperately)' + 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 '7: -f ; Optional: Change number of frames per second (default 10)' + example '$ v2gif foo.mov' + example '$ v2gif foo.mov -w 600' + example '$ v2gif -l 100 -d *.mp4' + example '$ v2gif -dh *.avi' + example '$ v2gif -thw 600 *.avi *.mov' + + # Parse the options + args=$(getopt -l "lossy:" -l "width:" -l del,delete -l high -l tag -l "fps:" -o "l:w:f:dht" -- "$@") + + use_gifski="" + del_after="" + maxsize="" + lossiness="" + maxwidthski="" + giftagopt="" + giftag="" + fps=10 + eval set -- "$args" + while [ $# -ge 1 ]; do + case "$1" in + --) + # No more options left. + shift + break + ;; + -d|--del|--delete) + # Delete after + del_after=true + shift + ;; + -h|--high) + #High Quality, use gifski + use_gifski=true + giftag="${giftag}-h" + shift + ;; + -w|--width) + maxsize="-vf scale=$2:-1" + maxwidthski="-W $2" + giftag="${giftag}-w$2" + shift 2 + ;; + -t|--tag) + # mark with a quality tag + giftagopt="true" + shift + ;; + -l|--lossy) + # Use giflossy parameter + lossiness="--lossy=$2" + giftag="${giftag}-l$2" + shift 2 + ;; + -f|--fps) + # select fps + fps="$2" + giftag="${giftag}-f$2" + shift 2 + ;; + esac + done + + # Done Parsing, all that's left are the filenames + movies="$*" + + if [[ -z "$movies" ]]; then + echo "$(tput setaf 1)No input files given. Example: v2gif file [file...] [-w ] [-l ] < $(tput sgr 0)" + return 1 + fi + + # Prepare the quality tag if requested. + [[ -z "$giftag" ]] && giftag="-default" + [[ -z "$giftagopt" ]] && giftag="" + + for file in $movies ; do + + output_file="${file%.*}${giftag}.gif" + + echo "$(tput setaf 2)Creating $output_file ...$(tput sgr 0)" + + if [[ "$use_gifski" = "true" ]] ; then + # I trust @pornel to do his own resizing optimization choices + 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 + else + ffmpeg -loglevel panic -i $file $maxsize -r $fps -vcodec png v2gif-tmp-%05d.png && \ + 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 + fi + + rm v2gif-tmp-*.png + + [[ "$del_after" = "true" ]] && rm $file + + done + + echo "$(tput setaf 2)Done.$(tput sgr 0)" +}