RaspberryPi3/RaspberryPi4 + PX-W3U4 + EPGStationで構築する録画鯖

# はじめに
私の所有しているハードウェア構成にマッチした情報がなかったため備忘録として残しておきます。

# ハードウェア構成
1. RaspberryPi3
2. PX-W3U4
3. [カードリーダー](https://www.amazon.co.jp/NTT%E3%82%B3%E3%83%9F%E3%83%A5%E3%83%8B%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%BA-%E6%8E%A5%E8%A7%A6%E5%9E%8BIC%E3%82%AB%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%83%BB%E3%83%A9%E3%82%A4%E3%82%BF%E3%83%BC-Tax-Mac%E5%AF%BE%E5%BF%9C-SCR3310-NTTCom/dp/B00117VJ7O)

# 環境構築手順
## RaspberryPiの構築
* [イメージ](https://www.raspberrypi.org/downloads/raspbian/)は「Raspbian Buster Lite 2019-07-10」を使用した

## kernelのビルド(px4_drvを構築するために必要:DKMSとかあるがそんな洒落たものは使わん)

環境構築に必要なパッケージを取得

```console
$ sudo apt-get install build-essential bc git bison flex libssl-dev autoconf automake pcscd libpcsclite-dev pcsc-tools git build-essential cmake libpcsclite1 libpcsclite-dev pcscd pcsc-tools pkg-config npm sqlite3 ffmpeg
```

kernelのソースコードを取得

```console
$ mkdir -p ~/usr/src # kernelのソースコードはポリシー的にrootで/usr/srcに配置したほうがよいかも
$ pushd ~/usr/src
$ git clone -b rpi-5.6.y --depth=1 https://github.com/raspberrypi/linux.git linux-5.6.y
```

kenerlのビルド

* 時間がかかる(3~4時間？)のでtmuxとかでセッションの復旧ができるようにしておいたほうがよい
(20/2/29追記：rpi4で52分に短縮)
(make -j 4 zImage modules dtbs  10869.38s user 1444.11s system 391% cpu 52:22.40 total)

```console
$ pushd linux-5.6.y
$ KERNEL=kernel7
$ make bcm2709_defconfig
$ make -j 4 zImage modules dtbs
$ sudo make modules_install
$ sudo cp arch/arm/boot/dts/*.dtb /boot/
$ sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
$ sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
$ sudo scripts/mkknlimg arch/arm/boot/zImage /boot/$KERNEL.img
$ popd
```

チューナーのドライバ生成

```console
$ git clone https://github.com/nns779/px4_drv.git
$ pushd px4_drv/fwtool && make -j 4
$ wget http://plex-net.co.jp/download/pxw3u4v1.4.zip && unzip pxw3u4v1.4.zip
$ sudo ./fwtool x64/PXW3U4.sys /lib/firmware/it930x-firmware.bin
$ popd
$ pushd px4_drv/driver
$ make -j 4
$ sudo make install
$ sudo modprobe px4_drv
$ ls /dev/px4video*
/dev/px4video0
/dev/px4video1
/dev/px4video2
/dev/px4video3
$ popd
```

B25の構築

```console
$ git clone https://github.com/stz2012/libarib25.git
$ pushd libarib25
$ cmake .
$ make -j 4
$ sudo make install
```
recpt1の構築

```console
$ git clone https://github.com/stz2012/recpt1.git
$ pushd recpt1/recpt1
$ sed -i -e "/^char \*bsdev\[NUM_BSDEV\] = {$/a \ \ \ \ \"/dev/px4video1\",\n\ \ \ \ \"/dev/px4video0\"," pt1_dev.h
$ sed -i -e "/^char \*isdb_t_dev\[NUM_ISDB_T_DEV\] = {$/a \ \ \ \ \"/dev/px4video2\",\n\ \ \ \ \"/dev/px4video3\"," pt1_dev.h
$ ./autogen.sh
$ ./configure --enable-b25
$ make -j 4
$ sudo make install
$ pushd /tmp
$ recpt1 --b25 --strip 21 20 test.ts # 試しに録画しtest.tsがVLCなどで再生できることを確認
$ popd; popd
```

mirakurunの構築

```console
$ ######################################### ↓古い {
$ pushd /tmp
$ curl -sL http://deb.nodesource.com/setup_8.x | sudo bash -
$ popd
$ sudo apt install -y nodejs
$ sudo npm install pm2@2.10.4 -g
$ sudo npm install mirakurun -g --unsafe --production
$ sudo npm install arib-b25-stream-test -g --unsafe
$ sudo gpasswd -a $USER video
$ sudo mirakurun config tuners # チューナーの設定を変更
$ ######################################### } ↓新しい(20/3/2) {
$ pushd /tmp
$ curl -sL http://deb.nodesource.com/setup_10.x | sudo bash -
$ popd
$ sudo apt install -y nodejs
$ sudo npm install pm2 -g
$ sudo npm install mirakurun -g --unsafe --production
$ sudo npm install arib-b25-stream-test -g --unsafe
$ sudo gpasswd -a $USER video
$ sudo mirakurun config tuners # チューナーの設定を変更
$ ######################################### }
```

```yaml:/usr/local/etc/mirakurun/tuners.yml
- name: PX4-S1
  types:
    - BS
    - CS
  command: recpt1 --device /dev/px4video0 --lnb 15 <channel> - -
  decoder: arib-b25-stream-test
  isDisabled: false

- name: PX4-S2
  types:
    - BS
    - CS
  command: recpt1 --device /dev/px4video1 --lnb 15 <channel> - -
  decoder: arib-b25-stream-test
  isDisabled: false

- name: PX4-T1
  types:
    - GR
  command: recpt1 --device /dev/px4video2 <channel> - -
  decoder: arib-b25-stream-test
  isDisabled: false

- name: PX4-T2
  types:
    - GR
  command: recpt1 --device /dev/px4video3 <channel> - -
  decoder: arib-b25-stream-test
  isDisabled: false
```

```console
$ sudo mirakurun restart
$ sudo curl -X PUT "http://localhost:40772/api/config/channels/scan" # しばし待つ
$ sudo mirakurun restart
$ sudo npm install rivarun -g
$ sudo rivarun --list | sed 's/},/},\n/g' # チャンネルを確認
$ sudo pm2 install pm2-logrotate
$ sudo vim /etc/logrotate.d/mirakurun
```

```text:/etc/logrotate.d/mirakurun
/usr/local/var/log/mirakurun.stdout.log
/usr/local/var/log/mirakurun.stderr.log
/{
  compress
  rotate 53
  missingok
  notifempty
}
```

EPGStationの構築

```console
$ git clone https://github.com/l3tnun/EPGStation.git
$ pushd EPGStation
$ sudo npm install --unsafe-perm=true --allow-root
$ sudo npm run build
$ cp config/config.sample.json config/config.json
$ cp config/operatorLogConfig.sample.json config/operatorLogConfig.json
$ cp config/serviceLogConfig.sample.json config/serviceLogConfig.json
$ sudo vim /usr/local/etc/mirakurun/channel.yml
```

```yaml:/usr/local/etc/mirakurun/channel.yml
- name: ＮＨＫＥテレ
  type: GR
  channel: '13'
- name: トップタワー
  type: GR
  channel: '17'
- name: ＣＢＣテレビ
  type: GR
  channel: '18'
- name: 中京テレビ
  type: GR
  channel: '19'
- name: ＮＨＫ総合
  type: GR
  channel: '20'
- name: 東海テレビ０１
  type: GR
  channel: '21'
- name: メ～テレ
  type: GR
  channel: '22'
- name: テレビ愛知
  type: GR
  channel: '23'
- name: 三重テレビ
  type: GR
  channel: '27'
- name: ぎふチャン
  type: GR
  channel: '30'
- name: BS Asahi
  type: BS
  channel: BS01_0
  serviceId: 151
- name: BS Asahi (Sub)
  type: BS
  channel: BS01_0
  serviceId: 152
- name: BS-TBS
  type: BS
  channel: BS01_1
  serviceId: 161
- name: WOWOW Prime
  type: BS
  channel: BS03_0
  serviceId: 191
  isDisabled: true
- name: BS JAPAN
  type: BS
  channel: BS03_1
  serviceId: 171
- name: WOWOW Live
  type: BS
  channel: BS05_0
  serviceId: 192
  isDisabled: true
- name: WOWOW Cinema
  type: BS
  channel: BS05_1
  serviceId: 193
  isDisabled: true
- name: BS11
  type: BS
  channel: BS09_0
  serviceId: 211
- name: BS SPTV
  type: BS
  channel: BS11_1
  serviceId: 241
  isDisabled: true
- name: BS Nippon (Sub)
  type: BS
  channel: BS13_0
  serviceId: 142
- name: BS Nippon
  type: BS
  channel: BS13_0
  serviceId: 141
- name: BS Fuji
  type: BS
  channel: BS13_1
  serviceId: 181
- name: NHK BS1 (Sub)
  type: BS
  channel: BS15_0
  serviceId: 102
- name: NHK BS1
  type: BS
  channel: BS15_0
  serviceId: 101
- name: NHK BS Premium (Sub)
  type: BS
  channel: BS15_1
  serviceId: 104
- name: NHK BS Premium
  type: BS
  channel: BS15_1
  serviceId: 103
- name: TV Asahi Ch. 2
  type: CS
  channel: CS2
  serviceId: 299
  isDisabled: true
- name: TV Asahi Ch. 1
  type: CS
  channel: CS2
  serviceId: 298
  isDisabled: true
- name: SPTV Promo
  type: CS
  channel: CS4
  serviceId: 100
- name: AT-X
  type: CS
  channel: CS16
  serviceId: 333
  isDisabled: true
- name: AT-X HD
  type: SKY
  channel: ATXHD
  serviceId: 33435
  satelite: JCSAT3A
  isDisabled: true
- name: AXN HD
  type: SKY
  channel: AXNHD
  serviceId: 33418
  satelite: JCSAT4A
  isDisabled: true
- name: BS SPTV
  type: SKY
  channel: CH585
  serviceId: 33353
  satelite: JCSAT3A
  isDisabled: true
- name: 放送大学BSキャンパスex
  type: BS
  channel: BS11_2
  serviceId: 231
- name: 放送大学BSキャンパスon
  type: BS
  channel: BS11_2
  serviceId: 232

```

```json:~/usr/src/EPGStation/config/config.json
...
  "ffmpeg": "/usr/bin/ffmpeg",
  "ffprobe": "/usr/bin/ffprobe",
  "recorded": "/mnt/TV",
...
```
```console
$ sudo pm2 startup
$ sudo pm2 start dist/server/index.js --name "epgstation"
$ sudo pm2 save
$ popd
```

あとはブラウザからhttp://[ラズパイIP]:8888にアクセスすればOK
こんな感じ
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342159/dde833ed-5779-5845-dd21-fd0d279d27d1.png)