TL;DR
- NVEnc(NVIDIAのGPU)対応のFFmpegのDockerfileを作成し,シングルタスクのコンテナでポータブルなエンコード環境を作りました
- 作成済みのDockerfile をGithubで公開しています
- nvencを含むバイナリファイルは再配布禁止なので,自分でDockerイメージをビルドして使用します
- Dockerコマンドでffmpegの処理を呼び出せる,快適なエンコード環境を整えます
-
docker run
コマンドに,入力ファイルとオプションを指定して実行することで,動画の処理を実現します
-
準備
- nvidiaのGPUを搭載したDockerホスト(Dockerを動かすマシン)
- nvidia-docker2がインストールされたDocker環境
- docker-ceとnvidia-docker2 をインストールしておく
- AWS EC2 g3s.xlargeで動作テストをしています
使い方
Dockerイメージ ffmpeg-nvenc のビルド
- ffmpeg-nvencのDockerイメージをビルドします.
- 初回のイメージビルドは時間が掛かります(20分くらい).一度イメージを作ってしまえば,Dockerのキャッシュが効くので再実行しても高速に終わります.
git clone https://github.com/myoshimi/ffmpeg-nvenc
cd ffmpeg-nvenc
sudo docker build -t ffmpeg-nvenc .
エンコード実行の例
blenderで作られたクリエイティブ・コモンズの動画Big Buck Bunnyをエンコードする手順です.以下のコマンド例では, BBB Sunflower versionの1080p60fpsの動画を使用しています.
# カレントディレクトリにある動画ファイル(bbb_sunflower_1080p_60fps_normal.mp4)を,
# GPUでh.265エンコードします.
# 実行後のファイルがbbb_sunflower_1080p_60fps_normal_h265.mp4として作られます.
docker run --rm --runtime=nvidia \
-v ${PWD}:/tmp/ ffmpeg-nvenc:latest \
-stats \
-i /tmp/bbb_sunflower_1080p_60fps_normal.mp4 \
-vcodec hevc_nvenc \
/tmp/bbb_sunflower_1080p_60fps_normal_h265.mp4
コマンドのキモは,(動画ファイルがある)カレントディレクトリを不揮発ボリューム/tmp
としてffmpeg-nvencコンテナがマウントして,ffmpegコマンドの入力ファイルとして使用することです.
その他のオプションは以下のとおりです.
Dockerイメージ指定(ffmpeg-nvenc:latest)より前はdockerのオプション,イメージ指定より後はffmpegのオプションです.
オプション | オプションの対象 | 効果 |
---|---|---|
--rm | docker | 状態が終了(exited)になったらコンテナを削除する |
-v | docker | コンテナがマウントする場所(カレントディレクトリ)を指定する |
-stats | ffmpeg | 処理の進行状況を標準出力に表示する |
-i | ffmpeg | 入力動画ファイル(コンテナがカレントディレクトリを/tmpにマウントしているので,コンテナから見たとき,/tmpがホストのカレントディレクトリになる) |
-vcodec | ffmpeg | ビデオコーデックの指定(後述) |
vcodecの指定
vcodecオプションを変更すると,コーデックを変更できます.
Processor | codec | -vcodec |
---|---|---|
CPU | H.265 | libx265 |
CPU | H.264 | libx264 |
GPU | H.265 | hevc_nvenc |
GPU | H.264 | h264_nvenc |
Dockerfileでやっていること
nvidia/cuda:10.0-devel-ubuntu18.04をベースに,必要なライブラリをインストールし,ffmpegをビルドしています.
Dockerfile内でビルドしているライブラリは以下の通りです.
- NASM
- YASM
- libx264
- libx265
- libvpx
- libfdk-aac
- libmp3lame
- libopus
- nv-codec-headers