m3u8 ファイルの URL がわかっていれば、テレビアンテナがなくてもインターネットでリアルタイムでテレビを視聴することができます。
しかしリアルタイムで視聴できても、これまでは録画をすることができませんでした。
最近になって録画をする方法がやっとわかりました。
python と cron を使います。
python
m3u8 から ts ファイルをダウンロードするのは、
import urllib.request
import m3u8
def tsdn():
playlist = m3u8.load('https://hoge.com/live_playlist.m3u8')
for i, segment in enumerate(playlist.segments):
# tsファイルのパス
uri = segment.absolute_uri
object_name = '/volume1/bak/python/ts/' + uri[uri.rfind('/') + 1:]
print(object_name)
urllib.request.urlretrieve(uri, object_name)
if __name__ == '__main__':
tsdn()
こうするとファイル名が連番の 10 秒間の ts ファイルが 6 個ダウンロードされます。
このプログラムでは 1 分間の ts ファイルしかダウンロードされません。
そして実行時間は 1 分以上かかるので、このプログラムをループを使って動かすと ts ファイルが連続的にダウンロードされません。
python のマルチプロセスを使うとおそらくできると思いますが、chatGPT の提示したプログラムではエラーが続出しました。
例外処理をしてエラーを吐いたらもう一度プログラムを実行するのは私にとってはとても大変なので、上のような単純な python を cron でコントロールしようと考えました。
cron の設定
12:30 から 14:00 まで 1 分ごとに python を実行する cron は、
30-59/1 12 * * sun python tsdown.py > myjob.log 2>&1
*/1 13 * * sun python tsdown.py > myjob.log 2>&1
こうすると、ts ファイルが 500 以上ダウンロードされます。
ts ファイルを結合する
linux では ts ファイルはそのまま閲覧できます。
でも、10 秒間と短いのでそれらを結合する必要があります。
手順としては ts ファイルのリストを作成し、そのリストにしたがって結合するようです。
cd ./ts
for i in `ls -v *.ts` ; do
echo file "'$i'"
done > list.txt
ffmpeg -f concat -i list.txt -c copy concated_temp.ts
ts ファイルから無劣化で mp4 へ変換
python でもできるようですが、ffmpeg の方が簡単です。
ffmpeg -i input.ts -c:v copy -c:a copy output.mp4
NAS で ts ファイルをダウンロード
synology の NAS を使っていますが、pip がインストールされていない場合は ssh ログインして次のようにします。
python -m ensurepip --upgrade
python -m pip install --upgrade pip
m3u8 を pip でインストール。
pip install m3u8
cron は、
30-59/1 12 * * 0 root python tsdown.py > myjob.log 2>&1
1/* 13 * * 0 root python tsdown.py > myjob.log 2>&1
cron の再起動は、
synosystemctl restart crond
後はこのプロセスを自動化すればいいと思います。
シェルスクリプトでちょっと自動化
#!/bin/sh
rm -r ./temp/*.*
for i in `ls -v ts/*.ts` ; do
echo file "'$i'"
done < list.txt
ffmpeg -f concat -i list.txt -c copy ./temp/igosyogi_`date +%Y%m%d%H%M%S`.ts
for file in ./temp/*.ts; do
echo $file
faname_ext="${file##*/}"
fname="${faname_ext%.*}"
ffmpeg -i $file -c:v copy -c:a copy ./mp4/$fname.mp4
done
作成したシェルスクリプトを cron で動かします。
16 15 * * * sh ~/iptv/moheno/tsmerge.sh
すべてはダウンロードできない
上の方法である程度のことはできますが、時々 ts ファイルのダウンロードがされない場合があります。10秒単位で抜け落ちてしまうのです。
その理由はよくわかりませんが、「server error」が発生するようです。
どれくらい抜け落ちるかというと、714個の ts ファイルがダウンロードされるはずのところ、631個しかないので、83個がダウンロードされなかったことになります。ざっと1割以上ですね。
囲碁などであればこれでも使えると思いますが、ボクシングなどであればいいシーンが抜けてしまうかもしれません。
10 秒ごとにプログラムを実行する
上のような方法ではかなりの部分の動画がダウンロードできず、動画としてはほとんど役に立ちません。
そこでプログラムを分単位ではなくて10秒ごとに実行することにしました。
cron で以下のようにします。
* 12 * * 0 for i in `seq 0 10 59`;do (sleep ${i}; ~/shell.sh) & done;
shell を別に作ります。
#!/bin/sh
python ~/tsdown.py
このようにすると、ほとんどすべてがダウンロードできます。