FFmpegの応用...?

前回↓

https://qiita.com/Frezledz/items/bc096102b11ef7532595

# 前回の深堀り

前回(前々回？)、いくつかよくわからないものが出てきましたね。ここで意味がやっと分かるでしょう。
## pix_fmt
```
ffmpeg -i input.webm -pix_fmt yuv420p output.mp4
```
このpix_fmtの正体は**各ピクセルにどのように保存するか**を示すものとなります。RGB、YUV、grayscaleなどです。mp4変換において、指定がないとyuv444という形式を使いますが、この形式に対応しているメディアプレイヤーは少数です。だから再生できないという事象が起きていたのです。
もっと詳しく↓

https://qiita.com/Yossy_Hal/items/8e0b9676698ba552c210

```
ffmpeg -i input.mp4 -vf "scale=640x360" output.mp4
```
# vf
これがいわゆるフィルタ処理の為のコマンドになります。FFmpegのフィルタの数は膨大なので、ここで全種類紹介するのはまあ不可能です。
ここでは解像度を変更しています。
![解像度](https://imagedelivery.net/q8waNcDoYpxPiqSgqF_zaw/84b70cb5-1895-45b3-fd9a-23db582ef700/w=9999)

```
ffmpeg -i input.mp4 -vf "scale=640x360,rotate=PI*0.5" output.mp4
```
このように、フィルタを一つずつカンマで区切って適用していきます。ここでは解像度を640x360にし、90度(pi/2)回転させていますね。

# フィルタいろいろ
## フェードイン
```
ffmpeg -i input.mp4 -vf "fade=type=in:duration=2,afade=type=in:duration=2" out.mp4
```
inとoutがあって、durationで調整。fadeの方は動画、afadeは音声に対してです。
## クロマキー
```
ffmpeg -i input -vf "chromakey=0x00ff00:similarity=0.1" output.avi
```
三つ話すことがあります。
まず、フィルタを使う上で自分が入力する値は当たり前ですが常に一つだけではありません。複数必要な時は、:で区切ってください。
まずはこの0xff00。これはカラーコードです。0x(16進数カラーコード)という形式で書きます。赤なら0xff0000、緑なら0x00ff00、青なら0x0000ffですね。
![hex](https://htmlcolors.com/img/hex-color.jpg)
二つ目に、なぜAVIファイルを選んだのか。
mp4ファイルは動画の透明度を記録することができません。Aviファイルは圧縮効率がかなり悪いですが、透明度に対応しています。
以下のテーブルを参考にどうぞ。
| フォーマット | 透明度対応 |
|:-:|:-:|
|mp4|no|
|webm|yes|
|avi|yes|
|jpeg|no|
png|yes|
|gif|no|

## ブラー
```
ffmpeg -i input -vf "avgblur=sizeX=3:sizeY=3" output.mp4
```
特にいうこともない。


# filter_complex
ここまでvfの解説をしてきましたが、少し自由度が低いのは否めないです。これよりも更に自由度の高い、filter_complexを紹介します。
非常に強力なコマンドです。どのメディアにフィルタをかけて、組み合わせて...ということを細かく指定できます。クロマキー処理をして別の動画に張り付けるコマンドを例に紹介します。巷ではクロマキー合成と呼ばれていますね。

```
ffmpeg -i video.mp4 -i back.png -filter_complex " [0:v]chromakey=color=0x00FF00:similarity=0.1,scale=1920x1080[trans];[1:v]scale=1920x1080[back]; [back][trans]overlay[out]" -map [out] -map 0:a out.mp4
```

一気に長くなりましたね。見やすくするためにいったん改行します。
```
ffmpeg -i video.mp4 -i back.png 
-filter_complex "
[0:v]chromakey=color=0x00FF00:similarity=0.1,scale=1920x1080[trans];
[1:v]scale=1920x1080[back];
[back][trans]overlay[out]
"
-map [out] -map 0:a out.mp4
```
まずはクロマキー処理をしたい動画と、背景画像を読み込みます。
そしてfilter_complexフィルタ。これもあくまで引数のうちの一つに過ぎないので、ダブルクォーテーション("")で囲む必要があります。
### filter_complexの処理内容 
1. [0:v]、0番目の動画を読み込んで、クロマキー処理をします。そして、解像度を1920x1080にします。そして、これにtransと名付けます。
2. [1:v]、1番目の動画(画像だけど)を読み込んで、解像度を変更します。この後重ねるために必要な処理になります。そして、backと名付けます。
3. backを下、transを上で、オーバーレイを実行します。これをoutと名付けます。

フィルタをかけた後はダブルクォーテーション(;)で区切る必要があります。C言語などと同じですね。

### 出力
ストリーム[out]と0番目のオーディオを指定します。そして出力。

ちなみにfilter_complexはかなり機種差が激しいらしく、使えないデバイスもあるそうです。


# ハードウェアアクセラレーション
FFmpegのもう一つの武器でしょう。GPUなどを使って処理を爆速化出来ます。私もあまり理解度は深くありませんが、速い。とにかく速い。

https://trac.ffmpeg.org/wiki/HWAccelIntro

### Nvidia GPU

```
ffmpeg -i %00d.png -c:v h264_nvenc NVoutput.mp4
```
NvidiaのCUDAを使ったh264エンコードを使ってエンコードします。マジで速い。

これ、エンコードしたら分かると思うのですが、かなり画質が悪いです。libx264ほど気が利いているわけではなく、ビットレートを自分で指定して画質を調整する必要があります。

https://www.stream.co.jp/blog/blogpost-32369/

```
ffmpeg -i video.mp4 -c:v h264_nvenc -bf 3 -refs 4 -b:v 7M -vf scale=1920x1080 out.mp4
```
-b:vにあたるものが、ビットレートになります。ここでは7M、700万です。
どれぐらいかがいいかはもう動画によるとしか言えません。1920x1080のmp4だと6~8Millionぐらいがちょうどいい気がします。

Nvidia GPU以外にもありますが、ここでは割愛します。

# 自分で書けるようになろう
ここまで読んだ方、お疲れさまでした。これが理解できればある程度自分で書けるぐらいにはなるでしょう。ただ、どんなフィルタがあって何を指定すればいいかは把握できていないでしょう。私も全部覚えているわけなく、ほぼ毎回とある方法で情報を仕入れています。


大きく分けて二つあります。
### FFmpeg公式ドキュメントを見る

https://ffmpeg.org/ffmpeg.html

ここにffmpegのほぼすべての情報が載っています。物凄い情報量ですね。

### FFmpegのヘルプコマンドを使う
```
ffmpeg -h
```
これでヘルプを得ることができます。ほかの情報を得るにはどうすればいいか、などの指示も書いてありますが、ここでもいくつか紹介します。
フィルタ一覧
```
ffmpeg -filters
```
エンコーダ一覧
```
ffmpeg -encoders
```
フォーマット一覧
```
ffmpeg -formats
```
フィルタそれぞれのヘルプを見る
```
ffmpeg -h filter=chromakey
```
ターミナルに出力されるデータは信じられないほど長いです。ターミナルは文字列の確認にはあまり向いていないので、テキストファイルに出力する方法を紹介します。これはffmpegだけでなく、基本的にどんなプログラムでも使えるので覚えておきましょう。
```
ffmpeg -filters > help.txt
```
```
> file.txt
```
これがキーワードです。あとはvimなりメモ帳なり、vimなりvimなりvimなりvimなりvimなりvimでみましょう。

私のffmpegの知識の8割ぐらいは放出しました。金払ってください(?)

続き(?)

https://qiita.com/Frezledz/items/41bc9bb32ef1663fbd79