自己紹介
株式会社digitalbigmoのパイプラインエンジニアの小池@plinecomです。
これは何?
1000個くらいのフォルダにある何万毎もの静止画OpenEXRファイルをフォルダ毎にQuickTimeムービー(.mov)にして欲しいと言われてしまった。いちいちコンポジットソフトで合成してたら面倒なことこの上ないので、ffmpegをPythonで制御して処理してしまうことにした。
とりあえず、コード
import ffmpeg
import glob
if __name__ == '__main__':
for path in glob.glob('/foo/bar/*'):
print(path)
fname = path.split('/')[-1]
print(fname)
video = ffmpeg.input(path + '/*.exr',
pattern_type='glob',
framerate=24
).output('/foo/bar/' + fname + '.mov',
pix_fmt='yuv420p'
).run(overwrite_output=True)
必要なPython外部モジュール
- ffmpeg-python
pip install ffmpeg-python
pipを使ってPyPIからダウンロードしてくる。このモジュールにはffmpeg自体は含まれないので、brewとかパッケージ管理システムを利用して突っ込むとか、ffmpeg公式から各プラットフォーム向けにプリビルドされているffmpegとffprobeをダウンロードして、Pathが通った場所に置いてくとかしておく必要がある。
一応Dockerfileも用意してみた。
FROM rockylinux:8
RUN dnf install -y which python3 epel-release
RUN dnf config-manager --set-enabled powertools
RUN dnf localinstall -y --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm
RUN dnf install -y ffmpeg
RUN pip3 install ffmpeg-python
docker pull plinecom/py_exr_ffmpeg
コードの説明
今回、特にOpenEXRだから何かをするということはないので、PNGでもTIFFでもDPXでも静止画を動画にできるはず。ffmpegくんは優秀なのだ。
EXRファイルの読み込み方法の指示
video = ffmpeg.input(path + '/*.exr',
pattern_type='glob',
framerate=24
パス名にワイルドカードが入っていてglobして欲しいことと、フレームレートは今回は24pだよということを伝えている。フレームレートをOpenEXRのヘッダからタイムコード取り出して処理するのはエレガントだけれど、担当者に聞けば分かる話なら、それはそれで良いのだ。
動画の書き出し方法の指示
).output('/foo/bar/' + fname + '.mov',
pix_fmt='yuv420p'
書き出し先とファイル名を指示する。オマケでpix_fmtを指示している。ここでpix_fmtをyuv420pにしないとmacでプレビューできないファイルが出来上がってしまう。簡単なチェック用途では不便なので我慢して4:2:0にしておく。ちなみに、420pの超小さい大きさで書き出すということを指示しているわけではない、色の表現方法を指示している。
処理方法の指示
).run(overwrite_output=True)
実行にあたって、すでに同じ名前の動画ファイルがあった場合、停止してしまって困ったので、強制上書きを指示している。そういうのが特になければrun()だけで良い。
宣伝
株式会社digitalbigmoでは美肌プラグインの販売や映像VFXの制作業務を行なっています。ご興味のある方は、webページを見にきてください。一緒にお仕事しましょう。
参考文献