PLEX PX-Q3PE4 で docker-mirakurun-epgstation を使いたい

Linux で TS 抜き環境で TV 視聴/録画サーバを作る。

DVR チューナーサーバーとして API を提供する mirakurun と UI を提供するクライアントの epgstation 、バックエンドのDBとして mysql/mariadb の組み合わせが定番。
手軽に使うようにするために、 docker 環境が何種類かつくられている。


今回は、 docker-mirakurun-epgstation 
https://github.com/l3tnun/docker-mirakurun-epgstation
を使ってみた。

しかしながらこの docker イメージでは対応しているチューナーカードが限定されている。手持ちの PLEX の PX-Q3PE4 は対応外のチューナーカードであった。これを使えるようにして設定したが、意外と手こずったので構築メモ。

なお、Docker 素人のため Docker の基本的な使い方も含めて。

# 環境
- Ubuntu 20.04 Ja LTS
- PLEX PX-Q3PE4
- NTT SCR3310-NTTCom スマートカードリーダー
  - B-CAS カード(赤)
- Fujitsu TX1310 M3
  -  Intel Celeron CPU G3930 @ 2.90GHz
  -  Memory 4GBytes



# 事前準備

- Docker は既にインストール済み
  - 「Ubuntu20.04 に Docker を導入する (Also Ubuntu 22.04)」
- https://qiita.com/nanbuwks/items/0ba1d13b3cd27e5c6426
- PLEX PX-Q3PE4 は既にドライバインストール済
- 録画コマンドである recpt1 は以下の記事通り既にインストール、動作確認済
  -「recpt1 で Cannot start b25 decoder」
  - https://qiita.com/nanbuwks/items/4b26ce36d07824411633

# 作戦を立てる

docker-mirakurun-epgstation を使ってみたい。
https://github.com/l3tnun/docker-mirakurun-epgstation
しかし前述の通りこの docker イメージは PLEX PX-Q3PE4 に対応していない。

- docker-mirakurun-epgstation には  mirakurn, epgstation, mariadb が入っている。
- このうち、TVチューナーカードに関係するのは mirakurun。
- mirakurun で TV チューナーカードは tuners.yml によって録画時の挙動を記述する。
- 標準の tuners.yml では dvbv5-zap コマンドを使って録画する設定になっている
- dvbv5-zap コマンドは /dev/dbv/adapter0/... などの /dev/dbv 以下にあるデバイスファイルを使っているらしい。


そのようなチューナーは
「Mirakurunのチューナー設定（DVBデバイスを使う場合） - にゃののん日記」
https://nyanonon.hatenablog.com/entry/20190909/1568040000
によると、

>　PT3、PT2、PT1、PX-S1UD、PX-BCUD等のチューナーは DVB デバイスとして認識され、/dev/dvb以下のadapter0から始まるデバイスファイルで扱うことが出来る。


これから推測して、 PT3、PT2、PT1、PX-S1UD、PX-BCUD等のチューナー は dvbv5-zap から使えるが、 PX4 系のドライバは dvbv5-zap では対応していないぽい。(伝聞ではなくてちゃんと調べるにはどうしたらいいのだろう?)


l3tnun/docker-mirakurun-epgstation で対応するには、以下の方法が必要。

- tuners.yml を変更して PX4 系のコマンドに書き換える
- 録画コマンドを導入する
- デバイスにアクセスする


## PX-Q3PE4 で録画する仕組み

さて、本来 PX-Q3PE4 の録画コマンドは Linux では何を使うのかな?

まず、PX-Q3PE4 のドライバは Linux 上では実質的に↓しか選択肢が無い。
「nns779/px4_drv: Unofficial Linux driver for PLEX PX4/PX5/PX-MLT series ISDB-T/S receivers (not V4L-DVB)」
https://github.com/nns779/px4_drv

これを使った場合、チューナーデバイスは /dev/px4_drv[n] となる。
これを使った録画は、これが使えるようにビルドした 録画コマンド recpt1 を使用する。

recpt1 を単体で呼び出した使用例として、
```
$ recpt1 --device /dev/px4video2 --b25 --strip 27 30 recordtest.ts
```

のようにすると、以下の条件で録画する。

- /dev/px4video2 を使用
- b25 デコードを行う 
- 地デジ27チャンネル ( NHK総合1@東京 )
- 30秒間
- 録画ファイル名 recordtest.ts

## 解決策

https://medium.com/chinachu/mirakurun-3-0-0-night-whale-23aaf2c23c25
によると、

> ⚠️ DVB デバイス以外で、従来の録画コマンドを利用する場合は /usr/local/mirakurun/opt/bin/ に録画コマンドをコピー (シンボリックリンク不可) してください。このディレクトリにデフォルトで PATH が通っています。また、 docker-compose.yml を編集してデバイスにアクセスができるようにしてください。

とある。 このことから、以下の2つの方法が考えられる。

1. Docker ホストで録画コマンド recpt1 を /dev/px4_drv[n] を使えるようにビルドし、 Docker 内の /usr/local/mirakurun/opt/bin/ に配置
1. Docker 内で録画コマンド recpt1 を /dev/px4_drv[n] を使えるようにビルドし、適切に配置

今回は後者で解決することにした


具体的には、以下の設定を行う


- docker 内の mirakurun から   /dev/px4_drv[n] の チューナーデバイスを見えるようにする
- docker の設定を変更して、dx4_drv に対応した recpt1 をdocker 内に生成する
- docker 内の tuners.yml を変更して PX-Q3PE4 に対応した recpt1 を使うように録画時の挙動を記述する



# 設定


## docker-mirakurun-epgstation 

適当なディレクトリで

```
$ git clone https://github.com/l3tnun/docker-mirakurun-epgstation -b v2 docker-mirakurun-epgstation
$ cd docker-mirakurun-epgstation
$ ls
LICENSE  Readme.md  docker-compose-sample.yml  docs  epgstation  mirakurun  recorded  setup.sh
```
epgstation と mirakurun はそれぞれ別の dockerimage を使い、それ用のフォルダが用意されている。
しかしながら epgstation はここに書かれた設定を使わずに、以下のように新たに git clone したものを使う。

```

$ git clone https://github.com/Chinachu/Mirakurun
```
今回は Mirakurun 3.9.0-rc.2 になりました。

```
$ ls
LICENSE  Mirakurun  Readme.md  docker-compose-sample.yml  docs  epgstation  mirakurun  recorded  setup.sh
```
mirakurun が  docker-mirakurun-epgstation  にあったもの、 Mirakurun が 改めて  git clone してできたものです。

Mirakurun/docker/Dockerfile を編集します。
「【完全解説】LinuxとPX-W3U4でEPGStation v2を構築する方法（PX-Q3U4／W3PE4／Q3PE4）  |  ページ 4  |  小茂根の暮らし」
https://komone-life.com/2021/03/07/how-to-install-epgstation-docker-bcas-3/4/
を元に、以下のようにしました。

```

RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y --no-install-recommends \
        ca-certificates \
        make \
        gcc \
        g++ \
        pkg-config \
        pcscd \
        libpcsclite-dev \
        libccid \
        libdvbv5-dev \
        pcsc-tools \
        dvb-tools \
        && \
# recpt1
\
    apt-get install -y --no-install-recommends \
        build-essential \
        libtool \
        autoconf \
        git \
        automake &&\
    git clone https://github.com/stz2012/recpt1 /tmp/recpt1 && \
    cd /tmp/recpt1/recpt1 && \
    ./autogen.sh && \
    ./configure && \
    make && \
    make install && \
#    rm -rf /tmp/recpt1 && \
    apt-get autoremove -y && \

    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
COPY --from=build /usr/local/lib/node_modules/mirakurun /app
CMD ["./docker/container-init.sh"]
EXPOSE 40772 9229
```


epgstation の Dockerファイルを作ります。

```
$ cd epgstation
$ ls
$ alpine.Dockerfile  config  data  debian.Dockerfile  logs  thumbnail
$ cp debian.Dockerfile Dockerfile
$ cd ..

```

docker-compose.yml をサンプルからコピーします。
```
$ ls
LICENSE  Mirakurun  Readme.md  docker-compose-sample.yml  docs  epgstation  mirakurun  recorded  setup.sh
$ cp docker-compose-sample.yml docker-compose.yml 
```
docker-compose.yml を編集します。
元ファイルの内容は以下の通りです。
```
version: '3.7'
services:
    mirakurun:
        image: chinachu/mirakurun
        cap_add:
            - SYS_ADMIN
            - SYS_NICE
        ports:
            - "40772:40772"
            - "9229:9229"
        volumes:
            - ./mirakurun/conf:/app-config
            - ./mirakurun/data:/app-data
        environment:
            TZ: "Asia/Tokyo"
        devices:
            - /dev/bus:/dev/bus
            - /dev/dvb:/dev/dvb
        restart: always
        logging:
            driver: json-file
            options:
                max-file: "1"
                max-size: 10m

    mysql:
        image: mariadb:10.5
        # image: mysql:8.0 # 囲み文字を使用する場合
        volumes:
            - mysql-db:/var/lib/mysql
        environment:
            MYSQL_USER: epgstation
            MYSQL_PASSWORD: epgstation
            MYSQL_ROOT_PASSWORD: epgstation
            MYSQL_DATABASE: epgstation
            TZ: "Asia/Tokyo"
        command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --performance-schema=false --expire_logs_days=1 # for mariadb
        # command: --character-set-server=utf8mb4 --collation-server=utf8mb4_0900_as_ci --performance-schema=false --expire_logs_days=1 --default-authentication-plugin=mysql_native_password # for myql
        restart: always
        logging:
            options:
                max-size: "10m"
                max-file: "3"

    epgstation:
        build:
            context: "./epgstation"
            dockerfile: "debian.Dockerfile"
        volumes:
            - ./epgstation/config:/app/config
            - ./epgstation/data:/app/data
            - ./epgstation/thumbnail:/app/thumbnail
            - ./epgstation/logs:/app/logs
            - ./recorded:/app/recorded
        environment:
            TZ: "Asia/Tokyo"
        depends_on:
            - mirakurun
            - mysql
        ports:
            - "8888:8888"
            - "8889:8889"
#         user: "1000:1000"
#         devices:
#             - /dev/dri:/dev/dri
        restart: always

volumes:
    mysql-db:
        driver: local


```
これを以下のように変更しました。

```
$ diff docker-compose-sample.yml docker-compose.yml 
1c1
< version: '3.7'
---
> version: '3'
3a4,6
>         build:
>           context: Mirakurun
>           dockerfile: docker/Dockerfile
12c15
<             - ./mirakurun/conf:/app-config
---
>             - ./Mirakurun/config:/app-config
16a20,27
>             - /dev/px4video0:/dev/px4video0
>             - /dev/px4video1:/dev/px4video1
>             - /dev/px4video2:/dev/px4video2
>             - /dev/px4video3:/dev/px4video3
>             - /dev/px4video4:/dev/px4video4
>             - /dev/px4video5:/dev/px4video5
>             - /dev/px4video6:/dev/px4video6
>             - /dev/px4video7:/dev/px4video7
18d28
<             - /dev/dvb:/dev/dvb
48d57
<             dockerfile: "debian.Dockerfile"
54c63
<             - ./recorded:/app/recorded
---
>             - /media/tv_current:/app/recorded
```

2022/08/26追記： ここから：

