アプリケーション開発ポータルサイト
ServerNote.NET
Amazon.co.jpでPC関連商品タイムセール開催中!
カテゴリー【RaspberryPIDebian
【Raspberry Piメモ・6】I2S-DACボードRBD-02+を装着しFOSTEX PM0.1でラジオを聴く
POSTED BY
2023-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

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

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

以上です。

※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

☆ServerNote.NETショッピング↓
ShoppingNote / Amazon.co.jp
☆お仲間ブログ↓
一人社長の不動産業務日誌
【キーワード検索】