rokkonet

PC・Androidソフトウェア・アプリの開発・使い方に関するメモ

EPGStationを「Ubuntu20.04 + PT2 + Mirakurun」にインストール

2023 Oct. 21.
2022 Feb. 26.
2021 Oct. 24.
2021 May 30.
2021 Apr. 07.

出典 EPGStation/doc/linux-setup.md at master · l3tnun/EPGStation · GitHub

関連ソフトの稼働確認

$ gcc --version
$ node --version
$ curl -o - http://<MirakurunURL>:<Port>/api/version
## 通常は curl -o - http://localhost:40772/api/version

$ ffmpeg -version
$ python --version
$ ps ax | grep mysql | grep -v grep

gccのインストール

$ sudo apt update && sudo apt install build-essential

FFMPEGのインストール

$ sudo apt update && sudo apt install ffmpeg

pythonのインストール

pyenvをEPGStationを稼働させるユーザー(tvとした)でインストールする

出典 ubuntu 20.04 / 18.04 に pyenv をインストールする話 #Python - Qiita

$ su - tv

$ sudo apt update && sudo apt install build-essential \
    libffi-dev \
    libssl-dev \
    zlib1g-dev \
    liblzma-dev \
    libbz2-dev \
    libreadline-dev \
    libsqlite3-dev \
    git

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv

$ echo 'export PYENV_ROOT="${HOME}/.pyenv"' >> ~/.profile
$ echo 'export PATH="${PYENV_ROOT}/bin:${PATH}"' >> ~/.profile
$ echo 'eval "$(pyenv init -)"' >> ~/.profile
source ~/.profile


pyenvがインストールされていることを確認する

$ pyenv -v


インストールできるpythonの一覧を出力する

$ pyenv install --list

適当なバージョンのpythonをインストールする

$ pyenv install 3.9.4


インストールされたpythonを確認する

$ pyenv versions


tvユーザーでのpythonバージョンを当該ユーザー空間グローバルに設定する

$ pyenv global 3.9.4


mariadbのインストールとEPGStation向け設定

mariadbのEPGStation向け設定

出典 https://github.com/y-hashida/Memo_Mirakurun-and-EPGStation

・データベースとユーザーを作成し、大量発生するバイナリログの保管期間を1日にする

$ sudo mysql
> CREATE DATABASE epgstation CHARACTER SET utf8;
  2021 Oct. 24.
  CREATE DATABASE epgstation CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; の方がよいと思う。
  COLLATE設定について
   https://qiita.com/tfunato/items/e48ad0a37b8244a788f6:title

> GRANT ALL ON epgstation.* TO epgstation@localhost IDENTIFIED BY 'epgstation';
> GRANT ALL ON epgstation.* TO epgstation@127.0.0.1 IDENTIFIED BY 'epgstation';
> SET GLOBAL expire_logs_days = 1;
> exit

EPGStationのインストール

出典 EPGStation/doc/linux-setup.md at master · l3tnun/EPGStation · GitHub

$ su - tv
$ git clone https://github.com/l3tnun/EPGStation.git
$ cd EPGStation
$ npm run all-install
$ npm run build

$ cp config/config.sample.yml config/config.yml
$ cp config/operatorLogConfig.sample.yml config/operatorLogConfig.yml
$ cp config/epgUpdaterLogConfig.sample.yml config/epgUpdaterLogConfig.yml
$ cp config/serviceLogConfig.sample.yml config/serviceLogConfig.yml

~/EPGStation/config/config.ymlを修正する

unix socket接続できなかったので、
 unix socket接続設定を削除
 40772ポートIP接続を設定
mysql利用に設定
録画ファイル名を設定
録画ファイル保存ディレクトリを設定
マニュアル EPGStation/doc/conf-manual.md at master · l3tnun/EPGStation · GitHub

# mirakurunPath: http+unix://%2Fvar%2Frun%2Fmirakurun.sock/
mirakurunPath: http://localhost:40772

# dbtype: sqlite
# sqlite:
#   extensions:
#     - '/hoge/regexp.dylib'
#   regexp: true

dbtype: mysql
mysql:
    host: localhost
    port: 3306
    user: epgstation
    password: epgstation
    database: epgstation

recordedFormat: '%SHORTYEAR%%MONTH%%DAY%%HOUR%%MIN%%TYPE%%CH%-%SID%-%CHNAME%-%TITLE%'

recorded:
    - name: recorded    ## ブラウザ上に表示される保存場所名
      path: '/RECORDED/DIR'    ## 保存ディレクトリのフルパス

#ffmpeg: /usr/local/bin/ffmpeg
ffmpeg: /usr/bin/ffmpeg
#ffprobe: /usr/local/bin/ffprobe
ffprobe: /usr/bin/ffprobe

ポート開放

8888番ポートをLAN内に開放する

(例)

$ sudo ufw enable
$ sudo ufw allow proto tcp from 192.168.1.0/24 to any port 8888    ## LAN
$ sudo ufw allow proto udp from 192.168.1.0/24 to any port 8888    ## LAN
$ sudo ufw allow proto tcp from 10.8.0.0/24 to any port 8888    ## openVPN
$ sudo ufw allow proto udp from 10.8.0.0/24 to any port 8888    ## openVPN
$ sudo ufw reload

自動起動設定(初回のみ行う)
$ cd ~/EPGStation
$ sudo npm install pm2 -g
$ sudo pm2 startup ubuntu
$ pm2 start dist/index.js --name "epgstation"
$ pm2 save


上記コマンド実行時の画面出力内容

$ sudo npm install pm2 -g
/usr/local/bin/pm2 -> /usr/local/lib/node_modules/pm2/bin/pm2
/usr/local/bin/pm2-dev -> /usr/local/lib/node_modules/pm2/bin/pm2-dev
/usr/local/bin/pm2-docker -> /usr/local/lib/node_modules/pm2/bin/pm2-docker
/usr/local/bin/pm2-runtime -> /usr/local/lib/node_modules/pm2/bin/pm2-runtime
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.3.1 (node_modules/pm2/node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ pm2@4.5.6
added 175 packages from 194 contributors in 15.996s


$ sudo pm2 startup ubuntu

                          Runtime Edition

        PM2 is a Production Process Manager for Node.js applications
                     with a built-in Load Balancer.

                Start and Daemonize any application:
                $ pm2 start app.js

                Load Balance 4 instances of api.js:
                $ pm2 start api.js -i 4

                Monitor in production:
                $ pm2 monitor

                Make pm2 auto-boot at server restart:
                $ pm2 startup

                To go further checkout:
                http://pm2.io/


                        -------------

[PM2] Init System found: systemd
-----------------------------------------------------------
 PM2 detected systemd but you precised ubuntu
 Please verify that your choice is indeed your init system
 If you arent sure, just run : pm2 startup
-----------------------------------------------------------
Platform ubuntu
Template
[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network.target

[Service]
Type=forking
User=root
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PM2_HOME=/root/.pm2
PIDFile=/root/.pm2/pm2.pid
Restart=on-failure

ExecStart=/usr/local/lib/node_modules/pm2/bin/pm2 resurrect
ExecReload=/usr/local/lib/node_modules/pm2/bin/pm2 reload all
ExecStop=/usr/local/lib/node_modules/pm2/bin/pm2 kill

[Install]
WantedBy=multi-user.target

Target path
/etc/systemd/system/pm2-root.service
Command list
[ 'systemctl enable pm2-root' ]
[PM2] Writing init configuration in /etc/systemd/system/pm2-root.service
[PM2] Making script booting at startup...
[PM2] [-] Executing: systemctl enable pm2-root...
Created symlink /etc/systemd/system/multi-user.target.wants/pm2-root.service → /etc/systemd/system/pm2-root.service.
[PM2] [v] Command successfully executed.
+---------------------------------------+
[PM2] Freeze a process list on reboot via:
$ pm2 save

[PM2] Remove init script via:


$ pm2 start dist/index.js --name "epgstation"

                          Runtime Edition

        PM2 is a Production Process Manager for Node.js applications
                     with a built-in Load Balancer.

                Start and Daemonize any application:
                $ pm2 start app.js

                Load Balance 4 instances of api.js:
                $ pm2 start api.js -i 4

                Monitor in production:
                $ pm2 monitor

                Make pm2 auto-boot at server restart:
                $ pm2 startup

                To go further checkout:
                http://pm2.io/


                        -------------

[PM2] Spawning PM2 daemon with pm2_home=/HOME/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /HOME/EPGStation/dist/index.js in fork_mode (1 instance)
[PM2] Done.
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name               │ mode     │ ↺    │ status    │ cpu      │ memory   │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0  │ epgstation         │ fork     │ 0    │ online    │ 0%       │ 21.8mb   │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘


$  pm2 save
[PM2] Saving current process list...
[PM2] Successfully saved in /HOME/.pm2/dump.pm2

EPGStationの稼働を http://localhost:8888 を開いて確認する。

PC再起動後、自動実行されなかったが、下記の 「自動起動した EPGStation の再起動(設定変更反映)」を行うと、PC再起動後自動実行された。

自動起動した EPGStation の再起動(設定変更反映)
## 出典 https://qiita.com/ikemura23/items/68fb61b16c6752daa7e8

$ cd ~/EPGStation
$ pm2 stop epgstation
$ pm2 start dist/index.js --name "epgstation" --update-env
$ pm2 startup
    ## 画面出力された指示にしたがって、画面のコマンドをコピーする

## 上記でコピーしたコマンドを実行する
$ sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u tv --hp ${HOME}
$ pm2 save
$ sudo reboot    ## PCを再起動してEPGStationの自動起動を確認


稼働確認
  • pm2コマンドで確認
$ pm2 status

  • mysqlのデータベーステーブルを確認
$ mysql -u epgstation -p epgstation
> show tables;
> select * from channel;
> select * from program;
> exit


ステータス表示
$ pm2 show epgstation


自動起動した EPGStation の終了
$ pm2 stop epgstation


手動起動
$ npm start


手動終了
$ npm stop


ログ保管場所

${HOME}/EPGStation/logs/
${HOME}/.pm2/logs/epgstation-out.log
${HOME}/.pm2/logs/epgstation-error.log

ログファイルについて
GitHub - l3tnun/EPGStation: Mirakurun を使用した録画管理ソフト

EPGStationのアンインストール

出典 EPGStationのインストール - にゃののん日記

$ pm2 delete epgstation    ## PM2に登録されているEPGStationを削除
$ pm2 save    ## PM2の現在の状態を保存
$ pm2 kill    ## PM2を停止
$ sudo systemctl stop pm2-xxxxxxxx    ## 現在のユーザ(xxxxxxxxをユーザ名に置き換える)でのPM2の自動起動を停止
$ sudo systemctl disable pm2-xxxxxxxx  ## 現在のユーザでのPM2の無効化
$ sudo rm -f /etc/systemd/system/pm2-xxxxxxxx.service    ## 設定を削除
$ rm -rf ~/.pm2     ## PM2の設定保存ディレクトリを削除


mysqlのテーブル構造

> show tables;
+----------------------------+
| Tables_in_epgstation       |
+----------------------------+
| channel                    |
| drop_log_file              |
| migrations                 |
| program                    |
| recorded                   |
| recorded_history           |
| recorded_tag               |
| recorded_tags_recorded_tag |
| reserve                    |
| rule                       |
| thumbnail                  |
| video_file                 |
+----------------------------+

> show columns from program;
+----------------------+--------------+------+-----+---------+-------+
| Field                | Type         | Null | Key | Default | Extra |
+----------------------+--------------+------+-----+---------+-------+
| id                   | bigint(20)   | NO   | PRI | NULL    |       |
| updateTime           | bigint(20)   | NO   |     | NULL    |       |
| channelId            | bigint(20)   | NO   |     | NULL    |       |
| eventId              | bigint(20)   | NO   |     | NULL    |       |
| serviceId            | int(11)      | NO   |     | NULL    |       |
| networkId            | int(11)      | NO   |     | NULL    |       |
| startAt              | bigint(20)   | NO   |     | NULL    |       |
| endAt                | bigint(20)   | NO   |     | NULL    |       |
| startHour            | int(11)      | NO   |     | NULL    |       |
| week                 | int(11)      | NO   |     | NULL    |       |
| duration             | int(11)      | NO   |     | NULL    |       |
| isFree               | tinyint(4)   | NO   |     | NULL    |       |
| name                 | text         | NO   |     | NULL    |       |
| halfWidthName        | text         | NO   |     | NULL    |       |
| shortName            | text         | NO   |     | NULL    |       |
| description          | text         | YES  |     | NULL    |       |
| halfWidthDescription | text         | YES  |     | NULL    |       |
| extended             | text         | YES  |     | NULL    |       |
| halfWidthExtended    | text         | YES  |     | NULL    |       |
| genre1               | int(11)      | YES  |     | NULL    |       |
| subGenre1            | int(11)      | YES  |     | NULL    |       |
| genre2               | int(11)      | YES  |     | NULL    |       |
| subGenre2            | int(11)      | YES  |     | NULL    |       |
| genre3               | int(11)      | YES  |     | NULL    |       |
| subGenre3            | int(11)      | YES  |     | NULL    |       |
| channelType          | varchar(255) | NO   |     | NULL    |       |
| channel              | varchar(255) | NO   |     | NULL    |       |
| videoType            | text         | YES  |     | NULL    |       |
| videoResolution      | text         | YES  |     | NULL    |       |
| videoStreamContent   | int(11)      | YES  |     | NULL    |       |
| videoComponentType   | int(11)      | YES  |     | NULL    |       |
| audioSamplingRate    | int(11)      | YES  |     | NULL    |       |
| audioComponentType   | int(11)      | YES  |     | NULL    |       |
+----------------------+--------------+------+-----+---------+-------+

> show columns from recorded;
+----------------------+------------+------+-----+---------+----------------+
| Field                | Type       | Null | Key | Default | Extra          |
+----------------------+------------+------+-----+---------+----------------+
| id                   | int(11)    | NO   | PRI | NULL    | auto_increment |
| reserveId            | int(11)    | YES  |     | NULL    |                |
| ruleId               | int(11)    | YES  |     | NULL    |                |
| programId            | bigint(20) | YES  |     | NULL    |                |
| channelId            | bigint(20) | NO   |     | NULL    |                |
| isProtected          | tinyint(4) | NO   |     | 0       |                |
| startAt              | bigint(20) | NO   |     | NULL    |                |
| endAt                | bigint(20) | NO   |     | NULL    |                |
| duration             | int(11)    | NO   |     | NULL    |                |
| name                 | text       | NO   |     | NULL    |                |
| halfWidthName        | text       | NO   |     | NULL    |                |
| description          | text       | YES  |     | NULL    |                |
| halfWidthDescription | text       | YES  |     | NULL    |                |
| extended             | text       | YES  |     | NULL    |                |
| halfWidthExtended    | text       | YES  |     | NULL    |                |
| genre1               | int(11)    | YES  |     | NULL    |                |
| subGenre1            | int(11)    | YES  |     | NULL    |                |
| genre2               | int(11)    | YES  |     | NULL    |                |
| subGenre2            | int(11)    | YES  |     | NULL    |                |
| genre3               | int(11)    | YES  |     | NULL    |                |
| subGenre3            | int(11)    | YES  |     | NULL    |                |
| videoType            | text       | YES  |     | NULL    |                |
| videoResolution      | text       | YES  |     | NULL    |                |
| videoStreamContent   | int(11)    | YES  |     | NULL    |                |
| videoComponentType   | int(11)    | YES  |     | NULL    |                |
| audioSamplingRate    | int(11)    | YES  |     | NULL    |                |
| audioComponentType   | int(11)    | YES  |     | NULL    |                |
| isRecording          | tinyint(4) | NO   |     | NULL    |                |
| dropLogFileId        | int(11)    | YES  | UNI | NULL    |                |
+----------------------+------------+------+-----+---------+----------------+

id:video_fileテーブルのrecordedIdと同じ値
startAt, endAt:unixタイムを1,000倍したミリ秒単位の数値。

> show columns from reserve;
+-----------------------------+------------+------+-----+---------+----------------+
| Field                       | Type       | Null | Key | Default | Extra          |
+-----------------------------+------------+------+-----+---------+----------------+
| id                          | int(11)    | NO   | PRI | NULL    | auto_increment |
| updateTime                  | bigint(20) | NO   |     | NULL    |                |
| ruleId                      | int(11)    | YES  |     | NULL    |                |
| ruleUpdateCnt               | int(11)    | YES  |     | NULL    |                |
| isSkip                      | tinyint(4) | NO   |     | 0       |                |
| isConflict                  | tinyint(4) | NO   |     | 0       |                |
| allowEndLack                | tinyint(4) | NO   |     | 0       |                |
| tags                        | text       | YES  |     | NULL    |                |
| isOverlap                   | tinyint(4) | NO   |     | 0       |                |
| isIgnoreOverlap             | tinyint(4) | NO   |     | 0       |                |
| isTimeSpecified             | tinyint(4) | NO   |     | 0       |                |
| parentDirectoryName         | text       | YES  |     | NULL    |                |
| directory                   | text       | YES  |     | NULL    |                |
| recordedFormat              | text       | YES  |     | NULL    |                |
| encodeMode1                 | text       | YES  |     | NULL    |                |
| encodeParentDirectoryName1  | text       | YES  |     | NULL    |                |
| encodeDirectory1            | text       | YES  |     | NULL    |                |
| encodeMode2                 | text       | YES  |     | NULL    |                |
| encodeParentDirectoryName2  | text       | YES  |     | NULL    |                |
| encodeDirectory2            | text       | YES  |     | NULL    |                |
| encodeMode3                 | text       | YES  |     | NULL    |                |
| encodeParentDirectoryName3  | text       | YES  |     | NULL    |                |
| encodeDirectory3            | text       | YES  |     | NULL    |                |
| isDeleteOriginalAfterEncode | tinyint(4) | NO   |     | 0       |                |
| programId                   | bigint(20) | YES  |     | NULL    |                |
| programUpdateTime           | bigint(20) | YES  |     | NULL    |                |
| channelId                   | bigint(20) | NO   |     | NULL    |                |
| channel                     | text       | NO   |     | NULL    |                |
| channelType                 | text       | NO   |     | NULL    |                |
| startAt                     | bigint(20) | NO   |     | NULL    |                |
| endAt                       | bigint(20) | NO   |     | NULL    |                |
| name                        | text       | YES  |     | NULL    |                |
| halfWidthName               | text       | YES  |     | NULL    |                |
| shortName                   | text       | YES  |     | NULL    |                |
| description                 | text       | YES  |     | NULL    |                |
| halfWidthDescription        | text       | YES  |     | NULL    |                |
| extended                    | text       | YES  |     | NULL    |                |
| halfWidthExtended           | text       | YES  |     | NULL    |                |
| genre1                      | int(11)    | YES  |     | NULL    |                |
| subGenre1                   | int(11)    | YES  |     | NULL    |                |
| genre2                      | int(11)    | YES  |     | NULL    |                |
| subGenre2                   | int(11)    | YES  |     | NULL    |                |
| genre3                      | int(11)    | YES  |     | NULL    |                |
| subGenre3                   | int(11)    | YES  |     | NULL    |                |
| videoType                   | text       | YES  |     | NULL    |                |
| videoResolution             | text       | YES  |     | NULL    |                |
| videoStreamContent          | int(11)    | YES  |     | NULL    |                |
| videoComponentType          | int(11)    | YES  |     | NULL    |                |
| audioSamplingRate           | int(11)    | YES  |     | NULL    |                |
| audioComponentType          | int(11)    | YES  |     | NULL    |                |
+-----------------------------+------------+------+-----+---------+----------------+

> show columns from video_file;
+---------------------+------------+------+-----+---------+----------------+
| Field               | Type       | Null | Key | Default | Extra          |
+---------------------+------------+------+-----+---------+----------------+
| id                  | int(11)    | NO   | PRI | NULL    | auto_increment |
| parentDirectoryName | text       | NO   |     | NULL    |                |
| filePath            | text       | NO   |     | NULL    |                |
| type                | text       | NO   |     | NULL    |                |
| name                | text       | NO   |     | NULL    |                |
| size                | bigint(20) | NO   |     | 0       |                |
| recordedId          | int(11)    | NO   | MUL | NULL    |                |
+---------------------+------------+------+-----+---------+----------------+

recordedId:recordedテーブルのidと同じ値

録画ファイル情報取得例

(例1)mysqlのデータから抽出

mysql > select video_file.id, video_file.parentDirectoryName, video_file.filePath, video_file.type, video_file.name, video_file.size, video_file.recordedId, recorded.startAt, recorded.endAt, recorded.name, recorded.description, recorded.extended from video_file LEFT OUTER JOIN recorded ON video_file.recordedId = recorded.id ;


(例2) config.ymlからの録画ファイル保存ディレクトリ取得 & mysqlデータ抽出

# visudo
epgstationUser ALL=(root) NOPASSWD: /usr/bin/mysql

$ su - epgstationUser
$ ConfigFile="${HOME}/EPGStation/config/config.yml"
$ ParentDir=$(cat "$ConfigFile" | grep -P '^[ \t]*path')
$ ParentDir=${ParentDir#*\'}
$ ParentDir=${ParentDir%\'*}
$ ParentDir=${ParentDir%/}
$ DestDir="DIR/TO/SAVE/RECORDED-FILE-LIST"
$ DestFileName="FILE-NAME-OF-RECORDED-FILE-LIST"
$ DbName=DATABE-NAME-OF-EPGSTATION-IN-MYSQL
$ sed "s:${ParentDir}\t*:${ParentDir}/:" > "${DestDir}/${DestFileName}" <(echo "select video_file.id, '${ParentDir}' as parentDirPath, video_file.filePath, video_file.type, video_file.name, video_file.size, video_file.recordedId, recorded.startAt, recorded.endAt, recorded.name, recorded.description, recorded.extended from video_file LEFT OUTER JOIN recorded ON video_file.recordedId = recorded.id" | sudo /usr/bin/mysql -D ${DbName})


録画ファイル保存ディレクト

録画ファイル保存ディレクトリは、mysqlデータベースには"recorded"と記録されており、パスを取得できない。
録画ファイル保存ディレクトリパスは ~/EPGStation/config/config.yml内のrecorded: path: 'PARENT/DIR'を参照する。

録画ファイル保存ディレクトリの変更について

  • ~/EPGStation/config/config.yml内のrecorded: path: 'PARENT/DIR'を変更すると録画ファイル保存ディレクトリが変更される。

録画ファイル変換(トランスコード)設定

設定記述ファイル:${USER}/EPGStation/config/config.yml
設定ブロック:encode:
設定記述:下記のように"- name:"で始め、変換コマンドjsファイル・拡張子・録画後タイムアウト時間(秒)を指定する。

2つの設定を記述した例

encode:
    - name: H.264
      cmd: '%NODE% %ROOT%/config/enc.js'
      suffix: .mp4
      rate: 4.0

    - name: H.264-cut4secs
      cmd: '%NODE% %ROOT%/config/enc-cut4secs.js'
      suffix: .mp4
      rate: 4.0

mpeg4変換スクリプト

デフォルト '%NODE% %ROOT%/config/enc.js'

const spawn = require('child_process').spawn;
const ffmpeg = process.env.FFMPEG;

const input = process.env.INPUT;
const output = process.env.OUTPUT;
const analyzedurationSize = '10M'; // Mirakurun の設定に応じて変更すること
const probesizeSize = '32M'; // Mirakurun の設定に応じて変更すること
const maxMuxingQueueSize = 1024;
const dualMonoMode = 'main';
const videoHeight = parseInt(process.env.VIDEORESOLUTION, 10);
const isDualMono = parseInt(process.env.AUDIOCOMPONENTTYPE, 10) == 2;
const audioBitrate = videoHeight > 720 ? '192k' : '128k';
const preset = 'veryfast';
const codec = 'libx264';
const crf = 23;

const args = ['-y', '-analyzeduration', analyzedurationSize, '-probesize', probesizeSize];

// dual mono 設定
if (isDualMono) {
    Array.prototype.push.apply(args, ['-dual_mono_mode', dualMonoMode]);
}

// input 設定
Array.prototype.push.apply(args,['-i', input]);

// メタ情報を先頭に置く
Array.prototype.push.apply(args,['-movflags', 'faststart']);

// 字幕データを含めたストリームをすべてマップ
// Array.prototype.push.apply(args, ['-map', '0', '-ignore_unknown', '-max_muxing_queue_size', maxMuxingQueueSize, '-sn']);

// video filter 設定
let videoFilter = 'yadif';
if (videoHeight > 720) {
    videoFilter += ',scale=-2:720'
}
Array.prototype.push.apply(args, ['-vf', videoFilter]);

// その他設定
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
]);

let str = '';
for (let i of args) {
    str += ` ${ i }`
}
console.error(str);

const child = spawn(ffmpeg, args);

child.stderr.on('data', (data) => { console.error(String(data)); });

child.on('error', (err) => {
    console.error(err);
    throw new Error(err);
});

process.on('SIGINT', () => {
    child.kill('SIGINT');
});


先頭4秒間カット・音声二重対応 '%NODE% %ROOT%/config/enc-cut4secs.js'

const spawn = require('child_process').spawn;
const ffmpeg = process.env.FFMPEG;

const input = process.env.INPUT;
const output = process.env.OUTPUT;
const analyzedurationSize = '10M'; // Mirakurun の設定に応じて変更すること
const probesizeSize = '32M'; // Mirakurun の設定に応じて変更すること
const maxMuxingQueueSize = 1024;
const dualMonoMode = 'main';
const videoHeight = parseInt(process.env.VIDEORESOLUTION, 10);
const isDualMono = parseInt(process.env.AUDIOCOMPONENTTYPE, 10) == 2;
const audioBitrate = videoHeight > 720 ? '192k' : '128k';
const preset = 'veryfast';
const codec = 'libx264';
const crf = 23;

const args = ['-ss', '4', '-y', '-analyzeduration', analyzedurationSize, '-probesize', probesizeSize];

// dual mono 設定
if (isDualMono) {
    Array.prototype.push.apply(args, ['-dual_mono_mode', dualMonoMode]);
}

// input 設定
Array.prototype.push.apply(args,['-i', input]);

// メタ情報を先頭に置く
Array.prototype.push.apply(args,['-movflags', 'faststart']);

// 字幕データを含めたストリームをすべてマップ
// Array.prototype.push.apply(args, ['-map', '0', '-ignore_unknown', '-max_muxing_queue_size', maxMuxingQueueSize, '-sn']);

// video filter 設定
let videoFilter = 'yadif';
if (videoHeight > 720) {
    videoFilter += ',scale=-2:720'
}
Array.prototype.push.apply(args, ['-vf', videoFilter]);

// その他設定
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
]);

let str = '';
for (let i of args) {
    str += ` ${ i }`
}
console.error(str);

const child = spawn(ffmpeg, args);

child.stderr.on('data', (data) => { console.error(String(data)); });

child.on('error', (err) => {
    console.error(err);
    throw new Error(err);
});

process.on('SIGINT', () => {
    child.kill('SIGINT');
});