Chinachu(Docker+PX-Q3PE4)+Amatsukazeによる録画+自動CMカット・エンコーディングを行う録画システムの構築

最近、家の大掃除と並行してNW構成や仮想基盤についてもすべて再設計しての作り直しを行っていたのだが、そんな中でPLEXのPX-Q3PE4が手に入ったので、せっかくだから今風の録画システムを作ってみることにする。

今風というにはちょっと古いかもしれないが、録画の管理には安定して動作してそうなChinachuを使う。 録画サーバ側の構築はめんどくさいのでDockerで行う。

また、CMの自動カット・エンコーディングについても自動で行わせたい。 なので、別途Windowsサーバを用意してAmatsukazeをサーバとして稼働させることにした。 こちらではNvidiaのGPUを使って、ハードエンコードをさせることにする。

チューナーについては、カードを物理的に用意するのがめんどくさかったのでSoftcasでテスト。 (実際にやる場合はちゃんと用意してね)

どちらもVM上に構築し、仮想基盤はProxmox VE 6.2を用いる。 PX-Q3PE4もGPUもパススルーしてVMに渡している。 (ESXiは最近は触ってないのだが、ProxmoxならGPUのPCIパススルーも比較的容易に行える)

1. 録画サーバ(Chinachu)の構築

パッケージ管理システムで使えるパッケージが比較的モダンで楽なので、OSはDebianを使う。 (Ubuntuでも同じように出来ると思うけど、実際には確かめてないので不明。CentOSは8になってだいぶ変わったらしいので今回は避けた。)

VMについては、PCIパススルーでPX-Q3PE4を渡してOSのインストール、NW設定が終わってる状態として進める。

PX-Q3PE4のドライバをインストールする

Docker側でチューナーを扱えるよう、ホスト側にPlexチューナーのドライバをインストールしておく。 Linuxでは有志の方が開発してくれたドライバを使ったほうが良いようなので、それを使うことにしよう。 以下のコマンドを実行する。

# 必要なパッケージの導入
sudo apt -y install pcscd libpcsclite-dev libccid pcsc-tools python2.7 mercurial cmake g++ autoconf git dkms

# PLEXチューナーのドライバを取得
mkdir -p ~/src/
cd ~/src/
git clone https://github.com/nns779/px4_drv.git

# ファームウェアのインストール
cd ~/src/px4_drv/fwtool/
make
wget http://plex-net.co.jp/plex/pxw3u4/pxw3u4_BDA_ver1x64.zip -O pxw3u4_BDA_ver1x64.zip
unzip -oj pxw3u4_BDA_ver1x64.zip pxw3u4_BDA_ver1x64/PXW3U4.sys
./fwtool PXW3U4.sys it930x-firmware.bin
sudo mkdir -p /lib/firmware
sudo cp it930x-firmware.bin /lib/firmware/

# チューナードライバのインストール
cd ~/src/px4_drv/
sudo cp -av ./ /usr/src/px4_drv-0.2.1
sudo dkms add px4_drv/0.2.1
sudo dkms install px4_drv/0.2.1
sudo modprobe px4_drv

ドライバを入れたら、VMを再起動する。

sudo reboot

再起動後、チューナーがちゃんと認識されているかを確認する。

user@tvm-rec-plex:~$ ls -la /dev/px4video*
crw-rw-r-- 1 root video 244, 0 10月  4 11:56 /dev/px4video0
crw-rw-r-- 1 root video 244, 1 10月  4 11:56 /dev/px4video1
crw-rw-r-- 1 root video 244, 2 10月  4 11:56 /dev/px4video2
crw-rw-r-- 1 root video 244, 3 10月  4 11:56 /dev/px4video3
crw-rw-r-- 1 root video 244, 4 10月  4 11:56 /dev/px4video4
crw-rw-r-- 1 root video 244, 5 10月  4 11:56 /dev/px4video5
crw-rw-r-- 1 root video 244, 6 10月  4 11:56 /dev/px4video6
crw-rw-r-- 1 root video 244, 7 10月  4 11:56 /dev/px4video7

Dockerコンテナを立ち上げる

PLEXのドライバを入れたら、次にChinachuのDockerイメージを立ち上げる。 docker-compose.ymlなどのファイルとまとめてGithubにリポジトリを上げてあるので、それを取ってきて立ち上げさせるようにしている。