最初に以下の設定を抜かしていたら EPG 番組表の動作がうまくいきませんでした。後に述べるようにこの記述を含んで再設定したらうまく動作するようになりました(version指定に問題があったかどうかは不明)。
```
1c1
< version: '3.7'
---
> version: '3'
```
2022/08/26追記： ここまで


dvb デバイスを使った場合、tuners.yml は自動で生成されますが今回はそうではないので
 Mirakurun/config/tuners.yml をあらかじめ編集しておきます。


https://eco.senritu.net/ubuntu20-04_plex_px-q3pe4_mirakurun_epgstation/
ここを参考に以下のようにしました。

```
- name: adapter_px0_0
  types:
    - BS
    - CS
  command: recpt1 <channel> - -
  decoder: arib-b25-stream-test
- name: adapter_px0_1
  types:
    - BS
    - CS
  command: recpt1 <channel> - -
  decoder: arib-b25-stream-test
- name: adapter_px0_2
  types:
    - GR
  command: recpt1 <channel> - -
  decoder: arib-b25-stream-test
- name: adapter_px0_3
  types:
    - GR
  command: recpt1 <channel> - -
  decoder: arib-b25-stream-test
- name: adapter_px0_4
  types:
    - BS
    - CS
  command: recpt1 <channel> - -
  decoder: arib-b25-stream-test
- name: adapter_px0_5
  types:
    - BS
    - CS
  command: recpt1 <channel> - -
  decoder: arib-b25-stream-test
- name: adapter_px0_6
  types:
    - GR
  command: recpt1 <channel> - -
  decoder: arib-b25-stream-test
- name: adapter_px0_7
  types:
    - GR
  command: recpt1 <channel> - -
  decoder: arib-b25-stream-test
```
epgstation に必要なものを作成します
```
$ cd epgstation/config
$ cp config.yml.template config.yml
$ cp operatorLogConfig.sample.yml operatorLogConfig.yml
$ cp epgUpdaterLogConfig.sample.yml epgUpdaterLogConfig.yml
$ cp serviceLogConfig.sample.yml serviceLogConfig.yml
$ cp enc.js.template enc.js
$ cd ../..
```

(2022/8/27追記：enc.js の作成が抜けていて、エンコードができなくなっていました。修正しました。)

チャンネル設定は自動設定に任せることにします。


# docker を作る

```

$ docker-compose pull
$ docker-compose build --no-cache
```

長い時間がかかります。1時間程かかりました。
起動の準備ができたら、今まで動いていたホスト側のスマートカードサービスを停止しておきます。

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

```
ここで停止し忘れたら Docker 内のサービス起動が失敗するのかな?

起動します。
```
$ docker-compose up -d
```

# 動作チェック

試した環境では、docker を動作させた PC は 192.168.42.100 でした。
以下のようにして確認をしていきました。

 ` http://192.168.42.100:40772/api/channels`
とアクセスすると
```
[{"type":"GR","channel":"16","name":"ＴＯＫＹＯ　ＭＸ","services":[]},{"type":"GR","channel":"21","name":"フジテレビ","services":[]},{"type":"GR","channel":"22","name":"ＴＢＳ","services":[]},{"type":"GR","channel":"23","name":"テレビ東京","services":[]},{"type":"GR","channel":"24","name":"テレビ朝日","services":[]},{"type":"GR","channel":"25","name":"日テレ","services":[]},{"type":"GR","channel":"26","name":"ＮＨＫＥテレ・東京","services":[]},{"type":"GR","channel":"27","name":"ＮＨＫ総合・東京","services":[]},{"type":"BS","channel":"BS15_0","name":"BS:BS15_0","services":[{"id":400101,"serviceId":101,"networkId":4,"name":"ＮＨＫＢＳ１"},{"id":400102,"serviceId":102,"networkId":4,"name":"ＮＨＫＢＳ１"}]},{"type":"BS","channel":"BS03_1","name":"BS:BS03_1","services":[{"id":400103,"serviceId":103,"networkId":4,"name":"ＮＨＫＢＳプレミアム"},{"id":400104,"serviceId":104,"networkId":4,"name":"ＮＨＫＢＳプレミアム"}]},{"type":"BS","channel":"BS13_0","name":"BS:BS13_0","services":[{"id":400141,"serviceId":141,"networkId":4,"name":"ＢＳ日テレ"},{"id":400142,"serviceId":142,"networkId":4,"name":"ＢＳ日テレ"}]},{"type":"BS","channel":"BS01_0","name":"BS:BS01_0","services":[{"id":400151,"serviceId":151,"networkId":4,"name":"ＢＳ朝日１"},{"id":400152,"serviceId":152,"networkId":4,"name":"ＢＳ朝日２"}]},{"type":"BS","channel":"BS01_1","name":"BS:BS01_1","services":[{"id":400161,"serviceId":161,"networkId":4,"name":"ＢＳ－ＴＢＳ"}]},{"type":"BS","channel":"BS01_2","name":"BS:BS01_2","services":[{"id":400171,"serviceId":171,"networkId":4,"name":"ＢＳテレ東"}]},{"type":"BS","channel":"BS13_1","name":"BS:BS13_1","services":[{"id":400181,"serviceId":181,"networkId":4,"name":"ＢＳフジ・１８１"}]},{"type":"BS","channel":"BS09_0","name":"BS:BS09_0","services":[]},{"type":"BS","channel":"BS11_1","name":"BS:BS11_1","services":[]}]
```

チャンネルを取得しているのがわかります。


 `http://192.168.42.100:40772/`

にアクセスして、Events  を見てみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e062df8b-1fa9-6ac1-80c1-826e32fc58ad.png)

特にエラーは出ていないようです。

 ` http://192.168.42.100:8888/`
