テレビ録画メディアサーバー構築入門(第10回)
エラー通知
スマホ等、日常的に使用する端末への通知機能があると、なにかと便利です。ここでは、ノティファイntfy.shを使用します。専用のサーバーが用意されていますが、せっかくなので自己ホストすることにします。
ntfy.sh
まず、サーバーのインストールですが、docker を使用すれば簡単です。
sudo docker run -d -p 8080:80 -e TZ=Asia/Tokyo --restart=always -it binwiederhier/ntfy serve続いて、
sudo tailscale serve --bg 127.0.0.1:8080そして、
sudo tailscale serve statusすると、
https://fearow22.taile153a7.ts.net (tailnet only)
|-- / proxy http://127.0.0.1:8080このように表示されたら、上の (tailnet only)のアドレスに移動すると、ntfyのサーバー画面が表示される。
「+ トピックを購読」から、たとえば、「PX-S1UD」でトピック名を生成する。
端末から、
curl -d "Hi" https://fearow22.taile153a7.ts.net/PX-S1UDを実行すると、通知が届くはず。
次は、クライエントアプリ。問題なく動作することを確認したら、スマホアプリをインストールします。サーバー名とトピック名を入力すると、ブラウザ上と同じように通知が受け取れる状態になります。
diskcheck.sh
動画サーバを運用していて、最も起こりやすく、しかもエラーメッセージをみても、最初は何が原因だかよくわからないものが、ディスク容量を使い尽くしたために、一切の書き込みができなくなるエラーです。マウントされたディスクを監視し、80%以上になったら ntfyで警告を飛ばすスクリプトが以下。
#!/bin/bash
# Monitor disk usage and send alert if >90% used
NTFYURL="https://fearow22.taile153a7.ts.net/PX-S1UD"
df -H | grep -vE '^ファイル|tmpfs|cdrom|snap' | while read -r line; do
usep=$(echo "$line" | awk '{ print $5 }' | tr -d '%')
# Check if usep is a valid number before comparison
if [[ "$usep" =~ ^[0-9]+$ ]]; then
# Skip header line
if [ "$usep" == "Use" ]; then
continue
fi
if [ "$usep" -ge 80 ]; then
curl -d "ALERT: High Disk Usage on $line ($usep%)" $NTFYURL
fi
fi
done追記:SSDは空き容量が少なくなると性能が大幅に低下する
毎時30分に実行するよう、cronに登録しておく。crontab -e
*/4 * * * * $HOME/work/encode.sh >> $HOME/work/encode.log 2>&1
0 * * * * $HOME/work/remove_empty_dirs.sh >> $HOME/work/encode.log 2>&1
0 5 * * * $HOME/work/deleteold.py >> $HOME/work/encode.log 2>&1
30 * * * * $HOME/work/diskcheck.sh >> $HOME/work/encode.log 2>&1
enc01.sh
いつも、というわけではありませんが、たまに mp4が正常に生成されないエラーにも悩まされます。これは、EPGStationが残した m2tsをchapter_exeやffmpeg で処理するときに出るエラーで、元のm2tsに問題があります。
対症療法として、ファイル名から不具合の原因になりそうな文字を取り除き、動画の先頭をすこし削ったmp4を作業フォルダにコピーして、それを処理するようにします。
#!/bin/bash
SOURCEDIR="$HOME/docker-mirakurun-epgstation/recorded/"
WORKDIR="$HOME/work/"
OUTDIR="$HOME/media/"
NHK1="GR20"
NHK2="GR13"
NTFY_URL="https://fearow22.taile153a7.ts.net/PX-S1UD"
encoded=false
$WORKDIR/toprocess.py | while IFS= read -r FILE;
do
cd $SOURCEDIR
if [ -f "$FILE" ]; then
FILENAME=${FILE%.*}
GRSTRING=`echo $FILENAME | sed -n 's/.*\(GR[0-9][0-9]\).*/\1/p'`
cleaned_filename=$(echo -n "${FILENAME}" | sed 's/[ \/\&\*\$]/_/g')
ffmpeg -ss 0.04 -i "$FILE" -c copy $WORKDIR/"$cleaned_filename".m2ts #先頭をカットしてcopy
cd $WORKDIR
if [ -z $GRSTRING ] || [ $GRSTRING = $NHK1 ] || [ $GRSTRING = $NHK2 ]; then
# NHKならば
# ./enc0.sh $SOURCEDIR/"$FILE" ${FILENAME}.mp4
./enc0.sh "$cleaned_filename".m2ts "$cleaned_filename".mp4
else
# NHK以外
# ./enc1.sh $SOURCEDIR/"$FILE" ${FILENAME}.mp4
./enc1.sh "$cleaned_filename".m2ts "$cleaned_filename".mp4
fi
if [ -s "$cleaned_filename".mp4 ] ; then
# ./mvjf.sh ${FILENAME}.mp4 $OUTDIR
./mvjf.sh "$cleaned_filename".mp4 $OUTDIR
curl -H "X-Priority: 3" -d "mp4 created: $FILE" $NTFY_URL
rm "$cleaned_filename".m2ts
else
echo ERROR: mp4 not created
curl -H "X-Priority: 4" -d "ERROR: mp4 not created: $FILE" $NTFY_URL
fi
./processed.py "$FILE"
encoded=true
fi
done
$encoded && $WORKDIR/update_thumbs.shenc01_emergency.sh
mp4生成に失敗した場合は、まず、処理済み動画リスト processed_filenames.json から該当のファイル名を削除します。そして、(cronのencode.shが実行される前に) 手動で、次のスクリプト enc01_emergency.sh を実行します。緊急措置ということで、放送局の区別なく、enc0.sh を使用しています。
#!/bin/bash
SOURCEDIR="$HOME/docker-mirakurun-epgstation/recorded/"
WORKDIR="$HOME/work/"
OUTDIR="$HOME/media/"
NTFY_URL="https://fearow22.taile153a7.ts.net/PX-S1UD"
while IFS= read -r FILE;
do
cd $SOURCEDIR
if [ -f "$FILE" ]; then
FILENAME=${FILE%.*}
cleaned_filename=$(echo -n "${FILENAME}" | sed 's/[ \/\&\*\$\#]/_/g')
ffmpeg -ss 0.04 -i "$FILE" -c copy $WORKDIR/"$cleaned_filename".m2ts #先頭をカットしてcopy
cd $WORKDIR
./enc0.sh "$cleaned_filename".m2ts "$cleaned_filename".mp4
if [ -s "$cleaned_filename".mp4 ] ; then
./mvjf.sh "$cleaned_filename".mp4 $OUTDIR
curl -H "X-Priority: 3" -d "mp4 created: $FILENAME" $NTFY_URL
rm "$cleaned_filename".m2ts
else
echo ERROR: mp4 not created
curl -H "X-Priority: 4" -d "ERROR: mp4 not created: $FILE" $NTFY_URL
fi
./processed.py "$FILE"
fi
done < <($WORKDIR/toprocess.py)これでもエラーになる例があったら?
わたしの環境では、これまで紹介してきた方法で、安定的に稼働するテレビ録画メディアサーバー環境が、期待通り、問題なく動作するようになりました。
この先、まだ取り組んでもよさそうな、細かな作業は、なくはないのですが、必ずしも必須なものではありません。個人的修正で、個別の環境に依存するような事柄(第7回のmvjf.shのような)は、書き残す価値があるかどうか。
ただ、また、予想外の不具合に遭遇するかもしれません。
気が向いたら、また続きを書き残すかもしれません。



コメント