中身の解説についてはめんどくさいから今回は省略(Sambaの設定とかは超適当なので、環境に応じて対応してほしい)。

本来なら nginx-proxy を通してhttpsでアクセス出来るようにすると良いのだが、そのへんはお好みで。 (Let's Encryptだとプライベートドメインは使えないので、適当に自己署名証明書でも作って読ませとけばいいだろう)

ちなみに、コンテナデータは /opt 直下に、録画したデータや番組表などについては /opt/data 配下に配置するようにしている。 また、ユーザアカウント(user)からdockerを操作出来るようにしているので、このあたりは適宜読み替えてもらいたい。

また、録画データを閲覧するためのsambaについても環境に応じて設定をすることを勧める。 (自分の場合はProxmoxのFirewallでIPを絞っておくことで対処しているためガバガバになっているけど)

# 事前に必要になるディレクトリ・ファイルを生成
sudo mkdir -p /opt/data
sudo chown -R ${USER}. /opt/data
mkdir -p /opt/data/chinachu/data/ /opt/data/recorded/
touch /opt/data/chinachu/data/reserves.json

# dockerデータを取得
cd /opt
git clone https://github.com/blacknon/plex_chinachu

# dockerを立ち上げ(buildが行われるので少し時間がかかる)
cd plex_chinachu
docker-compose up -d

# 番組表の取得・更新(反映に結構時間がかかる。30分ほど経っても反映されなかったらdockerを再起動して↓のコマンドを再実行)
curl -X PUT "http://127.0.0.1:40772/api/config/channels/scan"
docker exec -it chinachu ./chinachu update

動作を確認する

dockerコンテナを起動後、Webブラウザからアクセスしてストリーミング再生・録画が行えるか確認してみよう。 「https://chinachuのIPアドレス:10772」でアクセス出来るはずだ。 認証情報はデフォルトでakari:bakuhatsuになってるので、それでログインできる。

番組表が表示されるまでは少し時間がかかるので、/opt/data/chinachu/data/schedule.jsonへの書き込みがされてるようだったらしばらく待っていよう。 (このファイルが空の状態だと番組表がうまく取れてないことになる)

サービス化する

動作に問題がなさそうだったら、以下のコマンドでサービス化してしまおう。

# ディレクトリの作成・サービスファイルのコピー
mkdir -p ~/.config/systemd/user/
cp /opt/plex_chinachu/mirakurun-chinachu.service

# ユーザでのサービス化と自動ログイン設定
sudo bash -c "systemctl --user enable mirakurun-chinachu.service && loginctl enable-linger $(whoami)"

2. CMカット・エンコードサーバ(Amatsukaze)の構築

録画サーバ(chinachu)側が構築できたら、次はCMカット・エンコーディングを行うサーバを構築する。

Amatsukazeは残念ながらWindowsじゃないと動作しないようなので、今回は家を掃除中に発掘されたWindows 8.1にインストールして使うことにする。 (まだギリギリサポート中だし。Windows 10買うほどのことでもないだろうと。)

とりあえず、Windows 8.1はOSインストール、IPアドレスの設定、GPUのドライバインストールなど、一通りの作業は終わってるものとする。 ProxmoxでGPUパススルーをする場合はこちらの内容を参考にすると良いだろう。

ネットワークドライブの設定

事前に、Chinachuのsambaをネットワークドライブとしてマウントしておく。 chinachu側のdocker-compose.ymlではFドライブとしてchinachuを、エンコードファイルの置き場はGドライブとしてNASなどの共有ディレクトリをマウントするように書いている。

自分の環境に合わせて書き換えをする。

Amatsukazeのインストール・サービス起動

Amatsukazeのインストールを行う。 インストールといっても、7zipで圧縮されたファイルを任意の場所に展開して実行するだけなので、別にインストーラー等を実行させる必要はない。

事前に、Windows Updateで最新の状態にした上で、以下をインストールしておく(.Netフレームワークは4系も必要かもしれない。エラーが出たら入れよう)。

必要パッケージを入れたら、Amatsukazeをダウンロードしてこよう。 普通に最新版をそのまま取ってくればいい。

7zipファイルを取得したら任意の場所(自分の場合はC:/Users/user/Documents/Amatsukazeにおいてる)に展開し配置する。

展開したディレクトリ配下にあるAmatsukazeServer.vbsを実行することでAmatsukazeサーバが実行される。 同じディレクトリにあるAmatsukazeClient.vbsで接続ができる。

NVEncの導入

普通にAmatsukazeをインストールするだけでもCMカット・エンコードは行えるのだが、CPUでの処理だと処理時間がすごいかかってしまう。 なので、GPU(Nvidia)を使ってハードエンコードが行えるようにしてしまおう。

セットアップを楽に行うため、有志の方が作ってくれているNVEncCで入れてしまうのが良いだろう。

インストーラーもあるので、細かいインストール手順については割愛する。 任意のディレクトリに展開して、インストール先は展開したディレクトリを指定してやればいい。

インストーラー実行後、AmatsukazeClient.vbsを実行して基本設定タブのNVEncパスに、NVEncC64.exeのPATHを記述してやればいい。 (適用ボタンで保存されるので、忘れないようにしよう)

バッチファイルの配置

Amatsukazeは処理前後に自動実行するbatファイルを指定することが出来る。 サンプルとして、処理の前後にSlackに通知、処理後に動画ファイルをもとの場所に戻すbat(というか中身powershell)のサンプルだけ置いておく。

実行前

エンコード前に実行させるbatファイル。 (ps1ファイル呼び出してるだけ)

実行前_slack.bat
@echo off powershell -NoProfile -ExecutionPolicy Unrestricted "C:\Users\user\Documents\Amatsukaze\bat\実行前_slack.ps1 -filename "%IN_PATH%
実行前_slack.ps1
param( [string]$filename ) function ChangeUTF8{ param( [Parameter(Mandatory,Position=1)] [string]$text ) # 日本語エンコード用 $encode = [System.Text.Encoding]::GetEncoding('ISO-8859-1') $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($text) return $encode.GetString($utf8Bytes) } # SlackにPostする関数 function Send-Slack{ param( [Parameter(Mandatory,Position=1)] [string]$target, [Parameter(Mandatory,Position=2)] [string]$webhookUrl ) $text = "「" + $target + "」のCMカット・エンコーディングを開始します。" # Jsonに変換する $payload = @{ text = ChangeUTF8("Amatsukaze: 処理開始連絡`n"+$text); } # SlackのREST APIをたたく Invoke-RestMethod -Uri $webhookUrl -Method Post -Body (ConvertTo-Json $payload) } # SSL/TLS 1.2を許可する [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; # slackのWebhookを指定する $webhook_url = "https://hooks.slack.com/services/hogehoge/fugafuga" Send-Slack -target $filename -webhookUrl $webhook_url

実行後

エンコード後に実行させるbatファイル。 (ps1ファイル呼び出してるだけ) Slackに飛ばす他、移動してしまった動画ファイルをもとの場所に戻す処理をしている。

実行後_slack.bat
@echo off powershell -NoProfile -ExecutionPolicy Unrestricted "C:\Users\user\Documents\Amatsukaze\bat\実行後_slack.ps1 -filename "%IN_PATH%"
実行後_slack.bat
param( [string]$filename ) function ChangeUTF8{ param( [Parameter(Mandatory,Position=1)] [string]$text ) # 日本語エンコード用 $encode = [System.Text.Encoding]::GetEncoding('ISO-8859-1') $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($text) return $encode.GetString($utf8Bytes) } # SlackにPostする関数 function Send-Slack{ param( [Parameter(Mandatory,Position=1)] [string]$target, [Parameter(Mandatory,Position=2)] [string]$webhookUrl ) $text = "「" + $target + "」のCMカット・エンコーディングが終了しました。" # Jsonに変換する $payload = @{ text = ChangeUTF8("Amatsukaze: 処理終了連絡`n"+$text); } # SlackのREST APIをたたく Invoke-RestMethod -Uri $webhookUrl -Method Post -Body (ConvertTo-Json $payload) } # SSL/TLS 1.2を許可する [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; # slackへ投稿する $webhook_url = "https://hooks.slack.com/services/hogehoge/fugafuga" Send-Slack -target $filename -webhookUrl $webhook_url

動作確認

すべての作業が終わったら、Chinachuで録画完了後にAmatsukazeに自動でエンコード対象として追加されるようになる。 プロファイルやCMカットの設定(チャンネルごとのロゴなど)については、自身の環境に合わせて設定してやればいいだろう。