Skip to content

Instantly share code, notes, and snippets.

@nimbling
Forked from troyane/mp42gif.sh
Last active June 7, 2019 10:15
Show Gist options
  • Save nimbling/ab8fab7f4276e2ebe473b3d24c02ec0c to your computer and use it in GitHub Desktop.
Save nimbling/ab8fab7f4276e2ebe473b3d24c02ec0c to your computer and use it in GitHub Desktop.
See script and documentation here: https://github.com/troyane/StackOverflow-pro/tree/master/mp42gif Script to convert MP4 file to GIF (via ffmpeg). It creates intermediate custom color palette out of input video file and use it for resulting GIF for better picture quality. For more info see https://superuser.com/a/556031
#!/bin/bash
#
# Script to convert MP4 video to GIF with generation of custom color palette.
#
#=== Do not touch code below
# Inner variables
input_file=""
input_fps="20"
input_width="512"
output_name="output"
max_colors="256"
# Great and simple idea got here: https://stackoverflow.com/a/53463162/867349
function cecho() {
RED="\033[0;31m"
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
printf "${!1}${2} ${NC}\n"
}
function wecho() { # warning, yellow
cecho "YELLOW" "[WARN] ${1}"
}
function eecho() { # error, red
cecho "RED" "[ERROR] ${1}"
}
function iecho() { # info, green
cecho "GREEN" "[INFO] ${1}"
}
if ! [ -x "$(command -v ffmpeg)" ]; then
eecho 'Error: ffmpeg is not installed.' >&2
wecho 'Install it by next command "sudo apt install ffmpeg" and run script again.'
wcho 'Exiting.'
exit 1
fi
function usage() {
cat <<HELP_USAGE
-i|--input Input MP4 file.
-f|--fps FPS frame per second rate as a number. Default FPS=20.
-w|--width Width value as a number. Script will scale input picture width to given number.
Default Width=512. Height will be calculated proportionally.
-o|--output Output GIF file. Default Name=output.gif.
-m|--maxcol Maximum amount of colors used in the generated palette
--help Show this usage info.
HELP_USAGE
exit 1
}
function parse_args() {
if [ "$#" -eq 1 ]
then
eecho "You need to specify arguments."
usage
exit 1
fi
while [[ "$#" -gt 0 ]];
do
case $1 in
-i|--input) input_file="$2"; shift;;
-f|--fps) input_fps="$2"; shift;;
-w|--width) input_width="$2"; shift;;
-o|--output) output_name="$2"; shift;;
-m|--maxcol) max_colors="$2"; shift;;
--help) usage ; exit 0;;
*) eecho "Unknown parameter passed: $1" ; usage;;
esac
shift
done
}
function convert() {
palette_file="palette.png"
if [ -z "$input_file" ]
then
eecho "No input file given."
usage
exit 1
fi
iecho "Create palette $palette_file out of $input_file"
ffmpeg -i "$input_file" \
-vf fps=$input_fps,scale=$input_width:-2:flags=lanczos,palettegen=max_colors=$max_colors\
$palette_file
if [ $? -eq 0 ]; then
iecho "Palette created."
else
eecho "Can't continue. Exiting."
exit 1
fi
basename="${input_file%.*}"
echo $basename
iecho "Create GIF file ($bf-$max_colors.gif) based on input file ($input_file) and palette ($palette_file)."
ffmpeg -i "$input_file" \
-i $palette_file \
-filter_complex "fps=$input_fps,scale=w=$input_width:h=-2:flags=lanczos[x];[x][1:v]paletteuse" \
$output_name"-fps"$input_fps"-maxcol"$max_colors.gif
if [ $? -eq 0 ]; then
iecho "Output file created:"
ls -lah "$output_name"-fps"$input_fps"-maxcol"$max_colors.gif"
else
eecho "Can't continue. Exiting."
fi
rm $palette_file
}
# Establish run order
function main() {
iecho "Starting..."
convert
iecho "Finished."
}
parse_args "$@"
main
@nimbling
Copy link
Author

nimbling commented Jun 7, 2019

I added a "max colors" variable, and inserted the fps and color amounts in the output filename, to allow for rapid comparison of different settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment