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

# はじめに

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

CMカットもしたいため、まずはPCを購入する前にVMWare上に環境を作成し実験した。
[CMcut4U](http://www.asahi-net.or.jp/~sy8y-siy/CMcut_on_Unix/)を使用させていただいた。
このプログラムはフレーム単位のカットではなく秒単位のカットとなっているため、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等の割り振りは以下の通り。
![ubuntu.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609967/f5448df5-73b3-6318-2ff1-90803c5630fb.png)


# 環境構築
インストール方法は省略。少なくとも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」を追記

```sshd_config
vi /etc/ssh/sshd_config 
PermitRootLogin yes
```

sshを再起動

```
/etc/init.d/ssh restart
```

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

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

## Teratermの設定
設定 -> SSHポート転送 より、「Xクライアントアプリケーションの転送」にチェックを入れる。
![Teraterm_XmingSetting.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609967/ffc3ba80-a042-4434-b59f-33705a1c7a87.png)

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

## 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が表示されれば設定完了。
![Xming_firefox.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609967/b5e64691-cdf2-22e9-c7c8-73135095967c.png)

# 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のインストール

インストールするバージョンによりパスが異なるため、[リリース情報](https://github.com/docker/compose/releases)より予め確認すること。
下記コマンドは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で置換している。
設定ファイルのバックアップは取っていないため、必要であれば追記すること。

```encoder
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
```

その後、[作者様のサイト](http://www.asahi-net.or.jp/~sy8y-siy/create-logo/)の通り、ロゴファイルを作成する。
ここでディスプレイを使った操作があるが、上記設定により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」を使って手直しをすることができる。
![fixGUI.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609967/53f5dc9f-ed15-fa19-186f-3df4e15e6231.png)


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

オプションについては[作者様のサイト](http://www.asahi-net.or.jp/~sy8y-siy/CMcut_on_Unix/)参照のこと。

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

# 参考/配布先
- [（作者様のサイト）CMcut4U](http://www.asahi-net.or.jp/~sy8y-siy/CMcut_on_Unix/)
- [Tera Term](https://ja.osdn.net/projects/ttssh2/)
- [WinSCP](https://ja.osdn.net/projects/winscp/)
- [Xming](https://ja.osdn.net/projects/sfnet_xming/)
- [vmware](https://www.vmware.com/jp.html)
- [Docker Install](http://docs.docker.jp/engine/installation/)
- [Xmingの設定について](http://www.mikitechnica.com/11-xming-teraterm.html)