にアクセスすると、そのうち番組表が出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/432f046c-4636-3b93-c19d-8cd989ba66f6.png)



とりあえず、動きました。

# tips 
- checksignal で受信強度を調べることができる
- tssplitter で多重化ストリームを分離できる
- arib-b25-stream-test b25decoder 
- epgdump csv TSファイル名 で epg 情報を抜き出せる。(放送波がちゃんと録画できているかどうかのチェック)

- コンテナ内で手動で録画する
```
$ docker exec -it docker-mirakurun-epgstation_mirakurun_1 /bin/bash
# recpt1 --strip 27 30 /app-data/handrecorded.tss

```

現状では recpt1 が b25 を組み入れてないため --b25 オプションは使えない。

# エンコーディング速度

https://www.intel.com/content/www/us/en/developer/articles/technical/encode-and-decode-capabilities-for-7th-generation-intel-core-processors-and-newer.html

によると使用している i610 で H.264 エンコードは使えそうです。

先の「エンコードエラー」にてテストしたCUIでのエンコードでは

> speed=0.503x    

となり、結構遅かったでした。

しかしながら epgstation ブラウザ内だと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/71ea779b-8a2a-0a3d-5888-dea453ea60f6.png)
割と十分な速度が出ています。これだと設定変更しなくてもいいかな・・・


# トラブルシューティング  -  設定編

## EPG番組表が歯抜けになる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/20c73b3c-5c7d-05d5-6dae-b91d4c6c80cc.png)


docker を -d 無しで起動していたら、以下のような表示が出ていました。


```
epgstation_1  | [2022-08-25T10:10:52.461] [FATAL] system - epg updater is disconnected
mysql_1       | 2022-08-25 10:10:52 26204 [Warning] Aborted connection 26204 to db: 'epgstation' user: 'epgstation' host: '172.30.0.4' (Got an error reading communication packets)
epgstation_1  | [2022-08-25T10:10:52.480] [INFO] system - start epg updater pid: 288152
mirakurun_1   | 2022-08-25T10:10:53.439+09:00 info: 172.30.0.4 - GET /api/docs HTTP/1.1 200 27559 - 5.551 ms epgstation/2.5.1 MirakurunClient/3.5.0 Node/v14.17.1 (linux)
mirakurun_1   | 2022-08-25T10:10:53.441+09:00 info: 172.30.0.4 - GET /api/docs HTTP/1.1 200 27559 - 5.643 ms epgstation/2.5.1 MirakurunClient/3.5.0 Node/v14.17.1 (linux)
mirakurun_1   | 2022-08-25T10:10:53.465+09:00 info: 172.30.0.4 - GET /api/services? HTTP/1.1 200 - - 6.403 ms epgstation/2.5.1 MirakurunClient/3.5.0 Node/v14.17.1 (linux)
mirakurun_1   | 2022-08-25T10:10:53.737+09:00 info: 172.30.0.4 - GET /api/programs? HTTP/1.1 200 - - 50.093 ms epgstation/2.5.1 MirakurunClient/3.5.0 Node/v14.17.1 (linux)
mysql_1       | 2022-08-25 10:10:55 26205 [Warning] Aborted connection 26205 to db: 'epgstation' user: 'epgstation' host: '172.30.0.4' (Got an error reading communication packets)
epgstation_1  | [2022-08-25T10:10:55.598] [FATAL] system - epg updater is disconnected
mirakurun_1   | 2022-08-25T10:10:55.599+09:00 info: 172.30.0.4 - GET /api/events/stream? HTTP/1.1 200 - - 3.986 ms epgstation/2.5.1 MirakurunClient/3.5.0 Node/v14.17.1 (linux)
epgstation_1  | [2022-08-25T10:10:55.618] [INFO] system - start epg updater pid: 288163
```

mysql 関係でなにか問題が起こっているのでしょうか?


「Mirakurun 3.9.0-beta.24 以降の MySQL(MariaDB) 設定について」
https://github.com/l3tnun/EPGStation/blob/master/doc/mysql-mirakurun-3.9.0-beta.24.md

において、

> Mirakurun 3.9.0-beta.24 以降から Unicode 処理が変更された影響により、従来の EPGStation の文字コード設定(utf8)ではデータ ベースが更新できない不具合が発生しました。以下に対処方法を記載します。

とあります。

しかしながらそこの問題を睨んでも

 > config/config.yml を開き mysql.charset を utf8mb4 に設定する
> ```
> dbtype: mysql
> mysql:
>     host: 127.0.0.1
>     port: 3306
>     user: epgstation
>     password: epgstation
>     database: epgstation
>     charset: utf8mb4
> ```

> docker-compose.yml の services -> mysql -> command を以下のように変更する。

> ```
> # MariaDB の場合
> command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --performance-schema=false --expire_logs_days=1
> ```

どちらも設定は正常でした。しかしながら念の為に コンテナを削除、設定を変更してビルドし直しバックアップから DB 内容を復元したら



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0041b090-8549-a1ed-367a-8fd8d3791159.png)

直りました


なお、変更点は docker-compose.yml の冒頭、


```
version: '3.7'
```
とあったのを、
```
version: '3'
```
に変更しました。これで最新になったのが良かったのかな? と思ったら
「Compose ファイルのバージョンとアップグレード &mdash; Docker-docs-ja 20.10 ドキュメント」
https://docs.docker.jp/compose/compose-file/compose-versioning.html
によると、

> 注釈
> 
> Compose ファイルのバージョンを指定する場合は、メジャー番号とマイナー番号の両方を指定する必要があります。マイナーバージョンの指定がなければ、最新のマイナーバージョンではなく、デフォルトの 0 が使われます。その結果、新しいバージョンで追加された機能はサポートされません。たとえば
> 
> version: "3"
> は、以下の指定と同等です。
> 
> version: "3.0"

