Docker上に動画エンコード環境を作るまで(CMcut4U)


はじめに

普段はWindows10上にavisynthととaviutilを利用して自動CMカットバッチをキックしつつtsファイルのエンコードを行っているが、動画エンコード部分を別PCに切り出せないかなと思い、色々と試行錯誤したメモ書き。

CMカットもしたいため、まずはPCを購入する前にVMWare上に環境を作成し実験した。
CMcut4Uを使用させていただいた。
このプログラムはフレーム単位のカットではなく秒単位のカットとなっているため、CMがほぼ一定フレーム残る仕様となっている。

環境情報

Windows10 Home
CPU: i7-7700 CPU @3.60GHz
メモリ: 16.0GB

VMWare 14
Tera Term 4.86
Xming 6.9.0.31
WinSCP 5.5.4

ubuntuのCPU等の割り振りは以下の通り。

環境構築

インストール方法は省略。少なくともWindowsから操作したい場合はTera Term、Xming、WinSCPは必須(代替製品でもOK)。

Ubuntuのインストール

同じく省略。適宜ユーザを作成。

Ubuntuの設定

この項ではまだTeratermからの接続はできないため、Ubuntu上から設定を行う。

rootユーザのパスワード設定

作成したユーザにてログインし、下記コマンドでrootユーザのパスワードを設定する。

$ sudo passwd root

ssh許可

Windowsからsshで接続できるようにするための設定。
まずはパッケージをインストール。

apt-get update
apt-get install aptitude
aptitude install ssh

インストール後、/etc/ssh/sshd_configに「PermitRootLogin yes」を追記

vi /etc/ssh/sshd_config 
PermitRootLogin yes

sshを再起動

/etc/init.d/ssh restart

以降で特筆しない限りrootユーザでの作業とする。

Teraterm、Xmingの設定

この項はTeratermから操作をするための設定。Teratermを利用しない場合はスキップ可能。

Teratermの設定

設定 -> SSHポート転送 より、「Xクライアントアプリケーションの転送」にチェックを入れる。

設定 -> 設定の保存 より、設定情報を保存。

Xmingの設定

Xmingをインストールしたフォルダ内の「X0.hosts」を編集する。
デフォルトでは「localhost」のみが設定されているため、構築したUbuntuのIPを追記する。

X0.hosts
localhost
192.168.xxx.xxx

設定後、Xmingを再起動。

Ubuntuの設定

出力ディスプレイの設定を行う。
ログオフしても設定が消えないよう「.bashrc」にDISPLAY設定を追記する。
追記するIPはWindowsマシンのIPを追記する。

# cat export DISPLAY=192.168.yyy.yyy:0 >> /root/.bashrc

Xmingの動作確認

Teratermにて新しいセッションでUbuntuにログインする。
その後デフォルトでインストールされているであろうfirefoxを起動してみる。
(GUIを利用しているアプリケーションならなんでもいい)

# firefox &

WindowsマシンにFirefoxが表示されれば設定完了。

Docker、Docker-composeのインストール

Dockerのインストール

ここではstableをインストールする。

# apt-get update
# apt-get install -y apt-transport-https ca-certificates curl software-properties-common
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# apt-key fingerprint 0EBFCD88
# add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
# apt-get install -y docker-ce

インストール後にバージョン情報が表示されれば成功。

# docker --version
Docker version 19.03.8, build afacb8b7f0

Docker-composeのインストール

インストールするバージョンによりパスが異なるため、リリース情報より予め確認すること。
下記コマンドはversion 1.26.0-rc3をインストールする場合のものとなる。

Docker-compose_1.26.0-rc3
# curl -L https://github.com/docker/compose/releases/download/1.26.0-rc3/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose

インストール後にバージョン情報が表示されれば成功。

# docker-compose --version
docker-compose version 1.26.0-rc3, build 46118bc5

dockerfile、docker-composeを作成

まずはベースとなるディレクトリを作成する。今回は「/data/encoder」とする。

# mkdir -p -m 775 /data/encoder/volumes/work_area
# touch /data/encoder/docker-compose.yml
# touch /data/encoder/encoder

dockerfile

必要なソフトウェアをインストールしたりビルドしたりしているだけ。不要なファイル、ディレクトリは最後に削除。
apt-getでは人がわかりやすいように敢えて分けている。

一部設定を変更する必要があるため、設定ファイル(/opt/CMcut4U/const.rb)をsedで置換している。
設定ファイルのバックアップは取っていないため、必要であれば追記すること。

FROM ubuntu:18.04

LABEL version="1.0"
LABEL description="動画エンコード用サーバ"

WORKDIR /var/tmp

