[Raspberry Pi 4] Four-Channel Simultaneous Terrestrial Digital TV Recording Server on Ubuntu with PX-Q1UD

Docker

These are notes. I tried something called a recording server. Since I already had a Docker environment, it was easy to create. I also tried hardware encoding, but it was not stable, so these notes only cover building the normal setup. This is amateur work, so if you use it as a reference, do so at your own risk.

Update: In a separate article, I wrote about operating it with H/W encoding.
[Raspberry Pi 4] [Redo] Four-channel simultaneous terrestrial digital TV recording server on Raspberry Pi

Environment Tested

Raspberry Pi 4 8GB

Ubuntu Server 21.04 (notes)

I used docker-mirakurun-epgstation.

Docker is already installed (Docker installation notes)

$ docker --version
Docker version 20.10.7, build f0df350
$ docker-compose --version
docker-compose version 1.29.2, build unknown

Additional Equipment

PLEX USB-connected full-seg terrestrial digital TV tuner PX-Q1UD

IC card reader

B-CAS card

Connect the additional equipment to the Raspberry Pi.

# チューナによってはファームウェアが必要となるらしい。PX-Q1UD の場合は下記が必要。
$ sudo apt-get install -y unzip
$ wget http://plex-net.co.jp/plex/px-s1ud/PX-S1UD_driver_Ver.1.0.1.zip
$ unzip PX-S1UD_driver_Ver.1.0.1.zip
$ sudo cp PX-S1UD_driver_Ver.1.0.1/x86/i386/isdbt_rio.inp /lib/firmware/

再起動する

$ sudo reboot

ホスト側でも B-CAS カードが認識されるか確認しておく。(同じラズパイ4なのに、B-CASを認識しないボードがあってハマったため)

$ sudo apt install -y pcsc-tools pcscd $ pcsc_scan Japanese Chijou Digital B-CAS Card (pay TV)

pcscd は止めておく

$ sudo systemctl stop pcscd.socket $ sudo systemctl disable pcscd.socket

Run the Mirakurun and EPGStation Containers

Without overthinking it, follow the official procedure.

# 公式サイトの手順を順番に実行していく
$ git clone https://github.com/l3tnun/docker-mirakurun-epgstation.git
$ cd docker-mirakurun-epgstation
$ cp docker-compose-sample.yml docker-compose.yml
$ cp epgstation/config/config.yml.template epgstation/config/config.yml
$ cp epgstation/config/operatorLogConfig.sample.yml epgstation/config/operatorLogConfig.yml
$ cp epgstation/config/epgUpdaterLogConfig.sample.yml epgstation/config/epgUpdaterLogConfig.yml
$ cp epgstation/config/serviceLogConfig.sample.yml epgstation/config/serviceLogConfig.yml
$ docker-compose run --rm -e SETUP=true mirakurun

Modify docker-compose.yml as needed. If logs keep being written to the SD card, the SD card will wear out quickly, so I set the logging driver to none.

# 各コンテナの定義に下記を追加
        logging:
            driver: none

Start the Containers

Start the containers. The first time, container images are built, so it takes a while. Relax and wait patiently.

$ docker-compose up -d
Building epgstation
...
(それなりにビルドに時間がかかります。20分ぐらい)

After the containers start, you can access EPGStation at http://<Raspberry Pi address>:8888. It also takes a little time to retrieve the program guide and related data, but recording worked without problems. 👍

me
Me

At first I was building this with a 4 GB Pi 4, but I got stuck because it would not recognize the B-CAS card. Other Pi 4 and Pi 3 boards recognized it normally, so I moved the SD card to a Pi 4 8 GB partway through and continued the work. Did I draw a bad board? It is a mystery. 🍣

Bonus: I Tried Hardware Encoding, but... TBC

Even though the Pi 4 has more CPU power, it seems difficult to watch a program currently being broadcast by streaming it. There is no problem watching recorded video, but when watching a currently airing program in real time, the video stops every few seconds, making it basically unwatchable. Encoding after recording also takes quite a long time.

So I also looked into hardware encoding. However, I have not been able to run it stably at this point, so I will not write the details and will only leave notes on the items I tried.

Sites I Used as References

[Hardware Encoding] Hardware encoding in a Raspberry Pi 64-bit environment [Raspberry Pi]

I built ffmpeg on a Raspberry Pi 4 64-bit environment and tried hardware encoding

Checking the load when hardware-encoding MPEG-2 TS video to H.264 on a Raspberry Pi 4

Settings Needed for H/W Encoding

What I found by searching was that doing the following should make H/W encoding possible even from a container.

  • Allow the container to access the host H/W.
  • With ffmpeg 4.2.x, the video turns green, so it seems you need to use a different version.
  • It seems you need to use a codec called h264_v4l2m2m.
  • Change the settings so EPGStation encodes using h264_v4l2m2m.

