2021 Oct. 24.
2021 May 30.
2021 Apr. 07.
出典 EPGStation/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
node、Mirakurunのインストール
テレビ放送受信サーバーMirakurunを「Ubuntu/Arch系Manjaro Linux・PT2チューナー・DVBブロックデバイス」構成でインストール - rokkonet
pythonのインストール
pyenvをEPGStationを稼働させるユーザー(tvとした)でインストールする
出典 ubuntu 20.04 / 18.04 に pyenv をインストールする話 - 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向け設定
出典 GitHub - y-hashida/Memo_Mirakurun-and-EPGStation: Mirakurun と EPGStatoin のインストールメモ
・データベースとユーザーを作成し、大量発生するバイナリログの保管期間を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/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/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.pm2EPGStationの稼働を 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
- ブラウザで http://localhost:8888 を開いて確認
- mysqlのデータベーステーブルを確認
$ mysql -uepgstation -pepgstation > use epgstation; > show tables; > select * from channel; > select * from program; > exit
ステータス表示
$ pm2 show epgstation
手動起動
$ npm start
手動終了
$ npm stop
ログ保管場所
${HOME}/EPGStation/logs/
${HOME}/.pm2/logs/epgstation-out.log
${HOME}/.pm2/logs/epgstation-error.log
ログファイルについて
GitHub - l3tnun/EPGStation: Mirakurun を使用した録画管理ソフト
config.yml詳細マニュアル
EPGStation/conf-manual.md at master · l3tnun/EPGStation · GitHub
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'を参照する。