#作業用ディレクトリを作成
#日本語フォントをインストール
#Rubyのインストール
#wav-file(Ruby)のインストール
#pythonのインストール
#ffmpeg & mpvのインストール
#opencvのビルド&インストール
#CMcut4Uをインストール
#ゴミ掃除
RUN mkdir -m 775 /work_area && \
    apt-get update && \
    apt install -y fonts-takao && \
    fc-cache -fv && \
    apt install -y ruby && \
    apt install -y ruby-gtk2 && \
    gem install wav-file && \
    apt install -y python-dev python-numpy && \
    apt install -y ffmpeg && \
    apt install -y mpv && \
    apt install -y cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev && \
    apt install -y libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev && \
    mkdir -m 775 /work_area/opencv && \
    git clone https://github.com/opencv/opencv.git /work_area/opencv && \
    mkdir -m 775 /work_area/opencv_contrib && \
    git clone https://github.com/opencv/opencv_contrib.git /work_area/opencv_contrib && \
    cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local /work_area/opencv && \
    make && \
    make install && \
    mkdir -m 775 /opt/CMcut4U && \
    git clone https://github.com/kaikoma-soft/CMcut4U.git /opt/CMcut4U && \
    echo PATH="$PATH:/opt/CMcut4U" >> /root/.bashrc && \
    mkdir -m 775 /work_area/video /work_area/mp4 /work_area/logo /work_area/work /work_area/TS && \
    cat /opt/CMcut4U/const.rb | sed -i -e 's/1280x720/1920x1080/g' /opt/CMcut4U/const.rb && \
    cat /opt/CMcut4U/const.rb | sed -i -e 's/Top       =.*/Top       = "\/work_area"/g' /opt/CMcut4U/const.rb && \
    cat /opt/CMcut4U/const.rb | sed -i -e 's/$ffmpeg_bin      =.*/$ffmpeg_bin      ="ffmpeg"/g' /opt/CMcut4U/const.rb && \
    rm -rf /work_area/opencv/* && \
    rmdir /work_area/opencv && \
    rm -rf /work_area/opencv_contrib/* && \
    rmdir /work_area/opencv_contrib && \
    rm -rf /var/tmp/*

docker-compose

dockerファイルに「encoder」を指定している。
一部ウィンドウにて設定する必要があるため、Display情報を引っ張ってきている。
DISPLAYに設定するIPはwindowsホストのIPを指定すること。

docker-compose.yml
version: '3'

services:
  container1:
    build:
      context: .
      dockerfile: encoder
    environment:
      - DISPLAY=192.168.XXX.XXX:0
    volumes:
      - ./volumes/work_area:/work_area
      - /tmp/.X11-unix:/tmp/.X11-unix
    tty: true
    command: bash -c "/bin/bash"

イメージビルド

dockerファイルを見るとわかる通り、opencvをビルドしているためそれなりの時間がかかる。

cd /data/encoder
docker-compose build

起動 & ログイン

ビルドまで完了したので、あとは起動して中に入るだけ。

cd /data/encoder
docker-compose up
docker-compose start
docker exec -it encoder_container1_1 /bin/bash

tsファイル、出力されるファイルについて

上記設定を実施すると、全て「work_area」上で完結するようになっている。

ホストのubuntu上では下記の通り。

/data/encoder/volumes
    └─/work_area
          ├─/logo   ・・・ロゴファイルを配置するディレクトリ
          ├─/mp4    ・・・エンコードされたファイルが保存されるディレクトリ
          ├─/TS     ・・・エンコード対象を配置するディレクトリ
          ├─/video  ・・・利用しない
          └─/work   ・・・エンコード中に利用されるディレクトリ

TSファイルを配置する場合はTSディレクトリ配下に配置するのだが、直接ファイルを配置するとうまく動作しない。
必ず「~/TS/番組名/xx.ts」となるようにすること。

/data/encoder/volumes
    └─/work_area
          ├─/TS     ・・・エンコード対象を配置するディレクトリ
          |   └─/BANGUMI_A
          |        └─/hogehoge.ts
          ・
          ・
          ・

ロゴファイルの作成

一旦「cmcuterAll.rb」を実行する。この時ロゴファイルの存在しないため、エラーで止まる。

# cmcuterAll.rb

その後、作者様のサイトの通り、ロゴファイルを作成する。
ここでディスプレイを使った操作があるが、上記設定によりWindowsホスト上にスクリーンが表示される。

なお、この環境でのロゴ作成コマンドは下記となる。

# logoAnalysisSub.py --dir /work_area/BANGUMI_A/BS11_isekai/SS

再度「cmcuterAll.rb」を実行すればエンコードが開始される。

# cmcuterAll.rb

エンコード時間とか

15分のアニメを実行した結果、下記の通りとなった。

エンコード時間 容量 CMカット率
約24分 1.9GB -> 93.2MB

仕様通り、CMカット処理は秒単位での処理となっているため数フレームずつCMが残っている。
一方、CM部分が丸々残るということはなかった。
仮にCM部分が丸々残る場合は「fixGUI.rb」を使って手直しをすることができる。

また、cmcuterAll.rbのオプションにて、エンコードはせずcmカットに必要な計算までで止める機能もある。
これを前提にすれば無駄にエンコード時間を使わずに済む。

オプションについては作者様のサイト参照のこと。

まとめ

TSファイルをエンコードする環境をDockerファイルに構築することができた。
常にDocker環境を動かす必要性は全く無いので、親となっているubuntuでshell+cron使って定期バッチにし、TSディレクトリにtsファイルがある場合のみDocker起動してcmcuterAll.rbをキックする・・・くらいでいいと思う。

参考/配布先