naoki86star

インターネットの片隅でなにかしら書いてみる

raspberry piでラジオ

 ダイソーで300円のUSBスピーカを販売していると知って、それを知ったらraspberry piでインターネットラジオを流したくなった。なかなかこの値段でのUSBスビーカは他でみかけない。最寄り駅近くにあるそんな売り場面積広くない店舗だけども販売していたので一つ購入。audioジャックのついているpi2でやってみた。

 USBスピーカのaudioプラグをpi2のオーディオジャックつないだら、ノイズが聞こえてきた。え”?、PCにつないでみるとスピーカは正常で音をならしたら音が聞こえノイズは聞こえない。調べるとpiのconfigで対策できる可能性ある項目があるらしい。自分の場合これで解決できて、config.txtに`disable_audio_dither=1`追加してrebootしたらノイズが収まった。素晴らしい。

 ストリーミングプロトコルで流してくれるURLが分かる放送については、mplayerというコマンドが、再生する方法の一つであることを知った。インターネットラジオしてくれる放送の一部では、ダイレクトに流しているのでなく、定時間間隔でメディアファイルをUPLOADしている場合があるらしい。そういう場合は、単にコマンドとURLで起動しても思ったような使い勝手にならない。
 NHK第一とかは、数秒分毎に.tsファイルで配信されていて、.m3u8って拡張子ファイルがそのリストになっている。中身は(読んだ時点での)固定長テキスト。mplayer は.m3u8を読み込んで順に再生してくれるけどもTSファイルの区切りでダウンロードするからなのか音声にディレイがでる、それと.m3u8ファイルを読み直してくれないのでリストの分が終わるとコマンドが終わってしまう。
 TSファイル間のディレイは、読み出しと再生をそれぞれcurlとmplayerで別プロセスにしてみたら、なくすことができた。

(for i in `curl https://nhkradioakr1-i.akamaihd.net/hls/live/511633/1-r1/1-r1-01.m3u8 | grep -v ^# | sed 's/\r//g'` ; do curl https://nhkra
dioakr1-i.akamaihd.net/hls/live/511633/1-r1/$i;done) | mplayer -really-quiet -

 1-r1-01.m3u8ファイルは時間経過とともに変わっていくようなので、TSリストが全部入れ替わったタイミングで呼びなおせるといいかた思ったけども、それはもうshシェルのみだけだと厳しそう。一度読んだTSファイルは次回読むm3u8ファイルに残っている場合でも読まないような芸が必要。

 てなことでpython使ってしまった。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import httplib
import time
import sys

host = "nhkradioakr1-i.akamaihd.net"
path = "/hls/live/511633/1-r1/"
m3u8 = "1-r1-01.m3u8"

def getlist(tslist, playlist):
    conn = httplib.HTTPSConnection(host)
    conn.request("GET", path + m3u8)
    res = conn.getresponse()
    if res.status != 200:
        sys.exit(1)
    for l in res.read().split('\r\n'):
        if l.startswith('#'): continue
        if len(l)>0 and not l in tslist:
            tslist.append(l)
            playlist.append(l)
    conn.close()

def cachets(playlist):
    for tsfn in playlist:
        conn = httplib.HTTPSConnection(host)
        conn.request("GET", path + tsfn)
        res = conn.getresponse()
        if res.status != 200:
            sys.exit(1)
        print res.read()
        conn.close()

tslist = []

while True:
    playlist = []
    getlist(tslist, playlist)
    cachets(playlist)
    if len(tslist)>18:
        tslist = tslist[len(tslist)-18:]

これで耳で聞く分には切れ目をなくせた。

$ python script2.py | mplayer -really-quiet -

### 参考(調べる動かすため決定的情報があって有益だった場所)
Rpi 2 - Background noises - Raspberry Pi Forums
ラズパイでネットラジオを聞く(NHK らじる★らじる ) - やってみる

### 2022.2.11追記
ファイルのありかをコード埋め込み固定でずっと動かしていたら今朝未明から404を返されるようになってしまった。
www.nhk.or.jp/radio/config/config_web.xmlから読み込んでちゃんとやれ、みたい。しかもそれ見るとm3u8ファイルはネストしてる。
configからurlは読むようにしたが、このネスト構造は固定プログラミングにしてしまう。*1

*1:音源もTSからACCってのに変わったらしい