18
19

いまさら始める録画鯖(Dockerで録画鯖を動かしS3にデータを投げる話)

Last updated at Posted at 2022-12-09

この記事は TLB Enjoy Developers Advent Calendar 2022 10日目の記事です。

「こたつ欲しいなー」と思いながら部屋が狭いので膝掛けで今年の冬も乗り越えようと思っている とろんぽっとです。
普段はこのチームラボでPHPなどをかくバックエンドエンジニアとして働いています(PHP飽きた)。時代はクラウドですが、どうも好きになれずオンプレ大好きで普段からサーバを愛でてます

アドベントカレンダーなんだしネタ全振りな記事を書こうと思っていたのですが、前日になっても何もやってないので最近絶賛構築中の録画サーバについででも書きます

というわけで
冬ですね!!!1年って早いものでもう残す行事は忘年会と年末の休みくらいでしょうか1

これから年末にかけて特番などを見たいテレビ番組が増えてくるけど、「忘年会行ってたら見れなかった!」「今日放送ってさっきTwitterでみた」などが増えてくると思います。

ブラウザ経由でテレビの録画予約や視聴してみたくないですか?

ということで、Docker + Ubuntuを使ってロケフリ対応録画鯖を構築していこうと思います。
「なんでWindowsで組まねえんだ。BonDriverの記事が読みてえんだ」 という方、申し訳ないです。なんかね...なんか...Windowsで構築うまくできなかったんだ....(泣き崩れる

※ ちなみに今回はPCが転がってたので 転がってたSSDを拾ってきてESXiをインストールして仮想マシン立ててますが、Windows上にHyper-Vとかで仮想マシン立てるとPCが1台ですみます。
※ いわゆるTS抜きというやつです。録画した番組を誰でも見れるようなとろこに置くことは絶対にしないようにしてください。
※ 真似をして何か損害が出ても私は知らないので、自己責任でお願いします。

余談
ちなみにですが、ネット配信が当たり前になった今、TV放送の録画鯖の必要性が薄れています。
こんな録画鯖を組んでる筆者ですら、アニメはネットで見ているため、ほとんど使ってません
最近の若い人にはもう録画鯖なんて興味がない分野かもしれませんが「昔はそうだったんだね、おじいちゃん」という温かい目線で見ていただければ幸いです。2

構成

概念図

G8EmygWihOZMvTO1670571799_167057180.png

上記でも書きましたが、GPU搭載WindowsPCくんに仮想マシンたてて動かしても大丈夫です。(やったことないけど)

今回、時間の都合上 CMカットとエンコードに関しては記載しません。後日ブログかどこかに書きます(多分)(気力があれば)

録画鯖

ハードウェア構成

部品
CPU Intel Core i7-7700K
メモリ 16GB
GPU 内蔵(インテル® HD グラフィックス 630)
SSD HP S700 250GB (主にOS用)
チューナー PX-MLT5PE
カードリーダー SCM ICカードリーダー/ライター B-CAS・住基カード対応 SCR3310/v2.0 Amazon.co.jp
B-CASカード テレビから引っこ抜いてきた3

※ PX-MLT5PEはBCASさすカードリーダが付いてますが、linuxの場合は使えないのでカードリーダー必須です

ソフトウェア構成

名称 用途
ESXi 8.0 ハイパーバイザー
Ubuntu 22.04 OS
Docker v20.10 コンテナ動かすやつ
Mirakurun Chinachu向けのSpinel的なもの※
Chinachu 録画や再生視聴できるWebアプリケーション※

※ 他にも使ってるけど Dockerコンテナに押し込んでるので主なやつしか書いてません

GPU搭載Windowsくん

これは普段メインで使ってるPCです

部品
CPU AMD Ryzen™ 7 1700X
メモリ 32GB
GPU GTX 1060 6GB

ソフトウェア構成

名称 用途
Windows10 Pro OS
Docker for Windows コンテナ動かすやつ
Amatsukaze CMカットやエンコードをまとめてしてくれるすっごいやつ

大事なので2度書きますが、今回、時間の都合上 CMカットとエンコードに関しては記載しません。しかしここにソフトウェア名を乗っけているということは、使っているということです。気になる人は私の記事を待つより調べてみてください

録画鯖構築編

ハードウェアセットアップ

  1. チューナーをPCにぶっさす
  2. カードリーダーをPCに繋げる
  3. BCASカードをカードリーダーにぶっさす(向き気をつけよう (自分は反対に差してて数時間溶かした

仮想マシン作成 / OSインストール

これは適当にググって

構成のオプションからUSBデバイスの追加で チューナーとカードリーダーを設定が必要です。
※ Hyper-Vなどで仮想マシンを立てている人はWindows側のセットなしでチューナーを繋げれるかは知らぬ

Dockerのインストール

変なネット記事を見ずに、コマンド全部書いてくれてるから公式ドキュメントを読もう
https://docs.docker.com/engine/install/ubuntu/

Docker Composeはいらないの?って思ったあなた。情報が古いです。結構前に Dockerのサブコマンドに Goで再実装されているため、インストール不要です。

ドライバセットアップ

こちらの記事を参考に

2024-01-28 現在、こちらの方法ではうまくいきません。
https://github.com/tsukumijima/px4_drv こちらをご利用ください。

# dkms、autoconfを事前インストール
sudo apt install dkms autoconf unzip

# px4_drvを利用させてもらいます。
cd /tmp
git clone https://github.com/nns779/px4_drv
cd 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/

# dkmsでカーネルドライバを自動的に設定する
cd ../
sudo cp -a ./ /usr/src/px4_drv-0.2.1
sudo dkms add px4_drv/0.2.1
sudo dkms install px4_drv/0.2.1
sudo reboot

# 再起動後、/dev/px4をロードしていることを確認
lsmod | grep -e ^px4_drv
# px4_drv               143360  0

チューナーを認識しているか確認

$ ls -l /dev/pxm*
crw-rw-r-- 1 root video 236, 0 11月  8 17:23 /dev/pxmlt5video0
crw-rw-r-- 1 root video 236, 1 11月  8 17:23 /dev/pxmlt5video1
crw-rw-r-- 1 root video 236, 2 11月  8 17:23 /dev/pxmlt5video2
crw-rw-r-- 1 root video 236, 3 11月  8 17:23 /dev/pxmlt5video3
crw-rw-r-- 1 root video 236, 4 11月  8 17:23 /dev/pxmlt5video4

mirakurun と Chinachu のコンテナアップ

公式に DockerにmirakurunとChinachuを詰め込んだものが用意されていますが、Dockerfileが古いので今動きません。
ので動くものを書いた(Node.jsのversionをあげただけだけどね)のでこちらを git cloneなりZIPダウンロードなりで落としてきてください

セットアップ方法は大体 README.mdに書いてありますが、こんな感じです。

$ git clone https://github.com/NAKNAO-nnct/docker-mirakurun-chinachu.git
$ cd docker-mirakurun-chinachu

$ sudo mv -vf /usr/local/mirakurun /opt/mirakurun
$ sudo mkdir -p /opt/mirakurun/run /opt/mirakurun/opt /opt/mirakurun/config /opt/mirakurun/data
$ mkdir -p /opt/mirakurun/opt/bin

$ cp mirakurun/startup /opt/mirakurun/opt/bin/startup
$ chmod +x /opt/mirakurun/opt/bin/startup

$ docker compose down
$ docker compose run --rm -e SETUP=true mirakurun
$ docker compose up -d

2023/04/01 追記
下記を実行しないと動かないかもです

$ docker compose exec mirakurun bash

/app# echo "/opt/node_modules/arib-b25-stream-test/src/" | tee -a /etc/ld.so.conf
/app# ldconfig

rootで作業している人へ
録画とかができなくなるので、docker-mirakurun-chinachu を 0777 にしましょう(権限を正確に設定したい人はもうちょっと正確なパーミッションに)(なお私は乱雑な人なのでお察しください)

$ chmod -R 0777 docker-mirakurun-chinachu

mirakurun設定

mirakurunとは 有名な DVRチューナーサーバ

mirakurunでチューナーの設定をしていきます。とは言っても上のリポジトリ内に PX-MLT5PE用の設定が入っていますので、それをコピーしましょう。

$ cp mirakurun/conf/tuners.yml /opt/mirakurun/config/tuners.yml
$ docker compose restart mirakurun

ちなみに
設定内部で recpt1 に --deviceを引数に渡してますが、recpt1がチューナーを管理してくれるそうなので、引数で渡さなくてもいいかもです (試してない)

tuners.yml
command: /opt/bin/recpt1 --b25 --strip --device /dev/pxmlt5video0 <channel> - -

http://[録画サーバIP:40772/ にアクセスしてみると、

こんな画面が出てくると思います(スクショの撮り忘れ)

チャンネルスキャン

現在、地デジとBS、CSの大半を自動でスキャンしてくれるらしいので(どうせCSあまり映らないし見ないし)、mirakurunにスキャンしてもらいましょう。

$ curl -X PUT "http://localhost:40772/api/config/channels/scan?type=GR&refresh=true"
$ curl -X PUT "http://localhost:40772/api/config/channels/scan?type=BS&refresh=true"
$ curl -X PUT "http://localhost:40772/api/config/channels/scan?type=CS&refresh=true"

結構時間かかります、 気長に待ちましょう。

Chinachu

Chinachu とは 録画やストリーミング再生が可能なWebアプリです。mirakurunと同じ開発陣が開発されてます。

Mirakurunを使った録画アプリは Chinachuの他に EPGstation もありますが、こっちの方は導入がめんどくさかったのでChinachuにしてます。
ただ、EPGstationの方がネット記事がいっぱい転がってたりCMカットと連携させたりできますので、興味のある人はEPGstationを構築してみるのも面白いと思います。

動作確認

http://[録画サーバIP]:10772/ にアクセスすると下記のような画面が出てくると思います。(mirakurunのスキャンが終わってないと 番組表も何も表示されません。1日くらいほったらかしてみてください。ダメなら原因は別です。ログを見ましょう)

chinachu.png

あ、書き忘れてましたが、BASIC認証がかかってます。ID:PASSWORDが書いてますので それで入ることができます。

ホームにある「放送中の番組とライブ視聴」のボタンを押すと今放送中の番組が表示されるので、適当な番組の「ライブ視聴」を押して、番組が見れたら完成です。

あとは、番組表から、適当な番組を右クリックして「録画」してみてください。(テスト録画)、録画終了後に「録画済み」に移動していたら録画できてます。


はい、、、とここまできてようやく録画サーバの完成です。
ここからは録画後の運用などについて書いておきましょう。

ストレージが足りない

録画してみて「あれ?25分のアニメの癖にやたらめったら容量食うな」と思った方、正解です。めちゃくちゃ容量食います。
こんなことしてたらいくらHDDがあっても足りないので、適当な外部ストレージにでも投げ込みます。

世の中にはAmazon Simple Storage Service (通称 S3)という、オブジェクトストレージがあり、容量をあまり気にせずに投げることができるサービスがあります。しかしながら、AWSはネットワーク転送量が高いため、容量の大きなものをポンポン投げていては、料金が高額になってしまいます。
そこで、S3互換のオブジェクトストレージサービスのWasabiを利用していきたいと思います。

Wasabiのセットアップ

wasabiはNTT-PCの提供する WebArenaなどでも契約できますが、公式サイトをみると30日間無料トライアルと書いてるのでここから申し込んでいきましょう。

登録

まずはサクッと登録

バケット作成

こちらもトントントンとやっていきます
wasabi_3_create_bucket_1.png
wasabi_3_create_bucket_2.png
wasabi_3_create_bucket_3.png

アクセスキーの発行

ユーザからアクセスキーを発行します(AWSでいうIAMユーザ)。こちらが漏洩するとガチ目にやばいので、しっかり管理しましょう。(作成時にキーのCSVなどをDLし忘れると2度と表示されないので、作り直りてください)

wasabi_5_create_user_1.png
「プログラム(APIキーを作成)」をクリック
wasabi_5_create_user_2.png
wasabi_5_create_user_3.png
ここれではAmazonS3FullAccessを設定しておきます。
wasabi_5_create_user_4.png

録画サーバにマウント

次に、録画サーバにバケットをマウントします。こうすると、Linux内で内部ストレージのようにアクセスすることができます。

AWS CLIのセット

とりあえず、AWS cliをインストールします。

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install

これでS3互換のサービスにアクセスすることができます。

あとは、先ほど、DLした アクセスキーを設定していきます。

$ aws configure
AWS Access Key ID [None]: ここにAccess Key Id
AWS Secret Access Key [None]: ここにSecret Access Key
Default region name [None]: ap-northeast-1
Default output format [None]:

これでOKです。

Goofysのセット

s3fsが一番?有名かなと思いますが、それより早いというらしい goofys を使っていきます。

Install方法は README にも書いてますが、Linuxだとbinaryファイルを落としてくるだけです。

$ curl -L https://github.com/kahing/goofys/releases/latest/download/goofys -o /usr/local/bin/goofys
$ chmod a+x /usr/local/bin/goofys
$ goofys --version
goofys version 0.24.0-45b8d78375af1b24604439d2e60c567654bcdf88

あとは goofysを使って

$ cd docker-mirakurun-chinachu
$ mkdir recorded/wasabi
$ chmod 777 recorded/wasabi
$ goofys -o allow_other --dir-mode=0777 --endpoint=https://s3.ap-northeast-1.wasabisys.com rokuga recorded/wasabi

これでマウント完了です。

試しに何か置いてみましょう。

$ cd recorded/wasabi
$ echo "HOGEPIYO" > test.txt
$ ls
test.txt

適当なファイルを置いたあと、Wasabiのコンソールに見に行ってみると...

wasabi_6_test_file.png

ちゃんとファイルが作られてました。

録画したファイルをWasabiに飛ばす

(追記) なんか自分の環境だと動いてなさそうです。cronで定期的に wasabiに飛ばしてあげた方がいいかもです。

chinachuには、録画後スクリプトを動かすことができます。そこで、録画終了したファイルをwasabiに飛ばしていきます。

$ touch recorded/wasabi/log
$ vim recorded/upload.sh
$ chmod +x recorded/upload.sh
recorded/upload.sh
#!/bin/bash

log=/usr/local/chinachu/recorded/wasabi/log

echo @$(date +%Y/%m/%d/%H:%M:%S) >> $log
echo "start move file" >> $log
echo $1 >> $log

cd /usr/local/chinachu/recorded
mv $1 wasabi/$1

echo "end move file " >> $log

chinachuに作成したスクリプトを登録

vim ./chinachu/conf/config.json
./chinachu/conf/config.json
{
  # 中略

  "recordedFormat": "<title>_<subtitle>_<date:yymmdd-HHMM>.m2ts",

  "recordedCommand": "/usr/local/chinachu/recorded/upload.sh",    これ追記

  "storageLowSpaceAction": "remove"
}

これで、録画終了したファイルはWasabiに飛ばされます。

ちなみに、「/recorded に wasabiをそのままマウントすればいいじゃん」 って思われる方がいるかもしれません。
実際にできないことはないのですが、録画中は1番組につき常時数Mbpsのアップロードが行われ続けるため、ネットワークへの負荷がでかいです。(Home 5Gを使用している弊宅は無理でした)
また、録画速度 > ネットワークのアップロード速度 になってしまった場合、録画に失敗してしまいますので、あまりおすすめはできません。(ツヨツヨ回線だから大丈夫という方はそうしてください)

いい感じのPlayerでWebで見る

Plex Media Playerや jellyfinなどがありますが、今回はjellyfinを使っていきます

docker compoes up

既に docker-compsoe-jellyfin.yml を用意してますので、これを立ち上げます。

$ cd docker-mirakurun-chinachu
$ docker compose -f docker-compose-jellyfin.yml up -d

初期セットアップ

http://[録画鯖IP]:8096 にアクセスすると、初期設定画面が出てきます。
ここは適当にやってもらって、途中のメディアライブラリの設定で以下のようにセットしてください。

jelly_1.png
jelly_2.png

セットアップが完了すると、こんな感じで見ることができるようになります。
jelly_3.png

外出先から録画したい

はい、本来の目的ですよね。
ちなみにこのままポート解放を行なってやれば外部からアクセスできますが、まぁ大変です。
ってことで、Cloudflareを使っていきましょう

Cloudflare登録

cloudflareとは、有名なCDN事業者です。cloudflareで障害が起こると世界のインターネットの数割が止まると言われているくらいすっごい企業です(語彙力)

実際の登録手順は割愛

ドメイン登録

「え?金かかるの?」
と思われる方が多いと思います。 dottk などで無料ドメインを取って設定できるのですが、最近、無料ドメインだと制限かかなりキツくなってきました。ので、ドメインを取っていきましょう。

cloudflare_1_domain.png

cloudflareにログインした後に ドメインの登録から適当なドメインを取っていきます。
どうせ自分くらいしか使わないので、「.com」など有名どころではなく、「.stream」「.men」などが 年間3.16ドル なのでおすすめです。(円安辛いけどあまり大した金額にならないからヨシ)
ちなみに、私は https://wantan.men ってドメイン持ってます

Cloudflare Access Applicationsの設定

先ほどの画面の右のメニューバーに 「Zero Trust」とあるので、そこからCludflare Zero Trustの設定ページに行きます

Access > Applicationsから Add an applicationより以下の画像の手順で設定していきます。

STEP 1
cloudflare_2_application_1.png
「Self-hosted」を選択

STEP 2
cloudflare_2_application_1.pn2.png

Application name: 好きな言葉(適当)
Subdomain: *
Domain: 取得したドメインを選択

を入力したら NEXT

STEP 3
cloudflare_2_application_1.pn3.png

Policy name:適当
Session Duration:適当(1月とか長いのでもまぁ良い)

下にスクロールして
cloudflare_2_application_1.pn4.png

Create additional rurlesにて
Selector: Emails
Value: 自分のメアド

を入力したら NEXT、そしてそのままNEXTで完了

Cloudflare Access Tunnelsの設定

Access > Tunnels から Create a tunnel より以下の画像の手順で設定していきます。

STEP 1
cloudflare_3_access_1.png

STEP 2
cloudflare_3_access_2.png
録画サーバのOSを選択し(ubuntuならDebian)、写真下部のコマンドが書かれている右側をコピーして、録画サーバ上で実行

$ curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb && sudo dpkg -i cloudflared.deb && sudo cloudflared service install 認証キー

STEP 3
cloudflare_3_access_3.png

Subdomainに好きなの(chinachu)
Domainは取得したやつ
Pathは空白

Service
Typeは HTTP
URLは localhost:10772

を入力したら Saveを押して終了

外からアクセスしてみる

ブラウザを開いたら、先ほど設定したドメインにアクセスすると、以下のような画面が出てくる
cloudflare_4.png

あとは登録したメールアドレスを入力するとメールにアクセスコードが送られてくるので、入力すると、chinachuの画面を見ることができる。
これで外部からのアクセスの設定は終了

外出先から jellyfinを見たい

Access > Tunnels から先ほど作った tunnelsを開きます。
Public Hostname のタブから 「Add a public hostname」クリック
あとは Cloudflare Access Tunnels の STEP3同様に入力
subdomainは media
URLは localhost:8096 に設定してください。

そうすると、 https://media.登録したドメイン/ で見ることができるようになります。


これにて一通りの設定が終わりました。
これで一応外でネット越しにTVを見ることができるようになりました。
今回使ったソフトは基本的にオープンソースです。ソフトウェアを開発されてくださっている方々には感謝しかありません。ありがとうございます。

さて、そろそろ長くなってきた上、時間がなくなってしまったので、CMカットなどはまた別の機会に書いていこうと思います。

ここまで読んでくださった方は相当暇だと思うので、是非やってみてください!

TLB Enjoy Developers Advent Calendar 2022 、明日は @Miyayan さんです!お楽しみに!

  1. クリスマスなんてなかった、いいね?(リア充爆ぜろ)  

  2. ちなみに筆者は社会人3年目の老害です

  3. ネットで販売されてるのは違法だから自力でTV買ってこような?

18
19
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
19