Skip to content

Instantly share code, notes, and snippets.

@rixtox
Last active September 14, 2019 15:54
Show Gist options
  • Save rixtox/e9452cfa6f97c8cfbb7062aa07e34406 to your computer and use it in GitHub Desktop.
Save rixtox/e9452cfa6f97c8cfbb7062aa07e34406 to your computer and use it in GitHub Desktop.
Converts GIF to MP4 optimized for Telegram
#!/usr/bin/env bash
# Author: Rix
# Version: 0.0.1
set -eu -o errexit -o pipefail -o nounset
function print_usage {
echo 'Usage: gif2mp4 [-c] <[-r] INPUT> ...'
echo ' -c, --concat <OUTPUT> concat all inputs into single MP4'
echo ' -r, --repeat <COUNT> repeats count for following inputs'
}
function log {
local LEVEL="$1"
local MSG="$(date '+%D %T') [${LEVEL}] $2"
case "${LEVEL}" in
INFO*) MSG="\x1B[94m${MSG}\e[0m";;
WARNING*) MSG="\x1B[93m${MSG}\e[0m";;
ERROR*) MSG="\x1B[91m${MSG}\e[0m";;
*)
esac
echo -e "${MSG}"
}
function require {
if [ ! -x "$(command -v "$1")" ]; then
log "ERROR" "$1 is not found"'!' >&2
exit 1
fi
}
function join_by {
local IFS="$1"; shift; echo "$*"
}
require ffmpeg
INPUTS=()
REPEAT=()
CONCAT=""
CURRENT_REPEAT=1
while [[ $# -gt 0 ]]; do
OPT="$1"
case $OPT in
-c|--concat)
CONCAT="$2"
shift 2
;;
-r|--repeat)
CURRENT_REPEAT="$2"
shift 2
;;
-h|--help)
print_usage
exit 0
;;
-*)
print_usage
exit 2
;;
*)
INPUTS+=("$1")
REPEAT+=("${CURRENT_REPEAT}")
shift
;;
esac
done
INPUTS_LEN=${#INPUTS[@]}
if [[ ${INPUTS_LEN} -lt 1 ]]; then
print_usage
exit 2
fi
if [[ ${INPUTS_LEN} -eq 1 && -n "${CONCAT}" ]]; then
log WARNING "Skip concat for single input!"
CONCAT=""
fi
if [[ -n "${CONCAT}" ]]; then
mkdir -p $(dirname "${CONCAT}")
fi
OUTPUTS=()
for i in ${!INPUTS[*]}; do
INPUT="${INPUTS[$i]}"
if [[ -n "${CONCAT}" ]]; then
OUTPUT="${INPUT%.*}.ts"
else
OUTPUT="${INPUT%.*}.mp4"
fi
CMD=(ffmpeg -i "${INPUT}" -ignore_loop 1 -filter_complex "loop=$((${REPEAT[$i]}-1)):32767:0,scale=trunc(iw/2)*2:trunc(ih/2)*2" -y -pix_fmt yuv420p -c:v libx264 -crf 20)
if [[ -n "${CONCAT}" ]]; then
CMD+=(-bsf:v h264_mp4toannexb -f mpegts)
fi
CMD+=("${OUTPUT}")
"${CMD[@]}"
OUTPUTS+=("${OUTPUT}")
done
if [[ -n "${CONCAT}" ]]; then
ffmpeg -i "concat:$(join_by '|' "${OUTPUTS[@]}")" -y -pix_fmt yuv420p -c:v libx264 -crf 20 "${CONCAT}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment