EPGStation config.ymlのカスタマイズ（自己流）

# はじめに
この記事は[EPGStation](https://github.com/l3tnun/EPGStation/blob/master/Readme.md)（録画ソフト）`config.yml`のカスタマイズの備忘録です。
（浅い理解 × 自己流でカスタマイズしているので、多少変な点は目をつぶってください。。）
デフォルト設定よりも高画質な録画にしたり、HDDへのアクセス頻度を落としたりといったことをしています。


# config.ymlを調べる
config.ymlで難しかったのが`stream`セクションです。`live`やら`recorded`やら`ts`やら`encoded`やらややこしかったです。基本的には[公式マニュアル的なもの](https://github.com/l3tnun/EPGStation/blob/master/doc/conf-manual.md)を参照し、映像規格的な部分（TSやらHLSやら）は別途ググって調べました。


# 自分なりの理解
細かい話は分かりませんが、自分なりに以下の解釈をしました。
- stream｜ストリームに関する設定を書く（ストリームは、TVチューナーから流れてくる映像のこと）
    - live｜ライブ視聴に関する設定
        - ts｜TSはトランスポートストリームの略らしい。m2tsを何に変換するかを指定みたい
            - ts配下の設定は変換後の各種ファイル形式を表す？ m2tsllとhlsだけあればいい？
            - m2tsll｜テレビ放送とかでも使われている規格らしい？
            - hls｜HTTP Live Streamingの略。Appleが開発した規格で、ライブ配信によく使われる規格らしい。
    - recorded｜録画に関する設定
        - ts｜m2tsを何に変換するかを指定みたい
        - encoded｜エンコード済みの動画を何に変換して再生するかを指定みたい
- エンコードに関する設定は`config.yml`ではなく`enc.js`というnodejsコードに直書きされている。

# 自己流カスタマイズ (1/2) 画質に関する設定変更
### ストリーミングの設定変更
`config.yml`を編集していきます。本当によく分かっていませんが、上述の様に`hls`の設定だけあればいいと判断して、他のファイル形式はバッサリ削りました。（これでも動いているから一応大丈夫なのでしょう。。）
```yaml:config.ymlのstreamセクションのみ抜粋
stream:
    live:
        ts:
            hls:
                - name: 1080p
                  cmd:
                      '%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown
                      -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1
                      -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a
                      aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:1080 -b:v 10000k -preset veryfast
                      -flags +loop-global_header %OUTPUT%'
                - name: 720p
                  cmd:
                      '%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown
                      -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1
                      -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a
                      aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast
                      -flags +loop-global_header %OUTPUT%'
                - name: 480p
                  cmd:
                      '%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown
                      -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1
                      -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a
                      aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast
                      -flags +loop-global_header %OUTPUT%'
    recorded:
        ts:
            hls:
                - name: 1080p
                  cmd:
                      '%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown
                      -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1
                      -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a
                      aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:1080 -b:v 10000k -preset veryfast
                      -flags +loop-global_header %OUTPUT%'
                - name: 720p
                  cmd:
                      '%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown
                      -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1
                      -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a
                      aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast
                      -flags +loop-global_header %OUTPUT%'
                - name: 480p
                  cmd:
                      '%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown
                      -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1
                      -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a
                      aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast
                      -flags +loop-global_header %OUTPUT%'

        encoded:
            hls:
                - name: 1080p
                  cmd:
                      '%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 0 -ignore_unknown
                      -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1
                      -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a
                      aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf scale=-2:1080 -b:v 10000k -preset veryfast -flags
                      +loop-global_header %OUTPUT%'
                - name: 720p
                  cmd:
                      '%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 0 -ignore_unknown
                      -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1
                      -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a
                      aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf scale=-2:720 -b:v 3000k -preset veryfast -flags
                      +loop-global_header %OUTPUT%'
                - name: 480p
                  cmd:
                      '%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 0 -ignore_unknown
                      -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1
                      -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a
                      aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf scale=-2:480 -b:v 3000k -preset veryfast -flags
                      +loop-global_header %OUTPUT%'
```

### 録画される動画の設定変更
録画された動画の画質については、`config.yml`に加えて`enc.js`も変更する必要があります。
まずは`config.yml`の設定変更です。`encode`セクションにはもともと1つしかエントリがありませんが、以下の様に3つに変更します。
```yaml:config.ymlのencodeセクションのみ抜粋
encode:
    - name: mp4_high
      cmd: '%NODE% %ROOT%/config/enc.js high'
      suffix: .mp4
      rate: 4.0
    - name: mp4_middle
      cmd: '%NODE% %ROOT%/config/enc.js middle'
      suffix: .mp4
      rate: 4.0
    - name: mp4_low
      cmd: '%NODE% %ROOT%/config/enc.js low'
      suffix: .mp4
      rate: 4.0
```

上の変更によって録画する画質の選択ができる様になったので、実際の処理でも画質を変更できる様に`enc.js`を編集します。

```js:enc.js抜粋
// 以下の内容を削除します
// >>> ↓これは削除する >>>
// その他設定
Array.prototype.push.apply(args,[
    '-preset', preset,
    '-aspect', '16:9',
    '-c:v', codec,
    '-crf', crf,
    '-f', 'mp4',
    '-c:a', 'aac',
    '-ar', '48000',
    '-ab', audioBitrate,
    '-ac', '2',
    output
]);
// <<< ↑これは削除する <<<

// 元の内容に変えて以下のコードを挿入します
// >>> ↓これを挿入する >>>
//　画質設定を引数で受けとる
var qp = '24'
if (process.argv[2] == 'high'){
    qp = '20'
} else if (process.argv[2] == 'middle'){
    qp = '24'
} else if (process.argv[2] == 'low'){
    qp = '28'
}
// 画質設定を反映する
Array.prototype.push.apply(args,[
    '-preset', preset,
    '-aspect', '16:9',
    '-c:v', codec,
    '-crf', crf,
    '-f', 'mp4',
    '-c:a', 'aac',
    '-ar', '48000',
    '-ab', audioBitrate,
    '-ac', '2',
    '-qp', qp,
    output
]);
// <<< ↑これを挿入する <<<
```


# 自己流カスタマイズ (2/2) HDDへのアクセス頻度を落とす変更
EPGStationは番組情報の更新や、ストレージの空き容量チェックで定期的にストレージに接続します。
今回HDDを使っているため、あまり頻繁に突かれるとウィーンとHDDがうるさいので、接続頻度を落とす様に設定変更をしました。
```yaml:config.yml抜粋
# 番組情報を更新する間隔（分）を6時間に変更
epgUpdateIntervalTime: 360

# ストレージの空き容量をチェックする間隔（秒）を6時間に変更
storageLimitCheckIntervalTime: 21600
<<< config.yml変更内容 <<<
```


以上

# 関連記事
- [NASNEを自作してみた](https://qiita.com/hirmr/items/cde0baf51d82ca9de791)