iOSシミュレータで動画撮影+GIF変換してファイル圧縮もするバッチ(.command)


GitHubのプルリクに動画を添付できる機能がベータから正式版になったが、10MB以上だとアップロードできないので、（シミュレータで撮影した）動画をGIF変換してアップロードできる容量まで圧縮するバッチを用意しました。

**参考**

* [GitHubが動画のアップロード機能に正式対応。バグの再現手順や機能のデモなどの説明が動画で容易に － Publickey](https://www.publickey1.jp/blog/21/github_7.html)
* [iOS シミュレータで動画を収録して gif に自動で変換するスクリプトを書いた - Qiita](https://qiita.com/daichidaiji/items/db82f7aacd59b945fe86)


---
# 前準備

**ffmpegをインストール**

* ターミナルで以下のコマンドを入力して ffmpeg をインストールする
  * `brew install ffmpeg`

**バッチファイルを作成**

* テキストエディタなどで [simctl_recordVideo_gif.command](#バッチファイル) ファイルを作成する
* 保存する場所はどこでもお好きな場所で大丈夫です
* （私はプロジェクトファイルと同じディレクトリに util_command フォルダを作成して、そのフォルダ直下に .command ファイルを配置してます）

**バッチファイルに実行権限を付与**

* ターミナルで .command ファイルがあるディレクトリに移動
  * ターミナルで "cd "の後に .command ファイルがあるフォルダをドロップすれば、パスが自動入力されます
* `chmod u+x simctl_recordVideo_gif.command` を実行
* 参考: [Mac で git rebase master を自動でやるバッチ（.command） - Qiita](https://qiita.com/YokohamaHori/items/0391f02ff6cad75dfb57#%E5%AE%9F%E8%A1%8C%E6%A8%A9%E9%99%90%E3%82%92%E4%BB%98%E4%B8%8E)

## バッチファイル

simctl_recordVideo_gif.command

```bash:simctl_recordVideo_gif.command
#!/bin/bash

DATETIME=~/Desktop/`date +%Y%m%d_%H%M%S`
xcrun simctl io booted recordVideo $DATETIME.mov
ffmpeg -i $DATETIME.mov -vf scale=320:-1 -r 10 $DATETIME.gif
```

---
# 使い方

1. シミュレータを起動して動画撮影の準備をする（シミュレータが起動してないとエラー終了します）
1. `simctl_recordVideo_gif.command` を実行（commandファイルをダブルクリック or command + space で `record` or `_gif` と入力すれば出てくると思います）
1. ターミナルが起動して、動画撮影開始
1. シミュレータで撮影したい動作をする
1. 撮影を終了する時はターミナルで control + c を入力する
1. 撮影した動画(.mov, .gif)がデスクトップに保存されます

**備考**

* 動画ファイルの保存先をデスクトップ以外にしたい時は .command ファイルの以下を変更してください
  * ```DATETIME=~/Desktop/`date +%Y%m%d_%H%M%S````
* 圧縮率などのオプションを変更したい時は .command ファイルの以下を変更してください
  * `ffmpeg -i $DATETIME.mov -vf scale=320:-1 -r 10 $DATETIME.gif`
  * 参考: [ffmpegのオプションを色々試すバッチ](#ffmpegのオプションを色々試すバッチ)

---
# おまけ

## homebrewのインストールでエラーになった時

homebrewのインストール時に以下のエラーが発生

```
HEAD is now at d1a819986 Merge pull request #12620 from Homebrew/dependabot/bundler/Library/Homebrew/rubocop-1.24.0
Error:
  homebrew-core is a shallow clone.
To `brew update`, first run:
  git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
```

→エラーログに記載されている通りの git コマンドを打ってを打って解決

* `git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow`
* [Homebrew で Error: homebrew-core is a shallow clone が出て brew update が実行できない問題 | gotohayato.com](https://gotohayato.com/content/528/)


## ffmpegのインストールでエラーになった時

ffmpegのインストール時に以下のエラーが発生

```
...
cp: /private/tmp/d20211227-88398-77z05r/m4/.: unable to copy ACL to /usr/local/Cellar/m4/.: Bad file descriptor
Error: Failure while executing; `cp -pR /private/tmp/d20211227-88398-77z05r/m4/. /usr/local/Cellar/m4` exited with 1. Here's the output:
cp: /private/tmp/d20211227-88398-77z05r/m4/.: unable to copy extended attributes to /usr/local/Cellar/m4/.: Bad file descriptor
cp: /usr/local/Cellar/m4/./1.4.19: Permission denied
```

→以下のコマンドを打って解決

* `sudo chown -R $(whoami) /usr/local/Cellar`
* [brew install で `cp: chmod: /usr/local/Cellar/jemalloc/.: Operation not permitted`エラー - Qiita](https://qiita.com/tkek321/items/34ee207943a284478b57)


## simctlコマンドでエラーになった時

simctlコマンド実行時に以下のエラーが発生

```
xcrun: error: unable to find utility "simctl", not a developer tool or in PATH
```

→Xcode の Preferences から Locations で「Command Line Tools」を設定して解決

* [hawksnowlog: Xcode9 で simctl コマンドが使えない場合の対処方法](https://hawksnowlog.blogspot.com/2018/07/use-simctl-on-xcode9.html)


## ffmpegのオプションを色々試すバッチ

simctl_recordVideo_gif_Test.command

```bash:simctl_recordVideo_gif_Test.command
#!/bin/bash

DATETIME=~/Desktop/`date +%Y%m%d_%H%M%S`
xcrun simctl io booted recordVideo $DATETIME.mov
# ffmpeg -i $DATETIME.mov -vf scale=320:-1 -r 10 $DATETIME.gif

# ↓↓↓↓↓GIF変換だけしたい時はここでファイル名を指定
# DATETIME=~/Desktop/20211228_134356
# iPhone13Pro(シミュレータ)で24秒の動画(23.0MB)をGIF変換

ffmpeg -i $DATETIME.mov -vf scale=320:-1 -r 5 ${DATETIME}_320_5.gif
# →2.5MB
ffmpeg -i $DATETIME.mov -vf scale=320:-1 -r 10 ${DATETIME}_320_10.gif
# →4.3MB
ffmpeg -i $DATETIME.mov -vf scale=640:-1 -r 5 ${DATETIME}_640_5.gif
# →9.0MB
ffmpeg -i $DATETIME.mov -vf scale=640:-1 -r 10 ${DATETIME}_640_10.gif
# →15.3MB

ffmpeg -i $DATETIME.mov -filter_complex "[0:v] fps=5,scale=320:-1,split [a][b];[a] palettegen [p];[b][p] paletteuse" ${DATETIME}_320_5_palette.gif
# →5.2MB
ffmpeg -i $DATETIME.mov -filter_complex "[0:v] fps=10,scale=320:-1,split [a][b];[a] palettegen [p];[b][p] paletteuse" ${DATETIME}_320_10_palette.gif
# →9.7MB
ffmpeg -i $DATETIME.mov -filter_complex "[0:v] fps=5,scale=640:-1,split [a][b];[a] palettegen [p];[b][p] paletteuse" ${DATETIME}_640_5_palette.gif
# →19.1MB
ffmpeg -i $DATETIME.mov -filter_complex "[0:v] fps=10,scale=640:-1,split [a][b];[a] palettegen [p];[b][p] paletteuse" ${DATETIME}_640_10_palette.gif
# →35.7MB
```