PythonとRaspberry Piで毎日絶対にらじる★らじるを聴く
背景
皆さんには、毎日続けられなかった経験はありますか?
私は高校時代の一時期、英語のリスニングの勉強のため、らじる★らじるの語学チャンネルを毎日聴いていました。しかし、いちいちアプリを開くのが面倒だったり、つい時間を忘れることが続いた結果、いつの間にか全然聞かなくなってしまいました。
最近また英語の勉強をしたくなったのですが、当時以上に時間がなくて意識的に聞けなくなっています。そこで、「だったら毎日強制的に流してしまえばいいのでは??」と思い、家にある余ったラズパイを使って試してみました。
作ったもの
※音声つきの動画を記事内に載せれなかったため、完成イメージを共有します
あらかじめ狙った番組の放送時刻を記録しておき、毎日その時刻になったらストリーミングのURLにアクセスして音声データを取得、スピーカーで再生します。また、後から聴き直せるようにmp3ファイルに保存します。
ここでは、PCを開いていなくても再生されるように、ラズパイ上でこのプログラムを実行しています。
実装の流れ
今回はPythonをRaspberry Pi上で動かしています。すでにらじる★らじるを再生・録音する記事は世の中に多くあるため、他の方法を試したい方はぜひそちらも参照してください。
環境
- Raspberry Pi 4 Model B 4GB
- Raspberry Pi OS
- Python 3.12.2
音声再生にはスピーカー付きディスプレイを使いましたが、実際には音が出力できれば良いと思います。
作業の流れ
ストリームURLを取得
らじる★らじるは、m3u8形式で配信されています。このファイルにはプレイリストが記載されており、そこから実際の音声データを取得できます。
今回は、東京圏のラジオ第2で放送されている「エンジョイ・シンプル・イングリッシュ」を録音したいので、URLは以下のようになります。(2025/3/13現在)
https://radio-stream.nhk.jp/hls/live/2023501/nhkradiruakr2/master.m3u8
各地域のストリームURLや、その他番組情報の取得方法については、以下の記事で説明されています。
必要ライブラリのインストール
今回はオープンソースのメディアプレイヤーであるVLCを用いて音声データを再生します。今回はMac OSとRaspberry Piしか使用していませんが、Windowsにも対応しているため、必要事項は大きく変わらないと思います。
$ sudo apt update
$ sudo apt install -y vlc
$ pip install python-vlc
再生時間の指定
import datetime
start_time = datetime.time(23, 9)
end_time = datetime.time(23, 16)
公式ページ内の番組表に記載されている時刻を見て、その時刻を再生の開始時刻と終了時刻に設定します。
なおらじる★らじるは、配信時刻になってから30秒ほどは前の番組がずれ込んでいるので、前後1分程度余裕を持って設定しておくと良いと思います。
再生と録音の開始
if start_time <= now < end_time:
# VLCプレイヤーでストリームを再生
player = vlc.MediaPlayer(tokyo_stream_url)
player.play()
time.sleep(2) # バッファリングのため少し待つ
# 録音ファイルの保存パス
recording_filename = f"recording_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.mp3"
# ffmpegで録音開始
ffmpeg_cmd = [
"ffmpeg",
"-i", tokyo_stream_url,
"-c:a", "mp3",
"-b:a", "128k",
"-y", recording_filename
]
process = subprocess.Popen(ffmpeg_cmd)
# 指定時間まで録音を継続
while datetime.datetime.now().time() < end_time:
time.sleep(1)
現在時刻が再生・録音の対象時刻かどうかを判断し、対象時刻の場合はVLCプレイヤーを呼び出して音声を再生し、同時にffmpegで音声を録音しています。音声の再生が途中で途切れにくくするために、time.sleep(2)
を行いバッファリングをしています。最後に、現在時刻が終了時刻に到達するまで待機しています。
終了と翌日までの待機
# VLC再生停止
player.stop()
# ffmpegプロセス停止
if process:
process.terminate()
process.wait()
# 翌日の再生時間まで待機
now = datetime.datetime.now()
tomorrow = now + datetime.timedelta(days=1)
next_run = datetime.datetime.combine(tomorrow.date(), start_time)
wait_seconds = (next_run - now).total_seconds()
time.sleep(wait_seconds) # 翌日まで待機
終了時刻になったら、VLCとffmpegを停止します。その後、この処理を毎日繰り返して行えるように、翌日の開始時刻までの時間を計算し、その時間だけ待機します。
このコードを、While true
などの繰り返し処理を行うことで毎日実行します。
発生したエラー・問題など
音声の遅延
[00000001498d34f0] main input error: ES_OUT_SET_(GROUP_)PCR is called too late (pts_delay increased to 2771 ms)
上記のエラーは音声データ自体には問題ありませんが、再生の遅延が発生しています。
今回はあまり関係ないかと思いますが、気になるようでしたら「VLCのバッファサイズを増やす」「CPUへの負荷を減らす」などを試してみてください。
音が出ない
ラズパイで音を鳴らしていると、繋げている周辺機器によっては音が出なくなる場合があります(HDMI機器とイヤホンジャックをどちらも繋げる場合など)。その場合はラズパイのオーディオ出力の設定を明示的に指定してみてください。
バージョンによっても異なる場合がありますが、以下から設定できます。
sudo raspi-config
まとめ
ラズパイを使ったライフハックって楽しいですよね!他にも物理ボタンを使ってチャンネル変えたり、オンオフができるようにして、本物のラジオみたいにしてみたいと思っています。
ここまで読んでくださり、ありがとうございました🙇
Discussion