その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

シェルスクリプトでmp4からアニメーションgifを生成する

mp4からアニメーションgifを生成したい、というケースが最近ちょくちょくありまして。


たとえば「GitHub の README に動く様子を載せたい」場合、YouTubeやVimeoの埋め込みタグをREADME.mdに載せてもプレイヤーを表示してくれないので、アニメーションgifをつくって載せています。

元の動画はQuickTimeでシミュレータのキャプチャ動画を撮ったものだったり、iPhoneのカメラで撮ったものだったりするのですが、アニメーションgifへの変換はどういう方法があるのか知らなかったので、

  • QuickTimeで動画を短くトリムする
  • Photoshopで動画を読み込んで適当にフレーム飛ばしてAnimation Gifに書き出す

という非常に面倒なことをやっていました。


で、ふと下記記事を見ていると、

「90sのmp4から12fpsで320*180のアニメgifを作る」スクリプトが例に挙げられています。


高速化云々以前に、そんな便利なことができたのか!と。


というわけで試してみました。

準備

まず、自分の環境にはffmpegが入ってなかったのでインストール。

$ brew install ffmpeg


あとアニメーションgifを生成する gifsicle もインストールする必要があるのですが、brew installしようとすると

gifsicle: Unsatisfied dependency: XQuartz
Homebrew does not package XQuartz. Installers may be found at:
https://xquartz.macosforge.org

と怒られたので、エラー文の言う通りに https://xquartz.macosforge.org に行って、インストーラから XQuart をインストール。


で、あらためて gifsicle をインストール。

$ brew install gifsicle

シェルスクリプト作成

$ touch gen_animegif.sh
$ vi gen_animegif.sh


で以下のように編集(shellわからないので、元記事のコードをほぼそのままお借りしています)。

#!/bin/sh

# Task 1
SRC="$1"
[[ ! -f "$SRC" ]] && echo 'no exists' && exit 1
INI=$SECONDS
mkdir ./temp

# Task 2-3
ffmpeg -loglevel panic -ss 0 -i "$SRC" -r 12 -an -f image2 -s 320x180 "./temp/%03d.gif"
gifsicle -O3 --batch ./temp/*.gif

# Task 4
gifsicle ./temp/*.gif > output.gif
rm -rf ./temp
echo "done with `expr $SECONDS - $INI`s" && exit 0

実行してみる

$ sh ./gen_animegif.sh xxxx.mp4

23.9MB の mp4 動画ファイルが、コマンド一発で1.7MBのgifアニメに!


movファイルも試してみました。

$ sh ./gen_animegif.sh xxxx.mov

24MB → 5.1MBに!

問題点

上記shellだと、mp4(iPhoneで撮影)は出力ファイルにおける動画の向きが90度回転してしまい、mov(QuickTimeでスクリーンキャプチャ)は元々縦長だった動画が横長になって上下方向につぶれた感じになってしまいました。きちんと向きを処理する必要がありそうです。

まとめ

シェルスクリプト、他にも知らずに損してることがたくさんありそうです。勉強します。