Trying It

Allow the Container Side to Access the Host H/W
# /dev/vchiq にアクセスする必要があるらしい。そのパーミッションを変える。ラズパイもリブートしておく。
$ echo 'SUBSYSTEM=="vchiq",GROUP="video",MODE="0666"' | sudo tee /etc/udev/rules.d/10-vchiq-permissions.rules
# docker-compose.yml を編集して epgstationのコンテナから /dev 周りを見れるようにする
# /dev/video* が本当に必要かどうかがよくわかっていない。
# ホストのH/Wをいじれるように privileged: true にする
$ vi docker-compose.yml
    epgstation:
        build: epgstation
        volumes:
            - /etc/localtime:/etc/localtime:ro
            - ./epgstation/config:/app/config
            - ./epgstation/data:/app/data
            - ./epgstation/thumbnail:/app/thumbnail
            - ./epgstation/logs:/app/logs
            - ./recorded:/app/recorded
            - /dev/vchiq:/dev/vchiq
            - /dev/video10:/dev/video10
            - /dev/video11:/dev/video11
            - /dev/video12:/dev/video12
            - /dev/video13:/dev/video13
            - /dev/video14:/dev/video14
            - /dev/video15:/dev/video15
            - /dev/video16:/dev/video16
        privileged: true
Change the ffmpeg Version

If I use the container built as-is, ffmpeg 4.2.4 is built. The latest release was 4.4, so I tried that for now. In the 4.3 series, 4.3.2 seems to be the latest. I did not change the configure options. As others have shown, when encoding with h264_v4l2m2m specified in 4.2.x, a wonderfully green video was generated. That phenomenon did not occur with 4.4, so it seems to be working.

# Dockerfile を編集 
$ vi epgstation/Dockerfile

ENV FFMPEG_VERSION=4.2.4

ENV FFMPEG_VERSION=4.4

コンテナをビルドし直す

$ docker-compose build

I do not really understand it, but I tried something like a benchmark. This is an example of entering the container, running the command, and encoding a video of about three minutes.

# CPUでエンコードした場合。0.3倍速?なので10分以上かかった。エンコード中のCPU使用率は 380% 程度。
$ time ffmpeg -i test.m2ts -c:v libx264 -b:v 3M -y test.libx264.mp4

frame= 5631 fps=9.1 q=-1.0 Lsize= 75349kB time=00:03:07.78 bitrate=3287.0kbits/s dup=26 drop=0 speed=0.302x

real 10m21.868s user 37m52.953s sys 1m15.214s

# H/Wエンコードした場合。2.3倍速?なので1分ちょいで終わった。速い。エンコード中のCPU使用率は 180% 程度。
$ time ffmpeg -i test.m2ts -c:v h264_v4l2m2m -b:v 3M -num_capture_buffers 64 -y test.host.h264_v4l2m2m.mp4

frame= 5631 fps= 72 q=-0.0 Lsize=   71658kB time=00:03:07.55 bitrate=3129.9kbits/s dup=26 drop=0 speed=2.39

real    1m18.752s
user    2m14.459s
sys     0m14.174s

It seems to be working. The encoded video also plays properly. The CPU-encoded video is cleaner. The H/W-encoded video looked jagged. This might be adjustable with options.

Change the EPGStation Settings

Change the configuration files so encoding uses h264_v4l2m2m.

# libx264 が指定されているところを h264_v4l2m2m に置換する
$ emacs epgstation/config/config.yml
# 置換
# replace-string libx264 to h264_v4l2m2m 

こっちも適当に修正

$ emacs epgstation/config/enc.js

// コーデックを変更 //const codec = ’libx264’; const codec = ‘h264_v4l2m2m’;

// その他設定 Array.prototype.push.apply(args,[ ‘-preset’, preset, ‘-aspect’, ‘16:9’, ‘-c:v’, codec, ‘-crf’, crf, ‘-b:v’, ‘3M’, // ビットレートの指定が必要らしいので追加。 ‘-f’, ‘mp4’, ‘-c:a’, ‘aac’, ‘-ar’, ‘48000’, ‘-ab’, audioBitrate, ‘-ac’, ‘2’, output ]);

For now, this changes post-recording encoding to H/W encoding. However, from the second time onward, encoding would not finish, recording itself would stop working, and it was too unstable for actual operation. This is as far as I got for now.

me
Me

It would be great if I could get H/W encoding working properly, but I do not watch that much TV anyway. 🍣

More importantly, worrying about the SD card lifespan is getting tiresome, so maybe I should move the environment from the SD card to an SSD.