テレビ録画メディアサーバー構築入門(第8回)
空き時間に動画処理
録画動画の編集トランスコード処理は、CPU負荷がかかることから、録画中とは重ならない時間帯に実行しはじめ、そして完了するようにしたい。
重要なのは、録画中には動画処理をしないこと。
録画データの欠落(ドロップ)、チューナーの不安定化の原因となるためです。このことの重要性は、かなり強く強調しておきたいと思います。とりわけ本入門講座のように、非力なドングルチューナーを利用する上では、最重要事項といっても過言ではありません。
録画するなら動画処理するな。動画処理するなら録画するな。
同じ理由で、ライブ視聴はしない。
つまり、EPGStation(Webインターフェイス)は、録画の予約(と予約の確認)以外には使用しない。
とにかく、チューナーに余計な負荷をかけない。
さもなければ、1台数万円の高価なチューナーを買いなさい!といわれても、一般的とは言い難いし、怪しい?脱法?チューナーに金をかけるくらいなら、ネット配信に課金するなり、市販のテレビ録画機を買うなりする方が楽だしコストパフォーマンスがよいのでは? 完全無保証のTS抜きチューナーに数万円も出せません!!(個人の感想です)。
というわけで、本稿では、動画処理のタイミングに知恵を使う、前代未聞の道を選択します。
第6回では、早朝の5時に自動で実行させるようにしましたが、特定の時間帯ではなく、予約録画の空き時間に処理完了できれば、もっとも都合がよい。
そのためには、1.処理にかかる時間(目安)と、2.次の録画までの時間を知る必要がある。
処理にかかる時間は、処理する動画のサイズで決まる。処理する動画のリストは、前回の toprocess.py で求まるので、これを用いて、処理動画のサイズ(GB)は求まります。
gbsize_toprocess.sh
SOURCEDIR と TOPROCESS は適宜修正してください。
cd ~/work
nano gbsize_toprocess.sh#!/bin/bash
SOURCEDIR="$HOME/docker-mirakurun-epgstation/recorded/"
TOPROCESS="$HOME/work/toprocess.py"
total_bytes=0
while IFS= read -r FILE; do
# ソースディレクトリに移動
cd "$SOURCEDIR" || {
echo "Failed to change directory to $SOURCEDIR"
exit 1
}
# .m2ts ファイルをループ処理
if [ -f "$FILE" ]; then
size=$(stat -c%s "$FILE")
total_bytes=$((total_bytes + size))
fi
done < <($TOPROCESS)
total_gb=$(awk "BEGIN {printf \"%.2f\", $total_bytes / (1024*1024*1024)}")
#echo "Total size: $total_gb GB"
echo $total_gbchmod +x gbsize_toprocess.sh
./gbsize_toprocess.sh出力は、GB(ギガバイト)単位のファイルサイズです。
動画処理にかかる時間
1時間のテレビ番組を録画すると、m2tsファイルのサイズは、およそ7GBになります。
逆にいうと、約7GBのm2ts を1倍速で処理するには、1時間かかる。
すこし余裕をもたせて、6GBで1時間、と考えることにします。
処理速度が N倍速なら、6GBで1/N 時間となります。
処理速度は、PCの性能によりますので、変数speed で変えられるようにします。
次の録画までの時間
次の予約録画までの時間は、EPGStationの WebAPIから取得できます。
次の録画情報は、
http://localhost:8888/api/reserves?type=normal&limit=1&isHalfWidth=false
この中のstartAtが開始時刻(UNIX時間)です。現在時刻との差をとれば、あと何分かが求まる。
得られた時間が、動画処理にかかる時間より長い場合だけ、動画処理を実行するようにする(そうでない場合はなにもせずに終了する)。
encode.sh
以上の空き時間判定を自動化するスクリプト。SCRIPTとtotalsizeの作業ディレクトリの絶対パスは適宜変更のこと。
こちらも作業ディレクトリ ~/workに作成します。nano encode.sh
#!/bin/bash
SCRIPT="$HOME/work/enc01.sh" #実行スクリプト
totalsize=$($HOME/work/gbsize_toprocess.sh) #処理すべきファイルサイズ[Gb]
LOCKFILE="/tmp/encode.lock"
# ロックファイルが既存の場合は終了
if [ -f "$LOCKFILE" ]; then
echo "Script is already running. Exiting."
exit 1
fi
touch $LOCKFILE
# 現在Unix時刻
timenow=$(date +'%s')
# 1時間の動画サイズを 6GB とする
# totalsize GB は totalsize*60/6 分
# 処理速度が speed倍速なら totalsize*60/6/speed 分
speed=2.5
# 必要時間: 有効2桁で計算
mins_toencode=$(echo "scale=2; $totalsize*60/6/$speed" | bc)
epgstation_url=http://localhost:8888/
# 録画中件数
count=$(echo $(curl -s $epgstation_url"api/recording?isHalfWidth=false") | rev | cut -c 2-2 | rev )
if [ "$count" = "0" ]; then
#次の予約までの時間
def=$(curl -s $epgstation_url"api/reserves?type=normal&limit=1&isHalfWidth=false" | jq -c '.reserves[] | [.startAt]' | cut -c 2- | rev | cut -c 2- | rev)
# min_toencode 分以上あるならエンコード実行
if (( $(echo "scale=2; ($def/1000-$timenow)/60 > $mins_toencode" | bc -l) )); then
fi
# lockfile を削除
rm -f $LOCKFILE上記のとおり、変数speed=2.5 は、PCの性能に応じて書き換える。第4回参照
jq (JSON処理) を使うので、インストール。
sudo apt install jq
chmod +x encode.shこのスクリプト encode.shは、番組録画中は、なにもせず終了するようにしており、また、実行中に2重に実行しないよう、空のロックファイル
LOCKFILE="/tmp/encode.lock"
を作っています。
なので、時間を気にせず、繰り返し何度でも、実行できます。
重要:なにかのエラーで異常終了してロックファイルが残ると、削除 rm /tmp/encode.lock しない限り、encode.sh を実行しても、何も反応しなくなります。覚えておきましょう。
番組は5分おきの定時(0分、5分、10分、15分、・・・)に開始・終了することが多いので、4分おき(4分、8分、16分、20分、・・・)に実行するように、crontab に設定します。
crontab -e で編集モードに入り、前回の設定をコメントアウトして、2行目を新たに追加します。
#0 5 * * * $HOME/work/enc01.sh
*/4 * * * * $HOME/work/encode.sh >> $HOME/work/encode.log 2>&1今回は、すべての出力をログファイル encode.log に残す設定にしています。
未処理録画ファイルがあるようなら、ちゃんと動作するかリアルタイムに確認できます。
tail -f encode.logこれで、初回に考えていた「テレビ録画メディアサーバー」の全機能を実現することができました。書き残しておきたかったことは、ひとまず書き終えました。
ただ、まだ、必要不可欠ではないけれども、いろいろ気になるところがあります。



コメント