Real-ESRGANを使った動画の画質向上の方法について

# 概要
ダウンロードした動画やStable Diffusionで作った画像を高画質にしたいと思い実行したのですが、動画の高画質化が割と大変だったので備忘録としてまとめます。
# 目次
- 前提条件
- 動画の縮小
- フレームの切り出し
- 音声の抽出
- フレームごとの画質の向上
- フレームをまとめて動画へと再構成
- 構成した動画と音声の融合

# 前提条件
- GPUの保持
- ffmpegのインストール
- Real-ESRGANのインストール
上記の前提は満たしていることを前提として今後の話を進めていきたいと思います。今後これらのインストール方法についても記事をまとめたいです。Real-ESRGANのインストールはPytorchのバージョンやCUDAのバージョンのせいでかなり苦労したので。

# 動画の縮小
最初にffmpegを使って動画のを縮小します。
理由としては、画像のサイズが大きいと処理やメモリに負担がかかることと、縮小することによる画質の向上を目的として行っています。
以下に画像のサイズを変更するためのffmpegのコマンドを示します。

##### 例
input.mp4という動画ファイルを480x270にリサイズしてout.mp4という動画ファイルとして出力する。

```
ffmpeg -i input.mp4 -s 480x270 out.mp4
```


##### 例
input.mp4という動画ファイルをアスペクト比を維持したまま、横幅を480にリサイズしてout.mp4という動画ファイルとして出力する。

```
ffmpeg -i input.mp4 -vf scale=480:-1 out.mp4
```

##### 例
input.mp4という動画ファイルをアスペクト比を維持したまま、高さを270にリサイズしてout.mp4という動画ファイルとして出力する。

```
ffmpeg -i input.mp4 -vf scale=-1:270 out.mp4
```


# フレームの切り出し
次に、縮小した動画をフレームへと分解します。
以下に動画から静止画にするためのffmpegのコマンドを記載します。
本コマンドでは動画が30フレームであると設定して処理を行っています。
```
ffmpeg -i input.mp4 -vcodec png -r 30 image_%08d.png
```
合計フレーム数が8桁を超える場合には%08dの中の数値をフレームの桁数に合わせてください。

# 音声の抽出
次に、動画から音声を抽出します。
この音声データは画質の向上が終わった後の動画ファイルに合わせるために利用します。


以下にffmpegのコマンドを示します。
##### 最も単純な例
```
ffmpeg -i input.mp4 -vn output.mp3
```
このコマンドでは、指定した動画ファイルをmp3へと変換して出力しています。ただし、このコマンドでは動画に含まれている音声ファイルとは違う形式になっているため、音質の劣化が発生します。

##### 無劣化で音声を抽出する方法
最初に、以下のコマンドを入力することで、対象とする動画ファイルの音声コーデックを確認します。
```
ffmpeg -i input.mp4
```
ここで、音声コーデックの種類がわかった場合、出力ファイルの種類を同様のものへと変更して出力することで、劣化無しに音声の抽出を行うことが出来ます。
ここでは音声コーデックがaacであった場合を示します。
```
ffmpeg -i input.mp4 -vn -y -acodec copy output.aac
```

# フレームごとの画質の向上
次に、Real-ESRGANを使ったフレームごとの画質の向上です。
やり方としては単純で、Real-ESRGANで指定したファイルに含まれている画像を画質を保ったまま拡大してもらいます。
今回の場合だと、動画を構成している全フレームの画質の向上を行います。

以下に必要となるコマンドを示します。

```
python inference_realesrgan.py -n RealESRGAN_x4plus_anime_6B -i inputs
```
inputsが指定しているファイルなので、ここをフレームが入っているファイルのパスを入力することで、画質の向上が行えます。

#### 出力画像が真っ暗になる場合
Real-ESRGANを実行したとき、真っ暗な画像しか出力されない場合、以下のコマンドを入力することによって拡大された画像が出力される可能性があります。
```
python inference_realesrgan.py -n RealESRGAN_x4plus_anime_6B -i inputs　--fp32
```

# フレームをまとめて動画へと再構成
次に、画質の向上が行えたフレームをまとめ、動画へと再構成を行います。
ここの処理はフレームの切り出しの際に使用したコマンドと対応しているので、指定するファイル名はフレームの切り出しで用いた出力名に、Real-ESRGANで追加された名前に対応するものを用いるようにしてください。
```
ffmpeg -r 30 -i image_%08d_out.png -vcodec libx264 -pix_fmt yuv420p -r 30 out.mp4
```
基本的に、元のファイル名にoutと付け足されたものが出力されるので上記のコマンドで問題ないと思われます。
これで、切り出したフレームがまとめられ、動画として再構成されます。

# 構成した動画と音声の融合
先ほど作った動画は、フレームをまとめただけなので、無音のままとなってしまいます。
ここで先ほど抽出した音声ファイルを融合させることで、動画として完成します。
以下にffmpegのコマンドを示します。
```
ffmpeg -safe 0 -f concat -i list.txt -i audio.mp3 -filter_complex "amix" output.mp4
```
ここでlist.txtに以下のように結合させるファイル名を記載し、audio.mp3を結合させたい音声ファイルへと変更することで音声の結合が行えます。
```
file 'out.mp4'
```

# 終わりに
今回は動画の画質を向上させるための方法をまとめてみました。
Real-ESRGANを使った方法なので実写よりもアニメ動画向けの方法になっております。
また、ローカルで行う方法を用いましたので、実行するにあたってGPUの性能によりますがかなりの時間がかかると予想されます。


# 参考
* [【ffmpeg】動画の解像度を指定してリサイズ、アスペクト比を維持したまま解像度を変更する、回転する](https://qiita.com/riversun/items/d09d8e596a20ec1798f3)
* [動画をバラしたり再構成したりする時のffmpegメモ](https://qiita.com/reona396/items/d8f99e93ece66122fca2)
* [【無劣化】FFmpegで動画から音声を抽出する方法の解説！初心者も簡単！](https://jp.videoproc.com/edit-convert/extract-audio-with-ffmpeg.htm#3.%E9%9F%B3%E5%A3%B0%E6%8A%BD%E5%87%BA%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%82%82%E3%81%A3%E3%81%A8%E3%82%82%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)
* [RealESRGANで真っ黒な画像しか出てこない場合の改善法](https://apple-log.work/2023/06/305/)
* [ffmpegを使って動画や音声を結合する](https://qiita.com/ktsuchi/items/ca3c1dd5e027ca43a029)