ということで古いバージョンになってしまいました。3.7の指定がダメだったのか、docker の再構成が効いたのかは良くわかっていません(汗




## エンコードエラー

epgstation/logs/Service/encode.log

には以下のようにエラーが出ていました。

```
[2022-08-25T19:00:03.066] [INFO] encode - add new encode: 6
[2022-08-25T19:00:03.129] [INFO] encode - encode start. mode: H.264 name: アニメ　忍たま乱太郎「ミミズな牧之介の段」[字] file: /app/recorded/2022年08月25日18時50分00秒-アニメ　忍
たま乱太郎「ミミズな牧之介の段」[字].m2ts -> /app/recorded/2022年08月25日18時50分00秒-アニメ　忍たま乱太郎「ミミズな牧之介の段」[字].mp4
[2022-08-25T19:00:03.129] [INFO] encode - encodeId: 6
[2022-08-25T19:00:03.130] [INFO] encode - encodeCmd.suffix: .mp4
[2022-08-25T19:00:03.130] [INFO] encode - queueItem.directory: undefined
[2022-08-25T19:00:03.130] [INFO] encode - outputFilePath: /app/recorded/2022年08月25日18時50分00秒-アニメ　忍たま乱太郎「ミミズな牧之介の段」[字].mp4
[2022-08-25T19:00:03.167] [INFO] encode - create new encode process: 1661421603166
[2022-08-25T19:00:03.346] [INFO] encode - exit code: 1, signal: null
[2022-08-25T19:00:03.346] [ERROR] encode - encode failed: 6 /app/recorded/2022年08月25日18時50分00秒-アニメ　忍たま乱太郎「ミミズな牧之介の段」[字].mp4
[2022-08-25T19:00:03.346] [INFO] encode - delete encode output file: /app/recorded/2022年08月25日18時50分00秒-アニメ　忍たま乱太郎「ミミズな牧之介の段」[字].mp4
[2022-08-25T19:00:04.348] [ERROR] encode - delete encode output file failed: /app/recorded/2022年08月25日18時50分00秒-アニメ　忍たま乱太郎「ミミズな牧之介の段」[字].mp4
[2022-08-25T19:00:04.348] [ERROR] encode - [Error: ENOENT: no such file or directory, unlink '/app/recorded/2022年08月25日18時50分00秒-アニメ　忍たま乱太郎「ミミズな牧之介の段」[字].mp4'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'unlink',
  path: '/app/recorded/2022年08月25日18時50分00秒-アニメ　忍たま乱太郎「ミミズな牧之介の段」[字].mp4'
}

```

encode してみます

```
# time ffmpeg -i test.ts -vf bwdif=0 -c:v libx264 -preset medium -crf 23 -c:a copy -bsf:a aac_adtstoasc test.mp4
ffmpeg version 4.2.4 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 8 (Debian 8.3.0-6)
  configuration: --prefix=/usr/local --disable-shared --pkg-config-flags=--static --enable-gpl --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-version3 --enable-libaribb24 --enable-nonfree --disable-debug --disable-doc
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
[mpeg2video @ 0x55e33f85d2c0] Invalid frame dimensions 0x0.
    Last message repeated 4 times
[mpegts @ 0x55e33f858100] start time for stream 2 is not set in estimate_timings_from_pts
[mpegts @ 0x55e33f858100] PES packet size mismatch
[mpegts @ 0x55e33f858100] Could not find codec parameters for stream 3 (Unknown: none ([13][0][0][0] / 0x000D)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x55e33f858100] Could not find codec parameters for stream 4 (Unknown: none ([13][0][0][0] / 0x000D)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x55e33f858100] Could not find codec parameters for stream 5 (Unknown: none ([13][0][0][0] / 0x000D)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x55e33f858100] Could not find codec parameters for stream 6 (Unknown: none ([13][0][0][0] / 0x000D)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x55e33f858100] Could not find codec parameters for stream 7 (Unknown: none ([13][0][0][0] / 0x000D)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x55e33f858100] Could not find codec parameters for stream 8 (Unknown: none ([13][0][0][0] / 0x000D)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x55e33f858100] Could not find codec parameters for stream 9 (Unknown: none ([13][0][0][0] / 0x000D)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mpegts, from 'test.ts':
  Duration: 00:05:04.78, start: 64842.424089, bitrate: 15495 kb/s
  Program 1024 
    Metadata:
      service_name    : ?NHK?Am9g?1�?El5~
      service_provider: 
    Stream #0:0[0x100]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv, bt709, top first), 1440x1080 [SAR 4:3 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x110]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 255 kb/s
    Stream #0:2[0x138]: Data: bin_data ([6][0][0][0] / 0x0006)
    Stream #0:3[0x140]: Unknown: none ([13][0][0][0] / 0x000D)
    Stream #0:4[0x160]: Unknown: none ([13][0][0][0] / 0x000D)
    Stream #0:5[0x161]: Unknown: none ([13][0][0][0] / 0x000D)
    Stream #0:6[0x162]: Unknown: none ([13][0][0][0] / 0x000D)
    Stream #0:7[0x170]: Unknown: none ([13][0][0][0] / 0x000D)
    Stream #0:8[0x171]: Unknown: none ([13][0][0][0] / 0x000D)
    Stream #0:9[0x172]: Unknown: none ([13][0][0][0] / 0x000D)
    Stream #0:10[0x130]: Subtitle: arib_caption (Profile A) ([6][0][0][0] / 0x0006)
  Program 1025 
    Metadata:
      service_name    : ?NHK?Am9g?2�?El5~
      service_provider: 
  Program 1408 
    Metadata:
      service_name    : ?NHK?7HBS?G�?El5~
      service_provider: 
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg2video (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[libx264 @ 0x55e33f940100] using SAR=4/3
[libx264 @ 0x55e33f940100] using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2
[libx264 @ 0x55e33f940100] profile High, level 4.0
[libx264 @ 0x55e33f940100] 264 - core 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'test.mp4':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 1440x1080 [SAR 4:3 DAR 16:9], q=-1--1, 29.97 fps, 30k tbn, 29.97 tbc
    Metadata:
      encoder         : Lavc58.54.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
    Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 255 kb/s
[mpegts @ 0x55e33f858100] Invalid timestamps stream=0, pts=5857867380, dts=14447792963, size=79240eed=0.496x    
[mpegts @ 0x55e33f858100] DTS 5857864377 < 14447795966 out of order
[mpegts @ 0x55e33f858100] PES packet size mismatch:05:04.32 bitrate=5168.5kbits/s dup=10 drop=0 speed=0.503x    
[mpeg2video @ 0x55e33f8a9bc0] Invalid mb type in P-frame at 10 6
[mpeg2video @ 0x55e33f8a9bc0] Warning MVs not available
[mpeg2video @ 0x55e33f8a9bc0] concealing 5580 DC, 5580 AC, 5580 MV errors in P frame
test.ts: corrupt decoded frame in stream 0 time=00:05:04.53 bitrate=5171.7kbits/s dup=10 drop=0 speed=0.503x    
frame= 9134 fps= 15 q=-1.0 Lsize=  194470kB time=00:05:04.67 bitrate=5228.9kbits/s dup=12 drop=0 speed= 0.5x    
video:184765kB audio:9383kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.165917%
[libx264 @ 0x55e33f940100] frame I:53    Avg QP:20.86  size:119315
[libx264 @ 0x55e33f940100] frame P:2558  Avg QP:23.82  size: 39201
[libx264 @ 0x55e33f940100] frame B:6523  Avg QP:25.69  size: 12663
[libx264 @ 0x55e33f940100] consecutive B-frames:  0.9%  2.3% 28.0% 68.8%
[libx264 @ 0x55e33f940100] mb I  I16..4: 15.3% 75.6%  9.2%
[libx264 @ 0x55e33f940100] mb P  I16..4:  3.8% 13.8%  0.6%  P16..4: 47.8% 12.9%  6.5%  0.0%  0.0%    skip:14.5%
[libx264 @ 0x55e33f940100] mb B  I16..4:  0.3%  1.1%  0.1%  B16..8: 40.9%  3.8%  0.8%  direct: 5.1%  skip:48.0%  L0:41.7% L1:49.8% BI: 8.5%
[libx264 @ 0x55e33f940100] 8x8 transform intra:75.6% inter:86.7%
[libx264 @ 0x55e33f940100] coded y,uvDC,uvAC intra: 57.8% 65.0% 15.6% inter: 20.3% 25.0% 1.0%
[libx264 @ 0x55e33f940100] i16 v,h,dc,p: 26% 27% 12% 35%
[libx264 @ 0x55e33f940100] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 20% 17% 27%  5%  5%  6%  6%  6%  7%
[libx264 @ 0x55e33f940100] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 25% 16% 13%  6%  9%  9%  8%  7%  6%
[libx264 @ 0x55e33f940100] i8c dc,h,v,p: 53% 23% 19%  5%
[libx264 @ 0x55e33f940100] Weighted P-Frames: Y:5.5% UV:1.9%
[libx264 @ 0x55e33f940100] ref P L0: 57.0% 15.8% 19.7%  7.2%  0.3%
[libx264 @ 0x55e33f940100] ref B L0: 87.4% 10.4%  2.2%
[libx264 @ 0x55e33f940100] ref B L1: 96.6%  3.4%
[libx264 @ 0x55e33f940100] kb/s:4966.32

real	10m9.275s
user	19m13.440s
sys	0m4.644s
```

問題ありませんでした。 enc.js の問題かな? と思ったら・・・ enc.js の生成をしていませんでした。
```
$ cd epgstation/config
$ cp config.yml.template config.yml
$ cp enc.js.template enc.js
$ cd ../..
```

念の為 docker-compose down して up し直すと、無事に動くようになりました。


# 運用Tips


## 予約バックアップ

コンテナ epgstation 内に入る

```
$ docker-compose run --rm --entrypoint bash epgstation
Starting docker-mirakurun-epgstation_mysql_1     ... done
Starting docker-mirakurun-epgstation_mirakurun_1 ... done
Creating docker-mirakurun-epgstation_epgstation_run ... done
/app# 
```

コンテナ内で DB を config/backup.json にバックアップしてコンテナ外に出る
```
# npm run backup config/backup.json
# exit
```


epgstation/config の中身は以下の通りです。

作業前

```
config.yml           enc.js.template                 epgUpdaterLogConfig.yml       operatorLogConfig.yml        serviceLogConfig.yml
config.yml.template  epgUpdaterLogConfig.sample.yml  operatorLogConfig.sample.yml  serviceLogConfig.sample.yml
```
作業後

```
backup.json  config.yml.template  epgUpdaterLogConfig.sample.yml  operatorLogConfig.sample.yml  serviceLogConfig.sample.yml
config.yml   enc.js.template      epgUpdaterLogConfig.yml         operatorLogConfig.yml         serviceLogConfig.yml
```
backup はちゃんとできていますね!




## 予約リストア
epgstation のコンテナに入る
```
$ docker-compose run --rm --entrypoint bash epgstation
```

epgstation コンテナ内で作業

```
# npm run restore config/backup.json
# exit
```

## Docker コンテナ作り直す

適宜バックアップを行う。コンテナ作り直すと予約データは消えてしまうので、Mysql/Mariadb データベースのバックアップを作成。


コンテナを落とす

```
$ docker-compose kill epgstation && docker-compose rm -f epgstation
Going to remove docker-mirakurun-epgstation_epgstation_1
Removing docker-mirakurun-epgstation_epgstation_1 ... done


```

この時点で予約バックアップを行っておく。
作業終わったら、


```
$ docker-compose down -v
Stopping docker-mirakurun-epgstation_mirakurun_1 ... done
Stopping docker-mirakurun-epgstation_mysql_1     ... done
Removing docker-mirakurun-epgstation_mirakurun_1 ... done
Removing docker-mirakurun-epgstation_mysql_1     ... done
Removing network docker-mirakurun-epgstation_default
Removing volume docker-mirakurun-epgstation_mysql-db

```

docker を終了したので設定をやり直す。
適宜 docker-compose.yml などを書き換え
変更が終わったら、docker-compose.yml に基づきイメージを新たに取得

```
$ docker-compose pull
Pulling mirakurun  ... done
Pulling mysql      ... done
Pulling epgstation ... done
```
イメージをビルド
```
$ docker-compose build --pull
```
適宜コンテナ内に入って作業。予約データの復元などはここで行う。

更新したイメージで起動

```
$ docker-compose up -d
```




## チャンネルを増やす

BS12ツェルビ や 放送大学が無いので 追加したい。

Mirakurun/config/channels.yml の適当なところに以下を書き足します。

```
- name: BS12
  type: BS
  channel: BS09_2
  serviceId: 222

- name: 放送大学 BS1
  type: BS
  channel: BS11_1
  serviceId: 231

- name: 放送大学 BS2
  type: BS
  channel: BS11_1
  serviceId: 232

```

docker を down して、再度 up すると反映できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/aef7c1ef-d7b0-e3e7-c10c-339db94e4615.png)

