綺麗なGIFアニメを作る（カラーパレットを自動作成し適用）

# はじめに
FFmpegで動画ファイルから、綺麗なGIFアニメが作れます。
結論から書いてしまうと、「FFmpegで綺麗なGIFにするためのパレットを自動作成し、適用」でOKです。
FFmpegのコマンド入力のみで完結するので、一度覚えてしまえば簡単です。

- FFmegで綺麗なGIFアニメを作る方法。 
- macOSの機能で画面録画して、動画ファイルを作成。
- 動画ファイルをFFmpegでGIFアニメに変換（簡単な編集も）。

についてこの記事ではまとめています。


# Macで画面を録画
MacはOSの基本機能`commando + shift + 5`で画面録画が可能。
録画ファイルは`.mov`形式でデスクトップに保存される。

Macの画面をビデオに収録する方法 — Appleサポート
https://www.youtube.com/watch?v=v8fwj_OUBVA


# FFmpegでGIF変換
## FFmpeg（エフエフエムペグ）とは？
動画と音声をコマンドラインで変換できるソフト。

FFmpeg
https://www.ffmpeg.org/

## インストール
```terminal
$ brew install ffmpeg
```
ターミナルを起動して、HomebrewでFFmpegをインストール。


### 起動の前に
**デスクトップの動画を変換するときは...**

```terminal
$ cd /Users/ユーザー名/Desktop/
```
macOSの基本機能で画面録画すると、動画ファイルはデスクトップに保存されるので、ターミナルより`cd`で`Desktop`へ移動しておくとスムーズ。


## 基本の変換
```terminal:基本構文
$ ffmpeg 入力オプション -i 入力ファイル名 出力オプション 出力ファイル名
```
⬇︎ 変換例（オプションは省略可）

```terminal:input.movをoutput.gifへ変換
$ ffmpeg -i input.mov output.gif
```


# よく使うコマンド
基本の変換に以下のオプションを組み合わせれば編集も可能。

## フレームレート
```terminal:1秒間に10枚使用
$ ffmpeg -i input.mov -r 10 output.gif
```
`-r` 1秒間に使用するフレームレート(コマ数)をfpsで指定。

指定した値で、滑らかさとファイルサイズが決まる。
値が大きいほどコマ数が増えて滑らかに見えるが、ファイルサイズも大きくなる。
（何も指定しないと、元ファイルと同じfpsになり、重たいgifファイルが出来上がる）


## ループ回数
```terminal:ループさせない
$ ffmpeg -i input.mov -loop -1 output.gif
```

`-loop` ループ回数を指定
ループさせない場合は`-1`、無限ループは`0`を指定。


## 切り出し（開始と切出し秒数を指定）
```terminal:動画の開始５秒目から１0秒間を切り出す
$ ffmpeg -i input.mov -t 10 -ss 5 output.gif
```

```terminal:hh-mm-ssで指定
$ ffmpeg -i input.mov -t "hh:mm:ss" -ss "hh:mm:ss" output.gif
```

`-t` 切り出したい秒数
`-ss` 切り出しを開始する頭の秒数

※ 指定する秒数は、動画ファイルを`QuickTime Timeplayer`で確認しておけばスムーズ。

```terminal:動画の開始0秒から120秒までを切り出す
$ ffmpeg -i input.mov -t 120 -c copy output.gif
```

```terminal:動画の開始30秒目から最後まで切り出す
$ ffmpeg -i input.mov -ss 30 -c copy output.gif
```

`-t`や`-ss`だけの指定も可能です。

※ 上記のように`-c copy`オプションを指定すると、コーデックを再エンコードすることがないので処理は速いです。gif作成ではあまり必要ないかもしれませんが、動画を編集する際に役立ちます。

## リサイズ（アスペクト比を維持）
```terminal:横幅640に合わせて高さを調整（アスペクト比を維持）
$ ffmpeg -i input.mov -vf scale=640:-1 output.gif
```
`-vf`の`scale=横幅:高さ`で指定（`-vf`はビデオフィルタ）
自動で設定したいほうに`-1`を指定。


## リサイズ（サイズを指定）
```terminal:横幅640x高さ320
$ ffmpeg -i input.mov -s 640x320 output.gif
```
`-s`の`横幅x高さ`で指定
自動で設定したいほうに`-1`を指定。


## 再生速度を変更
```terminal:再生速度2.0倍
$ ffmpeg -i input.mov -vf setpts=PTS/2.0 output.gif
```
`-vf`の`setpts=PTS/速度`で指定
2.0倍は`setpts=PTS/2.0`
0.5倍は`setpts=PTS/0.5`


## 組み合わせて実行
```terminal:組み合わせ
$ ffmpeg -i input.mov -r 10 -loop -1 -vf scale=640:-1 -t 10 -ss 5 output.gif
```
input.movをoutput.gifに変換
`フレームレート`：10
`ループ`：なし
`リサイズ`：横幅640に合わせて高さを調整（アスペクトを比維持）
`切り出し開始`：5秒目から
`切り出したい秒数`：10秒間


# 綺麗なGIFアニメにする方法
```terminal:綺麗なGIFアニメにする
$ ffmpeg -i input.mov -vf "split[a][b]; [a]palettegen[c]; [b][c]paletteuse" output.gif
```
全てのフレームから最適パレットな自動作成し、適用することで綺麗なGIFアニメになる。
`-vf`オプションに`split[a][b]; [a]palettegen[c]; [b][c]paletteuse`を指定すると、カスタムパレットを生成し適用する。

こちらの記事が参考になりました。
How do I convert a video to GIF using ffmpeg, with reasonable quality?
https://superuser.com/questions/556029/how-do-i-convert-a-video-to-gif-using-ffmpeg-with-reasonable-quality

```terminal:綺麗なGIFアニメにする（フレームレート、リサイズ、再生速度も設定）
$ ffmpeg -i input.mov -vf "fps=10, scale=640:-1, setpts=PTS/2.0, split[a][b]; [a]palettegen[c]; [b][c]paletteuse" output.gif
```
パレットと同時に`フレームレート`と`リサイズ`も`再生速度`も設定する場合は`-vf`オプションで指定する。
`フレームレート`：fps=10
`リサイズ`：scale=640:-1
`再生速度`：setpts=PTS/2.0



## 切り出しとループも組み合わせる
```terminal:
$ ffmpeg -i input.mov -vf "fps=10, scale=640:-1, setpts=PTS/2.0, split[a][b]; [a]palettegen[c]; [b][c]paletteuse" -loop -1 -t 10 -ss 5 output.gif
```
紹介した内容をすべて組み合わせた全部入り。


# 参考
[Macの画面をビデオに収録する方法 — Appleサポート](https://www.youtube.com/watch?v=v8fwj_OUBVA)
[Mac で画面を収録する方法](https://support.apple.com/ja-jp/HT208721)
[それFFmpegで出来るよ！](https://qiita.com/cha84rakanal/items/e84fe4eb6fbe2ae13fd8)
[FFmpegで動画をGIFに変換](https://qiita.com/wMETAw/items/fdb754022aec1da88e6e)
[How do I convert a video to GIF using ffmpeg, with reasonable quality?](https://superuser.com/questions/556029/how-do-i-convert-a-video-to-gif-using-ffmpeg-with-reasonable-quality)


# おわりに
画面の操作や手順の説明したいけど、文字だけでは伝わりにくい...
そんなとき動画で説明できると、伝わりやすく便利かと思います。