#!/usr/bin/env /bin/bash
#
# Author: Lilian BESSON
# Email: Lilian.BESSON[AT]ens-cachan[DOT]fr
# Date: 27-12-2015
#
# A script to convert a buntch of gif animated files to MP4 movies.
# Copyright (C) 2015 Lilian BESSON (lbesson at ens-cachan dot fr)
#
# Find the latest version on http://perso.crans.org/besson/bin/gif2mp4.sh
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see ,
# or .
#
# Requires:
# - convert (imagemagick),
# - ffmpeg (or avconv).
#
# References:
# - https://sonnguyen.ws/convert-gif-to-mp4-ubuntu/
# - http://apple.stackexchange.com/a/103834
#
# TODO:
# - add an argument to cycle X times over the input gif file, with the trick explained here http://video.stackexchange.com/a/12906
#
version="0.2"
wdir="/tmp/gif2mp4/frames/"
wbackup="/tmp/gif2mp4/backup/"
# If possible, use ~/.color.sh (http://perso.crans.org/besson/bin/.color.sh)
[ -f ~/.color.sh ] && ( . ~/.color.sh ; clear )
gif2mp4f (){
olddir="$(pwd)"
mkdir --parents "${wdir}"
f="$(basename "$1")"
dossier="$(dirname "$1")"
# If MP4, find the appropriate gif source
f="${f//.mp4/.gif}"
# If .gif was not there, add it
f="${f%.gif}.gif"
dest="${f%.gif}.mp4"
# Special hack. DURTY XXX
if [ "${dossier:0:6}" = "/home/" ]; then
p="$(pwd)/"
else
p="$(pwd)/${dossier}"
fi
echo -e "Working with ${u}'${f}'${U} on ${blue}'${p}'${white}."
# echo -e "Starting, going to /tmp/gif2mp4/frames/..."
# cd "${wdir}"
if [ -f "${p}"/"${dest}" ]; then
echo -e "WARNING: The file ${u}'${dest}'${U} (from ${blue}'${p}'${white}) is ${red}already present${white}"
echo -e "${green}Backing up this file${white} to ${wbackup}..."
echo -e cp -vf "${p}"/"${dest}" "${wbackup}"
fi
# You can use two programs, Imagemagick's convert command and ffmpeg, to do this.
echo -e "\n${green}Converting the GIF file (${f}) to PNG frames...${white} (it can take a while)..."
echo -e convert -coalesce "${p}"/"${f}" "${wdir}"frames%04d.png
time convert -coalesce "${p}"/"${f}" "${wdir}"frames%04d.png
# Then convert the pngs to a movie:
echo -e "\n${green}Converting the PNG frames to a MP4 movie (${dest})...${white} (it can take a while)..."
echo -e ffmpeg -r 10 -i "${wdir}"frames%04d.png -vcodec mjpeg -y "${p}"/"${dest}"
time ffmpeg -r 10 -i "${wdir}"frames%04d.png -vcodec mjpeg -y "${p}"/"${dest}"
# avconv -r 8 -i "${wdir}"/frames%04d.png -qscale 4 "${p}"/"${dest}"
# echo -e "Done, going back to ${olddir}..."
# cd "${olddir}"
}
# Use this function
log=/tmp/gif2mp4_$$.log
echo -e "$0 have been called with the arguments (after processing the options) : ${blue}$@${white}." | tee -a "${log}"
for i in "$@"; do
# echo -e "Calling the function ${magenta}'gif2mp4f'${white} for the argument ${u}'${i}'${U} (on pwd = $(pwd))..." | tee -a "${log}"
# gif2mp4f "$i" | tee -a "${log}" # I don't use this complicated function anymore
echo -e "Using ${magenta}'ffmpeg'${white} for the file ${u}'${i}'${U} (on pwd = $(pwd))..." | tee -a "${log}"
echo -e "${warning}This can take a while...${white}"
# This one-liner command is better! Cf. http://unix.stackexchange.com/a/294892
echo ffmpeg -f gif -i "$i" -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" "${i%.gif}.mp4" | tee -a "${log}"
time ffmpeg -f gif -i "$i" -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" "${i%.gif}.mp4" | tee -a "${log}"
echo -e "Done for ${magenta}'gif2mp4f'${white} on ${u}'${i}'${U}..." | tee -a "${log}"
done
# echo -e "${red}Warning: Can I delete all the frames files?${white}"
# ls "${wdir}"frames*.png
# rm -rvI "${wdir}"frames*.png
# End of gif2mp4.sh