## 更に放送大学ラジオを追加する

Mirakurun/config/channels.yml を以下のようにして、docker を down して、再度 up したのですが・・・

```
- name: 放送大学 ラジオ
  type: BS
  channel: BS11_2
  serviceId: 531

- name: 放送大学 BS1
  type: BS
  channel: BS11_1
  serviceId: 231

- name: 放送大学 BS2
  type: BS
  channel: BS11_1
  serviceId: 232

- name: 放送大学 BS3
  type: BS
  channel: BS11_1
  serviceId: 233

```
これで動くかな? しかしながら docker-compose down して up した後、番組表が何も表示されなくなってしまいました。docker を作り直して対処。(原因不明)


## Docker サービス内でログオンして作業
まず、コンテナの名前を調べる

```
$ docker-compose config --service
mirakurun
mysql
epgstation
```

または

```
$ docker-compose ps --service   
mirakurun
mysql
epgstation
```

名前がわかったのでログオンしてみます。

mirakurun に run コマンドでログオンする例
```
$ docker-compose run --rm --entrypoint bash mirakurun
Creating docker-mirakurun-epgstation_mirakurun_run ... done
root@f9c5a98059c1:/app#
```
こちらは新たにサービスを作ってログオン、終了したらサービスは削除します。一時的にログインして動作確認などに使えばいいですね。

