PythonでMP4形式の動画ファイルをGIF形式に変換したい

# はじめに
Qiita Advent Calendar 開催中ですね。筆者は完走賞を目指して、土日を溶かしてせっせと指を動かして記事を書いています。そんなとき、Qiita に映像を載せたいときがあります。しかし、Qiita の記事では GIF 形式のみに対応しているみたいですね...。

私はパソコン上の画面を録画するときには OBS Studio というソフトウェアを使っています。手軽に画面をキャプチャできるので愛用しています。

https://obsproject.com/ja

しかし、このソフトウェアで出力できるファイル形式は次のいずれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/fbcc9d12-8a9c-c657-e785-7da047e4648d.png)

そう、GIF形式がありません！

オンラインでも変換できるツールはありますが、品質が悪かったり、変換に時間がかかったりとやや信頼できません...。そこで、本記事では MP4 形式の動画ファイルを GIF 形式に変換するプログラムを組んでいきたいと思います。なお、この方法は Python がインストールされていることが前提です！

:::note warn
注意
本記事の方法でGIF形式へのファイル変換は可能ですが、**変換後のファイルサイズはかなり大きくなります**。筆者の場合は、<INS>GIF形式のファイルサイズが元のMP4形式の20倍前後に膨れ上がった</INS> ことを確認しました。従って、容量が大きいMP4形式のファイルをGIF形式に変換したい場合は、また別のアプローチをとることが好ましいです。
:::

# 目的
タイトル通りです。MP4 形式の動画ファイルを GIF 形式に変換する Python プログラムを開発していきたいと思います。

# 開発開始
今回は、MoviePy ライブラリを利用します。一応、他のライブラリやパッケージとの競合を防ぐために仮想環境をつくっていきます。開発の流れとしては次のとおりです。Windows のマシンをお持ちで時間がない、とにかく手間をかけたくない場合は [まとめ](#まとめ) をご確認ください。

1. 仮想環境の作成
1. 仮想環境のアクティブ化
1. ライブラリのインストール
1. プログラムの実装
1. 動作確認
1. 仮想環境の非アクティブ化

それではやっていきましょう！

## 仮想環境の作成
作業するディレクトリでターミナルを開いて次のコマンドを実行します。「```仮想環境名```」はお好みの名称を決めてください。処理が完了するまで少し時間がかかります。
```
python -m venv 仮想環境名
```

## 仮想環境のアクティブ化
作成した仮想環境をアクティブ化していきます。OS によってコマンドが違うのでお手持ちのものにあわせたコマンドを実行してください。

### Windows
```
仮想環境名\Scripts\activate
```

### Mac / Linux
```
source 仮想環境名/bin/activate
```

仮想環境のアクティブ化に成功すると、ターミナルでディレクトリが記されている左に ```仮想環境名``` が表示されます。筆者の場合 (windows11) は次のようになっています。
```
(仮想環境名) (base) PS C:\~
```

## ライブラリのインストール
MoviePy ライブラリを仮想環境にインストールしていきます。
```
pip install moviepy
```

## プログラムの実装
コーディングをしていきます。ここでは、ソースファイル名を ```convertVideoToGif.py``` とします。メイン関数の ```input_file``` には変換したい動画のパス、```output_file``` には変換後のGIF形式ファイル名を指定しましょう。([「まとめ」からジャンプされた方はプログラムをコピーした後ここをクリックしてください ](#まとめ))

```py:convertVideoToGif.py
from moviepy.editor import VideoFileClip

# 動画をGIFに変換する関数
def convert_video_to_gif(input_file, output_file, fps=10):
    # 動画ファイルの読み込み
    clip = VideoFileClip(input_file)

    # GIFに変換
    clip.write_gif(output_file, fps=fps)

# メイン関数
if __name__ == "__main__":
    # 入力動画ファイル名
    input_file = "input_video.mp4"

    # 出力GIFファイル名
    output_file = "output_video.gif"

    # GIFのフレームレート
    fps = 10

    # convert_video_to_gif 関数を呼び出して、動画を GIF に変換
    convert_video_to_gif(input_file, output_file, fps)
```

## 動作確認
pythonプログラム ```convertVideoToGif.py``` を実行していきましょう。次にターミナルで入力するコマンドを記します。
```
python convertVideoToGif.py                                     
```
次が出力されたら、実行成功です！
```
$ python convertVideoToGif.py  # pythonプログラムの実行
MoviePy - Building file output_video.gif with imageio.
```

本記事の冒頭で記したように変換前の MP4 形式のファイルは Qiita でアップロードできないので、生成された GIF 形式のファイル ```output_video.gif``` のみを次に示します。[この記事](https://qiita.com/banana_bancho/items/30f5d9d2c5eea00ac11c#方法b-の動作結果) にある動画と同じものです(宣伝)。

![output_video.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/4dbc364f-ec3a-a3b9-e74c-3cd15a6dd0c6.gif)

## 仮想環境の非アクティブ化
次のコマンドで仮想環境を停止します( Windows 以外未確認です)。
```
deactivate
```

# まとめ
ここでは、なるべく時短をしたい人向けに工程を簡潔にまとめます。 Windows の内容となりますので、他 OS の方はご注意ください。

1. 変換したい動画ファイルの名称を ```input_video.mp4``` にしてください。
1. 動画ファイル ```input_video.mp4``` があるディレクトリに ```convertVideoToGif.py``` ファイルを作成して、[このプログラム](#プログラムの実装)をコピー&ペーストしてください。
1. 次のコマンドをコピー&ペーストしてターミナルで実行してください。
    ```
    # 仮想環境を作成
    python -m venv videoConvert

    # 仮想環境をアクティブにする
    videoConvert\Scripts\activate

    # ライブラリのインストール
    pip install moviepy

    # プログラムの実行
    python convertVideoToGif.py

    # 仮想環境を非アクティブにする
    deactivate
    ```
1. ```output_video.gif``` が作成されていれば成功です。

もし、失敗している場合はお手数ですが各工程を確認してください。「```python ~```」というコマンドで失敗している場合、「```py ~```」に変更すればうまくいく場合があります。

# おわりに
お疲れ様です。次の Github でもプログラムを公開していますのでご確認ください。

https://github.com/sakamo-bnn/convert-video-to-gif

次の記事も参照して頂けると幸いです。この記事では複数のMP4形式のファイルをまとめて変換できるようにしています。

https://qiita.com/skm_bnn/items/89c153c6d87a37618686