テレビ録画メディアサーバー構築入門(第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_gb
chmod +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

これで、初回に考えていた「テレビ録画メディアサーバー」の全機能を実現することができました。書き残しておきたかったことは、ひとまず書き終えました。

ただ、まだ、必要不可欠ではないけれども、いろいろ気になるところがあります。

いいなと思ったら応援しよう!

ピックアップされています

全自動TV録画 視聴環境構築

  • 26本

コメント

コメントするには、 ログイン または 会員登録 をお願いします。
予約録画、カット編集、番組整理を全自動化し、複数デバイスで手軽に視聴可能な、自分だけのメディアサーバーを、ゼロから作り上げる過程の全記録。誰でもたどれるよう必要なすべてを書き残す。https://github.com/takyaO/epg2jelly/
テレビ録画メディアサーバー構築入門(第8回)|takya
word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word

mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1