2024-07-13

音が良いと評判のアナログDACとスピーカーを使用してお店にラジオを流します。ストリーミングになるので、無線だと途切れ途切れになるため有線LANを使ったほうがいいです。
1、機材の準備と接続
用意したものは以下です。
・Raspberry Pi (3 or 4) + Raspberry Pi OS (Debian Buster)と有線LANケーブル環境
・RCAオーディオケーブル いわゆる黄・白・赤のアナログケーブルです。黄は使用しません。
・I2S DAC RBD-02+ GPIOに装着して使うアナログDACボード(http://linuxcom.shop-pro.jp/?pid=79120318)
・FOSTEX PM0.1(B) アナログスピーカー(https://www.amazon.co.jp/dp/B00I0MYSOY/ref=pe_492632_159100282_TE_item)
以下のように装着しました。



2、DACボードを認識させて再生テストをする
I2S DAC RBD-02+はRaspberry Pi OSではhifiberry-dacという名前で認識されます。デフォルトではロードされていないので、以下のようにして探します。
cd /boot
cat overlays/README | grep dac
Name: akkordion-iqdacplus
Load: dtoverlay=akkordion-iqdacplus,<param>=<val>
dtoverlay=akkordion-iqdacplus,24db_digital_gain
Name: allo-boss-dac-pcm512x-audio
Load: dtoverlay=allo-boss-dac-pcm512x-audio,<param>
"dtoverlay=allo-boss-dac-pcm512x-audio,
with "dtoverlay=allo-boss-dac-pcm512x-audio,
Name: allo-katana-dac-audio
Load: dtoverlay=allo-katana-dac-audio
Name: allo-piano-dac-pcm512x-audio
Load: dtoverlay=allo-piano-dac-pcm512x-audio,<param>
Name: allo-piano-dac-plus-pcm512x-audio
Load: dtoverlay=allo-piano-dac-plus-pcm512x-audio,<param>
Name: applepi-dac
Load: dtoverlay=applepi-dac
"dtoverlay=hifiberry-dacplus,24db_digital_gain"
Name: hifiberry-dac
Load: dtoverlay=hifiberry-dac
</val>
dtoverlay=hifiberry-dacが見つかったので、これをconfig.txtに追記します。
cd /boot cp -p config.txt config.txt.default vi config.txt dtoverlay=hifiberry-dac
rebootします。
reboot
認識されているかどうかaplayで確認します。
aplay -l **** List of PLAYBACK Hardware Devices **** card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones] Subdevices: 8/8 Subdevice #0: subdevice #0 Subdevice #1: subdevice #1 Subdevice #2: subdevice #2 Subdevice #3: subdevice #3 Subdevice #4: subdevice #4 Subdevice #5: subdevice #5 Subdevice #6: subdevice #6 Subdevice #7: subdevice #7 card 1: sndrpihifiberry [snd_rpi_hifiberry_dac], device 0: HifiBerry DAC HiFi pcm5102a-hifi-0 [HifiBerry DAC HiFi pcm5102a-hifi-0] Subdevices: 1/1 Subdevice #0: subdevice #0
カード番号1、デバイス番号0で無事認識されました。もう音を出せるので、以下フリー音源を扱っていただいてるサイトで
http://www.ne.jp/asahi/music/myuu/wave/wave.htm
loop1.wavをダウンロードして、以下コマンドで再生テストをします。
aplay --device=hw:1,0 loop1.wav
無事音が鳴れば大丈夫です。hw:1,0はカード番号1、デバイス番号0の装置から出力するよう指定しています。
3、play-radikoをセットアップする
ラジオの視聴にはRadikoを使用します。LinuxでRadikoを再生するためのスクリプトが以下作者様のGitHubで公開されているので、これを使わせていただきます。
https://github.com/takuya/play-radiko
・必要パッケージのインストール
apt install git rtmpdump ffmpeg swftools mplayer
・play-radikoのクローン
gitディレクトリを作成してそこにクローンする
cd mkdir git cd git git clone https://github.com/takuya/play-radiko
・出力先をDACボードに変更するためのソースコード修正
mplayerに渡す引数の箇所を変更します。
cd play-radiko
vi RadikoHLS.py
player_cmd = f"{self.mplayer} -ao alsa:device=hw=1.0 -cache 128 {options} '{input}'"
# player_cmd = f"{self.mplayer} -cache 128 {options} '{input}'"
などと、デフォルトmplayer再生コマンドをコメントアウトし、-ao alsa:device=hw=1.0を加えて修正します。
・再生時間を無制限にするためのソースコード修正
play_radiko.pyは-d (--duration)オプションを受け取って再生秒数を指定できますが、指定しなかった場合デフォルト1800秒が採用され30分後に自動で強制停止されプロセスが落ちます。
-dに大きい秒数は指定できますが無制限はありません。無制限にしたい場合は同じくソースコードRadikoHLS.pyを以下のように修正します。
cd play-radiko
vi RadikoHLS.py
terminate()としている行をさがして周辺をコメントアウトする。
# if duration:
# time.sleep(duration + buffer_time)
# p1.terminate()
# else:
# p1.communicate()
p1.communicate()
これで-d (--duration)の指定は効かなくなる=時間無制限での再生になります。
4、ラジオ再生
NHK-FMを再生してみます。
python3 /home/pi/git/play-radiko/play_radiko.py JOAK-FM
only -live INFO:root:area: JP13,東京都,tokyo Japan INFO:root:-------------------------- INFO:root:areaid :JP13 INFO:root:-------------------------- INFO:root:list of channels INFO:root:['TBS', 'QRR', 'LFR', 'RN1', 'RN2', 'INT', 'FMT', 'FMJ', 'JORF', 'BAYFM78', 'NACK5', 'YFM', 'HOUSOU-DAIGAKU', 'JOAK', 'JOAK-FM'] INFO:root:/usr/bin/mplayer -ao alsa:device=hw=1.0 -cache 128 'http://f-radiko.smartstream.ne.jp/JOAK-FM/_definst_/simul-stream.stream/chunklist_w1236588970.m3u8' MPlayer 1.3.0 (Debian), built with gcc-8 (C) 2000-2016 MPlayer Team do_connect: could not connect to socket connect: No such file or directory Failed to open LIRC support. You will not be able to use your remote control. Playing http://f-radiko.smartstream.ne.jp/JOAK-FM/_definst_/simul-stream.stream/chunklist_w1236588970.m3u8. Resolving f-radiko.smartstream.ne.jp for AF_INET6... Couldn't resolve name for AF_INET6: f-radiko.smartstream.ne.jp Resolving f-radiko.smartstream.ne.jp for AF_INET... Connecting to server f-radiko.smartstream.ne.jp[203.211.199.181]: 80... Cache size set to 128 KBytes Cache fill: 3.84% (5030 bytes) libavformat version 58.20.100 (external) libavformat file format detected. Invalid return value 0 for stream protocol Invalid return value 0 for stream protocol [hls,applehttp @ 0x7678d308]Opening 'http://f-radiko.smartstream.ne.jp/JOAK-FM/_definst_/simul-stream.stream/media-ui1bjrg4a_w1236588970_1024669.aac' for reading [hls,applehttp @ 0x7678d308]Opening 'http://f-radiko.smartstream.ne.jp/JOAK-FM/_definst_/simul-stream.stream/media-ui1bjrg4a_w1236588970_1024670.aac' for reading [lavf] stream 0: audio (aac), -aid 0 LAVF: Program 0 ========================================================================== Opening audio decoder: [ffmpeg] FFmpeg/libavcodec audio decoders libavcodec version 58.35.100 (external) AUDIO: 48000 Hz, 2 ch, floatle, 46.3 kbit/1.51% (ratio: 5789->384000) Selected audio codec: [ffaac] afm: ffmpeg (FFmpeg AAC (MPEG-2/MPEG-4 Audio)) ========================================================================== [AO_ALSA] Format floatle is not supported by hardware, trying default. AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample) Video: no video Starting playback... A:64827.6 (18:00:27.6) of 0.9 (00.8) 4.7% 0%
無事NHKが流れました!なお、Radikoのエリアは接続元IPアドレスから強制決定されるので、手動でエリアを指定することは基本できないようです。
試しに、RadikoHLS.pyの該当箇所を兵庫県にしてみてABCラジオを聴こうとしても、
vi RadikoHLS.py
txt = res.read()
# area = txt.decode('utf-8')
area = "JP28,兵庫県,hyogo Japan"
logging.info(f"area: {area}")
return area
python3 /home/pi/git/play-radiko/play_radiko.py ABC
only -live
INFO:root:authtoken: XhoJUMCp81WbwvBmXmXWjw
INFO:root:offset: 9
INFO:root:length: 16
INFO:root:partialkey: b'YzAzYjM1MmUxZWYyZmQ2Ng=='
INFO:root:area: JP28,兵庫県,hyogo Japan
INFO:root:--------------------------
INFO:root:areaid :JP28
INFO:root:--------------------------
INFO:root:list of channels
INFO:root:['ABC', 'MBS', 'OBC', 'CCL', '802', 'FMO', 'RN1', 'RN2', 'CRK', 'KISSFMKOBE', 'HOUSOU-DAIGAKU', 'JOBK', 'JOAK-FM']
Traceback (most recent call last):
File "/home/pi/git/play-radiko/play_radiko.py", line 51, in <module>
main()
File "/home/pi/git/play-radiko/play_radiko.py", line 46, in main
radiko.play_radiko(channel, duration)
File "/home/pi/git/play-radiko/RadikoHLS.py", line 334, in play_radiko
self.play_radiko_livestream(channel, duration)
File "/home/pi/git/play-radiko/RadikoHLS.py", line 347, in play_radiko_livestream
chunk_url = self.chunk_m3u8_url(live_url, auth_token)
File "/home/pi/git/play-radiko/RadikoHLS.py", line 143, in chunk_m3u8_url
res = urllib.request.urlopen(req)
File "/usr/lib/python3.7/urllib/request.py", line 222, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib/python3.7/urllib/request.py", line 531, in open
response = meth(req, response)
File "/usr/lib/python3.7/urllib/request.py", line 641, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python3.7/urllib/request.py", line 569, in error
return self._call_chain(*args)
File "/usr/lib/python3.7/urllib/request.py", line 503, in _call_chain
result = func(*args)
File "/usr/lib/python3.7/urllib/request.py", line 649, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
</module>
403: Forbiddenとなり、あなたのIPは兵庫じゃないでしょウソをつくなと怒られて終了します。
ただ、この接続元IP判定は間違ってることが多々あり、東京の別の場所から接続しようとしたら兵庫県と判定されてしまうことがありました。この辺りはもうやむを得ないです。
5、cronでバックグラウンド再生・停止
店の開店に合わせて10:00に開始し、閉店に合わせて20:00に停止するcronを仕込みます。
crontab -e 0 10 * * * python3 /home/pi/git/play-radiko/play_radiko.py JOAK-FM > /home/pi/play_radiko.log 2>&1 & 0 20 * * * killall -KILL mplayer python3
以上です。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
Wav2Lipのオープンソース版を改造して外部から呼べるAPI化する
Wav2Lipのオープンソース版で静止画の口元のみを動かして喋らせる
【iOS】アプリアイコン・ロゴ画像の作成・設定方法
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【2】
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【1】
【Xcode】iPhone is not available because it is unpairedの対処法
【Let's Encrypt】Failed authorization procedure 503の対処法
【Debian】古いバージョンでapt updateしたら404 not foundでエラーになる場合
ファイアウォール内部のWindows11 PCにmacOS Sequoiaからリモートデスクトップする
【Windows10】リモートデスクトップ間のコピー&ペーストができなくなった場合の対処法
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
Windows11のコマンドプロンプトでテキストをコピーする
【Apache】サーバーに同時接続可能なクライアント数を調整する
Androidホームで左にスワイプすると出てくるニュース共を一切表示させない方法
【Linux】mkfsコマンドでProceed anyway?と確認を求められるのを回避する
タスクスケジューラで変更を適用できません。ユーザーアカウントが不明であるか、パスワードが正しくないか、またはユーザーアカウントにタスクを変更する許可がありません。と出た
【Debian】古いバージョンでapt updateしたら404 not foundでエラーになる場合
apt upgradeしたあとnvidia-smiがダメになった場合