eppstation に run コマンドでログオンする例
```
$ docker-compose run --rm --entrypoint bash epgstation
Starting docker-mirakurun-epgstation_mysql_1     ... done
Starting docker-mirakurun-epgstation_mirakurun_1 ... done
Creating docker-mirakurun-epgstation_epgstation_run ... done
/app# 
```


現在動いている epgstation に exec コマンドでログオンする例
```
$ docker-compose exec epgstation bash

root@5eb7a4bebd34:/app#
```
run コマンドはサービスを起動してログオンしましたが、exec コマンドは現在動いているサービスにログオンします。

または

```
$ docker exec -it docker-mirakurun-epgstation_epgstation_1 /bin/bash


```

ログオンした後、日本語が文字化けして困ったとき
```
# ls recorded 
''$'\357\274\256\357\274\250\357\274\253\343\202\271\343\203\232\343\202\267\343\203\243\343\203\253\343\200\200\351\201\270\343\200\214\346\277\200\351\227\230\343\202\254\343\203\200\343\203\253\343\202\253\343\203\212\343\203\253\343\200\200\346\202\262\345\212\207\343\201\256\346\214\207\346\217\256\345\256\230\343\200\215\357\274\217\343\200\214\346\262\226\347\270\204\346\210\246\343\200\200\345\205\250\350\250\230\351\214\262\343\200\215''.ts'
''$'\357\274\256\357\274\250\357\274\253\343\202\271\343\203\232\343\202\267\343\203\243\343\203\253\343\200\214\343\202\246\343\202\257\343\203\251\343\202\244\343\203\212\344\276\265\346\224\273\345\215\212\345\271\264\343\200\200\343\200\234\342\200\234\343\203\227\343\203\274\343\203\201\343\203\263\343\201\256\346\210\246\344\272\211\342\200\235\345\207\272\345\217\243\343\201\257\343\201\251\343\201\223\343\201\253\343\200\234\343\200\215''.ts'
''$'\357\274\256\357\274\250\357\274\253\343\202\271\343\203\232\343\202\267\343\203\243\343\203\253\343\200\214\343\203\223\343\203\253\343\203\236\343\200\200\347\265\266\346\234\233\343\201\256\346\210\246\345\240\264\343\200\215''.ts'
.
.
.
# export LANG=C.UTF-8
# ls recorded 
 ＮＨＫスペシャル　選「激闘ガダルカナル　悲劇の指揮官」／「沖縄戦　全記録」.ts
 ＮＨＫスペシャル「ウクライナ侵攻半年　〜“プーチンの戦争”出口はどこに〜」.ts
 ＮＨＫスペシャル「ビルマ　絶望の戦場」.ts
.
.
.
```

# トラブルシューティング - 運用編

## B25 デコードできない

