From 3a90bf18fbec190c1b504e683f4292509c27b19b Mon Sep 17 00:00:00 2001 From: Ira Abramov Date: Mon, 20 Nov 2017 19:38:46 +0200 Subject: [PATCH 1/3] 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)" +} From 605f30381fce64593e9b083f410c304119dbe755 Mon Sep 17 00:00:00 2001 From: Ira Abramov Date: Wed, 22 Nov 2017 14:43:02 +0200 Subject: [PATCH 2/3] Add alerting feature - warn if the resulting GIF is too large for twitter or other threasholds. --- plugins/available/v2gif.plugin.bash | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/plugins/available/v2gif.plugin.bash b/plugins/available/v2gif.plugin.bash index 744895ca..443fbb28 100644 --- a/plugins/available/v2gif.plugin.bash +++ b/plugins/available/v2gif.plugin.bash @@ -14,10 +14,11 @@ function v2gif { 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 '4: -h ; Optional: high quality using gifski (installed seperately) - overrides "--lossy" above!' 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)' + param '8: -a ; Optional: Alert if resulting file is over kilobytes (default is 5000, 0 turns off)' example '$ v2gif foo.mov' example '$ v2gif foo.mov -w 600' example '$ v2gif -l 100 -d *.mp4' @@ -25,7 +26,7 @@ function v2gif { 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" -- "$@") + 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="" del_after="" @@ -35,6 +36,7 @@ function v2gif { giftagopt="" giftag="" fps=10 + alert=5000 eval set -- "$args" while [ $# -ge 1 ]; do case "$1" in @@ -77,6 +79,11 @@ function v2gif { giftag="${giftag}-f$2" shift 2 ;; + -a|--alert) + # set size alert + alert="$2" + shift 2 + ;; esac done @@ -110,6 +117,15 @@ function v2gif { rm v2gif-tmp-*.png + # Checking if the file is bigger than Twitter likes and warn + if [[ $alert -gt 0 ]] ; then + out_size=$(wc --bytes < $output_file) + 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)" + del_after="" + fi + fi + [[ "$del_after" = "true" ]] && rm $file done From 7935ca483487f2126c503734a234420167631221 Mon Sep 17 00:00:00 2001 From: Ira Abramov Date: Wed, 22 Nov 2017 14:44:09 +0200 Subject: [PATCH 3/3] @lwinkler suggested this takes over the old plugin. --- plugins/available/gif.plugin.bash | 140 ++++++++++++++++++++++++---- plugins/available/v2gif.plugin.bash | 134 -------------------------- 2 files changed, 120 insertions(+), 154 deletions(-) delete mode 100644 plugins/available/v2gif.plugin.bash diff --git a/plugins/available/gif.plugin.bash b/plugins/available/gif.plugin.bash index 596111cd..443fbb28 100644 --- a/plugins/available/gif.plugin.bash +++ b/plugins/available/gif.plugin.bash @@ -1,34 +1,134 @@ cite about-plugin -about-plugin 'gif helper functions' +about-plugin 'video to gif helper functions' # From https://gist.github.com/SlexAxton/4989674#comment-1199058 -# Requirements (Mac OS X using Homebrew): brew install ffmpeg gifsicle imagemagick -function gifify { - about 'Converts a .mov file into an into an animated GIF.' +# 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 file name' - param '2: max width in pixels (optional)' - example '$ gifify foo.mov' - example '$ gifify foo.mov 600' + 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) - overrides "--lossy" above!' + 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)' + param '8: -a ; Optional: Alert if resulting file is over kilobytes (default is 5000, 0 turns off)' + 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' - if [ -z "$1" ]; then - echo "$(tput setaf 1)No input file given. Example: gifify example.mov [max width (pixels)]$(tput sgr 0)" + # 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" -- "$@") + + use_gifski="" + del_after="" + maxsize="" + lossiness="" + maxwidthski="" + giftagopt="" + giftag="" + fps=10 + alert=5000 + 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 + ;; + -a|--alert) + # set size alert + alert="$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 - output_file="${1%.*}.gif" + # Prepare the quality tag if requested. + [[ -z "$giftag" ]] && giftag="-default" + [[ -z "$giftagopt" ]] && giftag="" - echo "$(tput setaf 2)Creating $output_file...$(tput sgr 0)" + for file in $movies ; do - if [ ! -z "$2" ]; then - maxsize="-vf scale=$2:-1" - else - maxsize="" - fi + output_file="${file%.*}${giftag}.gif" - ffmpeg -loglevel panic -i $1 $maxsize -r 10 -vcodec png gifify-tmp-%05d.png - convert +dither -layers Optimize gifify-tmp-*.png GIF:- | gifsicle --no-warnings --colors 256 --delay=10 --loop --optimize=3 --multifile - > $output_file - rm gifify-tmp-*.png + 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 + + # Checking if the file is bigger than Twitter likes and warn + if [[ $alert -gt 0 ]] ; then + out_size=$(wc --bytes < $output_file) + 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)" + del_after="" + fi + fi + + [[ "$del_after" = "true" ]] && rm $file + + done echo "$(tput setaf 2)Done.$(tput sgr 0)" } diff --git a/plugins/available/v2gif.plugin.bash b/plugins/available/v2gif.plugin.bash deleted file mode 100644 index 443fbb28..00000000 --- a/plugins/available/v2gif.plugin.bash +++ /dev/null @@ -1,134 +0,0 @@ -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) - overrides "--lossy" above!' - 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)' - param '8: -a ; Optional: Alert if resulting file is over kilobytes (default is 5000, 0 turns off)' - 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 "alert:" -l "lossy:" -l "width:" -l del,delete -l high -l tag -l "fps:" -o "a:l:w:f:dht" -- "$@") - - use_gifski="" - del_after="" - maxsize="" - lossiness="" - maxwidthski="" - giftagopt="" - giftag="" - fps=10 - alert=5000 - 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 - ;; - -a|--alert) - # set size alert - alert="$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 - - # Checking if the file is bigger than Twitter likes and warn - if [[ $alert -gt 0 ]] ; then - out_size=$(wc --bytes < $output_file) - 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)" - del_after="" - fi - fi - - [[ "$del_after" = "true" ]] && rm $file - - done - - echo "$(tput setaf 2)Done.$(tput sgr 0)" -}