FFmpegを利用した動画の合成、クロマキー合成

## **はじめに**

仕事や私用でちょくちょく使う機会のあるFFmpeg。記憶がなくなる前に以前調べた動画合成+クロマキーに関する情報を残しておきます。

## **FFmpegとは何ぞや?**

動画と音声を記録・変換・再生するためのツールです。Windows, Mac, LinuxどのOSにも対応しており、動画のエンコードだけではなくストリーミング等も出来る優れものです。

### **FFmpegのいいところ**

**様々な形式の動画を扱うことが出来る**

使い方としては`ffmpeg -i 入力動画 オプション色々設定 出力動画`という形で表現するのですが、この入力、出力動画の種類が本当に豊富です。

- 通常PCで再生できる動画はもちろんサポート
- 連続静止画⇔動画の変換が可能。

例:
```
ffmpeg -i input.mp4 -vcodec copy output/%06d.jpg
```

- 入力にRTP等のストリーミング配信URLを指定することが可能

RTPサーバー作成することがあれば便利な機能です。

**オプションパラメーターが豊富**

サイズやコーデック、フレームレートの変更はもちろんのこと、動画の合成(今回紹介)等色々なことが出来ます。
その他ほんとに色々なことの出来る面白いツールです。

**再生・動画解析コマンドもついてくる**

FFmpegをインストールすると、エンコード用のffmpegだけでなく再生専用のffplayというコマンドや、1フレーム毎の情報まで解析可能なffprobeというコマンドまでついてきます。
そのおかげで、エンコードツールとしてだけではなく、RTPストリーミングや動画の情報を確認したい時に便利なクライアントツールとしても使えます。

### **インストール**

以下からダウンロードできます。
https://www.ffmpeg.org/download.html

**Windowsの場合:**
ビルド済みのツールが展開されているので、ダウンロードしたzipファイルを展開すればそのまま使えます。

**Linuxの場合:**
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg してビルドします。ただデフォルトではH.264やH.265等他の圧縮形式が含まれていないので、別途FFmpegがサポートしているライブラリをインストールする必要があります。
例えばH.264ならx264等

## **動画の合成**

今回はFFmpegを使って以下2つの動画を重ねてみます。

<img width="540" alt="sky_540p.gif" src="https://qiita-image-store.s3.amazonaws.com/0/252277/e08b1539-e704-8788-9325-2d757368a865.gif">  <img width="320" alt="fire_320p.gif" src="https://qiita-image-store.s3.amazonaws.com/0/252277/53193730-7568-24d6-10d7-f337fec7df28.gif">

### **単純に動画を重ねる**

動画を重ねるのは、FFmpegのフィルタ機能であるoverlayコマンドで可能です

```
ffmpeg -i sky_540.mp4 -i fire_320.mp4 -filter_complex "overlay=x=0:y=0" -preset ultrafast merge.mp4
```

overlayの後のx, yは合成する位置の指定です。0,0は左端。
実行結果は以下のように動画を上からそのまま重ねる形になります。合成後の音声は最初の入力動画のみが聞こえます。

![merge.gif](https://qiita-image-store.s3.amazonaws.com/0/252277/6e389039-4ef8-55f4-15d4-7a11656fc976.gif)

### **クロマキー合成**

動画が重ねられるだけでも色々面白いですが、黒背景が邪魔なので、黒部分を透過したクロマキー合成をしてみます。
コマンド例は以下。

```
ffmpeg -i sky_540p.mp4 -i fire_320p.mp4 -filter_complex "[1:0]colorkey=black:0.01:1[colorkey];[0:0][colorkey]overlay=x=0:y=0" -preset ultrafast combine.mp4
```

結果このように余計な黒背景がなくなります。
![combine.gif](https://qiita-image-store.s3.amazonaws.com/0/252277/0c151e16-f412-8c52-bfc1-4cceaead65f5.gif)

以下filter_complex内のコマンドオプションを説明

#### **複数のfilter_complexを組み合わせる方法の解説**

今回のコマンド例では、`colorkey=black:0.01:1`(背景黒色を透過する)と、`overlay=x=0:y=0`(動画を合成する)という2つのオプションを組み合わせています。
filter_complexで複数のオプションを組み合わせる場合は、`[入力情報]option[出力動画名の定義]`(最後のオプションは出力名省略)という記載を繰り返します。
[0:0], [1:0]はそれぞれ入力動画の1つ目、2つ目の意味。

このことを踏まえてコマンド例のオプションを説明すると、

1. `[1:0]colorkey=black:0.01:1[colorkey]`⇒2つ目の入力動画に対して背景黒色を透過した動画を作成し、[colorkey]という名前を付ける
2. `[0:0][colorkey]overlay=x=0:y=0`⇒１つ目の入力動画と、1で作成した[colorkey]動画を重ねる

となります。このfilter_complexオプションのおかげで、1コマンドで様々な動画変換・合成を行うことが可能です。

例えば透過合成の例は以下サイトのように、うまくfilter_complexでオプションを組み合わせて表現することが出来ます。
[FFMPEG を使って透過したオーバーレイ動画を作る](http://nico-lab.net/ffmpeg_overlay_two_videos_transparency/)

### **おまけ: 音声を重ねる**

音声合成にはamixというオプションを使います。

```
ffmpeg.exe -i inputA.mp3 -i inputB.mp3 -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -t 15 output.mp3
```

## **参考**

クロマキー合成: [FFMPEG でクロマキー合成](http://nico-lab.net/ffmpeg_with_chroma_key_by_colorkey/)
透過合成: [FFMPEG を使って透過したオーバーレイ動画を作る](http://nico-lab.net/ffmpeg_overlay_two_videos_transparency/)
情報量の多いサイト: [Windows の ffmpeg で生放送する方法](http://looooooooop.blog35.fc2.com/blog-entry-903.html#fovl)
音声の合成: [ffmpeg の -filter_complex オプション amix のinputsが取れる最大値は32 ヽ(ﾟｰﾟ*ヽ)(ﾉ*ﾟｰﾟ)ﾉわぁい](https://qiita.com/scleen_x_x/items/c2af43843393f5d4729d)
gifの作成:[FFmpegで動画をGIFに変換](https://qiita.com/wMETAw/items/fdb754022aec1da88e6e)