「Docker サービス内でログオンして作業」を参照して、mirakurun にログインします。
```
$ docker-compose exec mirakurun bash
```

カード認識できているかどうか調べます。

```
# pcsc_scan
Using reader plug'n play mechanism
Scanning present readers...
Waiting for the first reader... - 
```

認識しません。

カード指し直しましたが状況改善せず。
再起動してみました。

ホストOSをリブート、ないし以下のように docker-compose を使いました。

```
$ docker-compose down

```

```

$ docker-compose up -d

```

改めて pcsc_scan してみます。
```
# pcsc_scan 
SCardEstablishContext: Service not available.
```

おや? しかしながらこのまま動作確認すると、録画が B25 デコードされてました。
なお、Service not available でなくちゃんと反応があるときもありました。

```
# pcsc_scan
Using reader plug'n play mechanism
Scanning present readers...
0: NTT Communications Corp. SCR3310-NTTCom USB SmartCard Reader [Vendor Interface] 00 00
 
Sun Feb 12 10:19:58 2023
 Reader 0: NTT Communications Corp. SCR3310-NTTCom USB SmartCard Reader [Vendor Interface] 00 00
  Event number: 0
  Card state: Card inserted, Shared Mode, 
  ATR: 3B F0 12 00 FF 91 81 B1 7C 45 1F 03 99

ATR: 3B F0 12 00 FF 91 81 B1 7C 45 1F 03 99
+ TS = 3B --> Direct Convention
+ T0 = F0, Y(1): 1111, K: 0 (historical bytes)
  TA(1) = 12 --> Fi=372, Di=2, 186 cycles/ETU
    21505 bits/s at 4 MHz, fMax for Fi = 5 MHz => 26881 bits/s
  TB(1) = 00 --> VPP is not electrically connected
  TC(1) = FF --> Extra guard time: 255 (special value)
  TD(1) = 91 --> Y(i+1) = 1001, Protocol T = 1 
-----
.
.
.
```

カードリーダーが反応しないのは1ヶ月に一度ぐらい発生しています。うーむ。


## 信号レベルの確認

```
$ docker exec -it docker-mirakurun-epgstation_mirakurun_1 /bin/bash

```
NHK総合(東京スカイツリー送信のチャンネル)
```
#  checksignal --device /dev/px4video2 27
device = /dev/px4video2
C/N = 27.813392dB^C
SIGINT received. cleaning up...

```
テレビ東京(東京スカイツリー送信のチャンネル)

```
#  checksignal --device /dev/px4video2 23
device = /dev/px4video2
C/N = 26.684056dB^C
SIGINT received. cleaning up...

```
BSのNHK BS1
```
#  checksignal --device /dev/px4video1 101
device = /dev/px4video1
C/N = 17.730118dB^C
SIGINT received. cleaning up...
```
BSの放送大学EX
```
#  checksignal --device /dev/px4video1 231
device = /dev/px4video1
C/N = 17.090128dB^C
SIGINT received. cleaning up...
```

## pcsc をホスト側で行う

まずは docker を停止します。

```
$ docker-compose down


```

ホスト側で、
```

$ sudo systemctl start pcscd.socket
```
してから、必要な作業を行う
```

$ pcsc_scan
```
なお、カードリーダーはUSBポートから刺し直さないと反応しなかったことがありました。
作業が終わったら、
```

$ sudo systemctl stop pcscd.socket
```
してから、docker を起動し直します。

```
$ docker-compose up -d


```

## ルートファイルシステムがいっぱいになって起動しなくなった

recovery mode で起動し、シングルユーザモードで録画ファイルなどを削除してルートファイルシステムを空けて再起動

## mariadb コンテナが不調(Aria recovery failed)

上のルートファイルシステムがいっぱいになった後、起動したらこのトラブルが発生しました。
解決方法は別記事にしてみました。

「docker-mirakurun-epgstation で mariadb コンテナが不調(Aria recovery failed)」
→ https://qiita.com/nanbuwks/items/394a06315af242aff953

## Webページにアクセスできなくなった

「docker-mirakurun-epgstation のチューナーカードを PX-MLT8PE に換装」
https://qiita.com/nanbuwks/items/ef160c9b9ee1f402b3cf
で設定した環境で、トラブルに見舞われました。

(ここでは 192.168.0.200 で設定したサーバの場合です。 )

EPGStation 画面が出ない `http://192.168.0.200:8888/`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c0f8da25-5d65-12e6-d731-cb2c0190ebf8.png)

Miarakurun `http://192.168.0.200:40772/` も同様でした。


docker ps でみてみると、あれ? Mirakurun は?
```
$ docker ps
CONTAINER ID   IMAGE                                    COMMAND                   CREATED       STATUS         PORTS                                                           NAMES
387abc3c6b6b   docker-mirakurun-epgstation_epgstation   "npm start"               6 weeks ago   Up 8 minutes   0.0.0.0:8888-8889->8888-8889/tcp, :::8888-8889->8888-8889/tcp   docker-mirakurun-epgstation_epgstation_1
3543c591c5a3   mariadb:10.5                             "docker-entrypoint.s…"   6 weeks ago   Up 8 minutes   3306/tcp                                                        docker-mirakurun-epgstation_mysql_1
```


```
$ docker-compose start
Starting mirakurun  ... error
Starting mysql      ... done
Starting epgstation ... error

ERROR: for mirakurun  Cannot start service mirakurun: error gathering device information while adding custom device "/dev/pxmlt8video0": no such file or directory
```


これは、ドライバが新しいカーネルに対応していなかったのが原因でした。

こちらにまとめました


「Mirakurun が起動しない (./include/linux/export.h:29:22: error: passing argument ... でドライバのコンパイルエラー)」
https://qiita.com/nanbuwks/items/5a8870a46cb7d564c49b