Orange Pi 3 radiko SimulRadio

これまでradiko SimulRadioはOrangePi3上のubuntuコンテナを中心に設定、構成していたのですがその経緯にはdebianにswftools(ARM64)パッケージが無かったことから始まっています。(ubuntuリポジトリは利用できるのかな?)
このことは前回busterコンテナに再設定するまで忘れていたのですがなんとかradikoも動作するようになりました。
忘れていたことは忘れて改めてOrangePi3本体に設定してみました。

radiko

raspbianのswftoolsパッケージ情報を見ると依存するパッケージとインストールされるファイル情報が読み取れます。パッケージ自体は古いのでdebian系arm(64bit)でコンパイル済ならば流用できる可能性が高いと想像できます。

$ apt show swftools
Package: swftools
Version: 0.9.2+git20130725-4.1
Priority: extra
Section: utils
Maintainer: Christian Welzel <gawain@camlann.de>
Installed-Size: 5,043 kB
Depends: gsfonts, libc6 (>= 2.7), libfreetype6 (>= 2.2.1), libgif7 (>= 5.1), libjpeg62-turbo (>= 1.3.1), libmp3lame0, libzzip-0-13 (>= 0.13.56), zlib1g (>= 1:1.1.4)
Suggests: gs-common
Homepage: http://www.swftools.org/
Download-Size: 621 kB
APT-Manual-Installed: yes
APT-Sources: http://raspbian.raspberrypi.org/raspbian buster/main armhf Packages
Description: Collection of utilities for SWF file manipulation/creation
 SWF Tools is a collection of SWF (Flash) manipulation and creation utilities.
 .
 This package includes: as3compile, font2swf, gif2swf, jpeg2swf, png2swf,
 swfcombine, swfextract, swfdump, swfrender, swfstrings, swfbbox, swfc and
 wav2swf.
 .
  * as3compile is a standalone ActionScript 3.0 compiler. Mostly compatible
    with Flex.
  * font2swf converts font files (TTF, Type1) into SWF.
  * gif2swf converts GIFs into SWF. It is also able to handle animated gifs.
  * jpeg2swf takes one or more JPEG pictures and generates an SWF slideshow.
  * png2swf takes one or more PNG pictures and generates an SWF slideshow.
  * swfcombine is a tool for inserting SWFs into Wrapper SWFs. (Templates)
    E.g. for including the pdf2swf SWFs into some sort of Browsing-SWF.
  * swfextract allows one to extract Movieclips, Sounds, Images etc. from SWF
    files.
  * swfdump prints out various information about SWFs.
  * swfrender converts a swf to an image.
  * swfstrings scans SWFs for text data.
  * swfbbox allows one to readjust SWF bounding boxes.
  * swfc is a tool for creating SWF files from simple script files.
  * wav2swf converts WAV files into SWF.
 .
 This package does not include pdf2swf and avi2swf.

このファイルの中でradikoの再生録音に直接必要なファイルは/usr/bin/swfextractです。
また最初のauthkeyの作成にlibjpeg.so.8が必要になります。
これらのファイルをubuntuコンテナからコピーしました。

不足しているパッケージをインストール(mpv mplayer ffmpegはインストール済)

# apt install libxml2-utils rtmpdump libzzip-0-13

ubuntuからコピーしたswfextractを/usr/local/binにコピーします。

# cp swfextract /usr/local/bin

radikoスクリプトを実行

$ ~/bin/radiko.sh -p FMT
swfextract: error while loading shared libraries: libjpeg.so.8: cannot open shared object file: No such file or directory
[stop] failed get keydata (/var/tmp/authkey.png)

こんなエラーになる場合はlibjpeg.so.8がインストールされていません。
ubuntuにはlibjpeg.so.8.1.2がインストールされています。

$ ll /usr/lib/aarch64-linux-gnu/libjpeg*
lrwxrwxrwx 1 root root     16  7月  6  2018 libjpeg.so.8 -> libjpeg.so.8.1.2
-rw-r--r-- 1 root root 236168  7月  6  2018 libjpeg.so.8.1.2

コピーして同じようにリンクを張ります。

# cp libjpeg.so.8.1.2 /usr/lib/aarch64-linux-gnu
# cd /usr/lib/aarch64-linux-gnu
# ln -s libjpeg.so.8.1.2 libjpeg.so.8

radikoスクリプトを実行してエラーが無ければauthkey.pngとplayer.swfが作成されます。
/var/tmp

-rw-r--r-- 1 pi pi 198393  9? 22 17:06 authkey.png
-rw-r--r-- 1 pi pi 685413  9? 22 17:06 player.swf

もう一つの方法としてraspberry piなどで実際に聴取しているauthkey.pngとplayer.swfがあれば直接コピーすることでlibjpeg.so.8無しに動作が可能です。(ユーザーは合っていること)

SimulRadio

OrangePi3のtigervncはgeometry=”922×545″でdwmの左右の境界線(default)は0.55(55:45)に設定しています。この値に収まるようにsimul.pyのフォントを調整してみました。
フォントの見栄えはOSの設定、vncserver(tiger or tight)などによって違ってきます。
https://codeday.me/jp/qa/20190513/817329.html

from tkinter.font import Font

if __name__ == '__main__':
    root = Tk()
    root.title('SimulRadio')

    # Font
    listfont = Font(family="calibri",size=8)
    #root.option_add("*Font", listfont)
    root.option_add("*Listbox*Font", listfont)


ボタンのフォント、文字サイズはstyleで変更します。
root.option_add(“*Font”, listfont)は全体の文字サイズを変更しますがmessageboxの文字サイズも変更してしまうためListboxのみ変更しています。
以前より2ポイント位小さくなっていますが選局には支障ないと思います。

ncmpcpp

やはりncmpcはクセがあるようでOrangePi3では接続拒否されてしまいました。ncmpcppのインストール容量は少し大きくなりますが確実に接続できるようです。
mpd.confのmusic_directory設定は音楽ファイルのある任意のディレクトリを指定できます。
設定ファイルは今までのものを全てコピーしているので一旦空にしてmpdを再起動します。

$ cd ~/.config/mpd
$ : > mpd.log && : > state && : > sticker.sql && : > database
$ killall mpd && /usr/bin/mpd &


簡易なデータベースも瞬時に作成します。
PlaylistとBrowseの切り替えはTabまたは数字キーの1,2で切り替えます。
Browseから曲を選択してPlaylistに登録、再生


ラジオをPlayすると登録したPlaylistをクリア、ラジオを再生します。
simul radio – ncmpcppの再生は同じmpdを使用しているので切り替えが可能です。
radikoの再生もmpdを停止するので自動でOK、radikoの再生中からncmpcppだけは自動でmpvを止めないのでradikoを一旦停止する必要があります。
←→キーで音量調整ができます。

Orange Pi 3 Armbian debian buster 5.3.0

Linux Kernel version 5.3になってArmbian Debian busterもだいぶ安定してきたように思います。

当サイトのOrangePi3もstretchからdebian busterに移行してみました。

マイクロSDカード作成

# dd if=Armbian_5.97.190920_Orangepi3_Debian_buster_dev_5.3.0.img of=/dev/sdb bs=1M status=progress

chrony

NTPクライアントにchronyが採用されているのですが起動していませんね。

# journalctl -xe
Fatal error : Could not get _chrony uid/gid

原因がよくわからないので従来のntpをインストールします。

# apt install ntp
以下のパッケージは「削除」されます:
  chrony
以下のパッケージが新たにインストールされます:
  libopts25 ntp

インストールすると時刻が同期するようになります。

tigervnc server

ヘッドレスで運用しているOrangePi3はtigervnc serverをインストールしているのですがtigervnc1.9.0はクラッシュしてしまいます。

# apt install xserver-xorg x11-xserver-utils tigervnc-standalone-server tigervnc-common tigervnc-viewer
$ dpkg -l | grep tiger
ii  tigervnc-common 1.9.0+dfsg-3 arm64 Virtual network computing; Common software needed by servers
ii  tigervnc-standalone-server 1.9.0+dfsg-3 arm64 Standalone virtual network computing server
ii  tigervnc-viewer 1.9.0+dfsg-3 arm64 Virtual network computing client for X

以前よりbusterは試しているのですが有効な解決策が見つからないので少々姑息な手段ですが一旦1.9.0をインストールしてからstretchでインストールした1.7.0と差替えます。

# cp Xtigervnc /usr/bin/Xtigervnc
# cp tigervncconfig /usr/bin/tigervncconfig

起動、コピペも特に問題無いようです。

日本語入力uim anthy

uimは依存関係が変更になっています。uim-xim uim-gtk2.0を指定します。

# apt install uim uim-anthy uim-xim uim-gtk2.0

cpufreq

現在のsun50i-h6-orangepi-3.dtbは問題なく起動する(480MHz-1.8GHz)のですが当サイトの環境ではcpuクロックを変更すると再起動を繰り返してしまいます。
特に最新のdtbを必要とするデバイスも無いことから取り敢えず5.1.5dtbに差し替えています。

5.1.5dtbでは問題なく切り替え可、動作します。
1.32GHz〜1.49GHzではフル稼働時も温度上昇を抑えることができます。

docker-ce

docker-ceのインストールはraspberry piと同様でOKですね。

$ curl -sSL https://get.docker.com | sh
# Executing docker install script, commit: 6bf300318ebaab958c4adc341a8c7bb9f3a54a1a
You're using 'debian' version 'buster'.
Upstream release is 'debian' version 'buster'.
+ sudo -E sh -c apt-get update -qq >/dev/null
+ sudo -E sh -c apt-get install -y -qq apt-transport-https ca-certificates curl >/dev/null
+ sudo -E sh -c curl -fsSL "https://download.docker.com/linux/debian/gpg" | apt-key add -qq - >/dev/null
Warning: apt-key output should not be parsed (stdout is not a terminal)
+ sudo -E sh -c echo "deb [arch=arm64] https://download.docker.com/linux/debian buster stable" > /etc/apt/sources.list.d/docker.list
+ sudo -E sh -c apt-get update -qq >/dev/null
+ [ -n  ]
+ sudo -E sh -c apt-get install -y -qq --no-install-recommends docker-ce >/dev/null
+ sudo -E sh -c docker version
Client: Docker Engine - Community
 Version:           19.03.2
 API version:       1.40
 Go version:        go1.12.8
 Git commit:        6a30dfc
 Built:             Thu Aug 29 05:30:43 2019
 OS/Arch:           linux/arm64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.2
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.8
  Git commit:       6a30dfc
  Built:            Thu Aug 29 05:29:15 2019
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.2.6
  GitCommit:        894b81a4b802e4eb2a91d1ce216b8817763c29fb
 runc:
  Version:          1.0.0-rc8
  GitCommit:        425e105d5a03fabd737a126ad93d62a9eeede87f
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
If you would like to use Docker as a non-root user, you should now consider
adding your user to the "docker" group with something like:

  sudo usermod -aG docker pi

Remember that you will have to log out and back in for this to take effect!

WARNING: Adding a user to the "docker" group will grant the ability to run
         containers which can be used to obtain root privileges on the
         docker host.
         Refer to https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface
         for more information.

busterではubuntuコンテナのmpdの挙動が怪しくなってなってしまいました。
debian busterコンテナに再設定、こちらは問題なく動作しています。

debian busterにはradikoの再生に必要なswftools(arm64)パッケージが見当たりません。
こちらも手っ取り早くubuntuコンテナ(/usr/bin/swfextract)からコピーして/usr/local/bin/swfextractに置いています。
またlibjpeg62-turboをインストールしています。

# cp swfextract /usr/local/bin
# apt install libjpeg62-turbo

SimulRadio(サイマルラジオ) - MPD(music player daemon)

前回までに作成したSimulRadioは少々UIがダサいことを除けば問題なく稼働しているのですが唯一の欠点は接続、再生開始に約10秒前後を要することです。

なんとかこの待ち時間を短縮すべく再生プレーヤーにMPD(music player daemon)を導入してみました。

MPDはpc audio,raspberry pi(moode audio)などで音質、安定性とも定評のあるmusic daemonですね。
当サイトの環境では音声はpulse audioで全てmoode audioに送っているのでMPDはユーザーで起動実行しています。(systemdのmpd(pulse audio)は接続できない)
RaspberryPi3,OrangePi3上のubuntuコンテナで確認

MPDのインストール

# apt install mpd mpc ncmpcpp

インストールしたMPDはsystemdから自動起動しないようdisableしておきます。

# systemctl stop mpd
# systemctl disable mpd

mpd.conf

/etc/mpd.confから抜粋 alsaを使う場合は有効に!
raspberry piのalsaでも確認していますがmpvなどのようにalsa-pulseaudioの自動切り替えはしないのでOS(pulseaudio)の設定次第になります。
~/.config/mpd/mpd.conf

music_directory     "~/radio/music"
playlist_directory  "~/radio/playlist"
db_file             "~/.config/mpd/database"
log_file            "~/.config/mpd/mpd.log"
pid_file            "~/.config/mpd/pid"
state_file          "~/.config/mpd/state"
sticker_file        "~/.config/mpd/sticker.sql"
bind_to_address "localhost"
port            "6600"
input {
    plugin   "curl"
}
input {
    enabled  "no"
    plugin   "tidal"
}
input {
    enabled  "no"
    plugin   "qobuz"
}
decoder {
    enabled  "no"
    plugin   "hybrid_dsd"
}
audio_output {
    type     "pulse"
    name     "pulse audio"
}
#audio_output {
#    type    "alsa"
#    name    "My Sound Card"
#}

ディレクトリを作成

$ mkdir ~/radio/music && mkdir ~/radio/playlist

mpdの起動、確認

$ /usr/bin/mpd &

適当な音楽ファイルを~/radio/musicに放り込んでインストールしたncmpcppからmpdの確認をします。

$ ncmpcpp


ncmpcというクライアントソフトもありますがraspberry piではうまく接続できませんでした。
browse画面で選択するとplaylistに登録追加されます。
デフォルトではyoutubeから直接再生はできないようです。
ダウンロードしたmp4ファイルは音声のみ再生可
設定に間違いが無ければalsaまたはpulse audioから再生します。

$ ncmpc


ncmpcも動作していました。
再起動が必要だったようです。

radioの再生

$ mpc help | less


mpdクライアントのmpcにはいろいろなコマンドがあります。
この中から適当なコマンドを使ってプログラム内で実行しています。


mpdの基本はplaylistを作成してmpcから実行指示します。
mpc add urlでplaylistに登録
mpc play 再生開始
mpc stop 停止
mpc clear playlistをクリア
pythonプログラムではplaylistを書き換えて実行しています。

killall.sh

mpc stopとmpc clearを追加

#!/bin/sh
mpc stop
mpc clear
killall -q mpv
killall -q mplayer
killall -q ffplay

simul.py

SimulRadioの動作はmpvプレーヤー時と同じようにしたいと思います。
参考 simul.py

mpdの起動
simul.py起動時プログラムの最初の方でmpdが起動していなかったらmpdを起動します。

# mpd
command = ("ps ax | grep mpd | grep -v grep")
proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
if not (proc):
    subprocess.run("/usr/bin/mpd &", shell=True)

play
前回は余計なことをしてyoutube urlも実行できると書いてしまったのでyoutube再生はmpvで実行するようにしました。選択したurlをmpc addしてwww.youtube.comの文字列があったらmpvで実行します。

# selection
def play_selection():
    for i in lb.curselection():
        a = (lb.get(i))
        subprocess.run("mpc add " + (a), shell=True)
        command = ("mpc playlist | grep -oP 'www.youtube.{0,4}' | grep -v {")
        proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
        proc = proc.strip()
        if proc == 'www.youtube.com':
            command = ((("mpv ") + (a)) + (" &"))
        else:
            command = ("mpc play")
        subprocess.run(command, shell=True)

ON AIR
ON AIR情報はmpc playlistから取得しています。停止時はkillall.shでmpc clearしてplaylistから削除

# ON AIR
def button7_click():
    command = ("mpc playlist | grep -oP 'JCB.{0,3}' | grep -v {")
    proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
    if not (proc):
        command = ("mpc playlist | grep -oP 'jp/3.{0,4}' | grep -v {")
        proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
        # CSRA NHK
        if not (proc):
            command = ("mpc playlist")
            proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
            proc = proc.strip()
            if proc == 'https://nhkradiohkfm-i.akamaihd.net/hls/live/512076/1-fm/1-fm-01.m3u8':
                proc = 'NHK FM 仙台'
            if proc == 'https://nhkradiohkr1-i.akamaihd.net/hls/live/512075/1-r1/1-r1-01.m3u8':
                proc = 'NHK R1 仙台'
            if not (proc): 
                command = ("ps ax | grep mpv | grep -v grep | awk '{print $NF}'")
                proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
                proc = proc.strip()
                if proc == '-':
                    proc = 'Radiko playing'
                else:
                    proc = 'No Station'
            messagebox.showinfo('ON AIR', proc)
        # ListenRadio
        else:
            proc = proc.strip()
            proc = proc[3:]
            with open("/home/pi/radio/CSRA/ListenRadio", 'r') as f:
                for id in f:
                    if re.search((proc), id):
                        messagebox.showinfo('ON AIR', id)
    # JCB
    else:
        proc = proc.strip()
        with open("/home/pi/radio/JCBA/JCB", 'r') as f:
            for id in f:
                if re.search((proc), id):
                    messagebox.showinfo('ON AIR', id)

simul.py実行

$ ~/bin/simul.py &

さて肝心のmpdの成果ですがかなりの改善を得ることができました。
特にListenRadioではplayとほぼ同時に再生を開始します。

ubuntuコンテナからも同様で
JCBA 3〜4秒
mms: 2〜3秒
接続再生開始します。
http(https)はmpdが圧倒的に早そうです。
これでストレス無く聴取できそうです。あとはラジオ局間の音量のばらつきが少なければいいのですが…
UI、操作類は一切変わっていないはずです。

Raspberry pi SimulRadio(サイマルラジオ)

前回までサイマルラジオCSRA(ListenRadio)とJCBAの動作を確認したので一つのプログラムに纏めてみたいと思います。

基本は同じプログラムなのでボタンの数は増えますがON AIRの部分を少し変更することでいけると思います。

ON AIR(再生中の放送局表示)はエリアを切り替えること、局数も多いことから必須と考えています。

SimulRadio

ON AIR
前回messageboxには正常に表示するのですがmessageboxから抜ける際Typeerrorが出ていました。どうやらmessagebox.askyesnoが関係しているようです。(loopしている?)
messagebox.showinfoで表示することでエラーを回避することができました。

mpvはurlを実行しています。
JCBAはJCB+3文字をCSRA(ListenRadio)はjp/3+4文字を取り出しています。
改行コード、CSRA(ListenRadio)は3文字(jp/)を削除してそれぞれIDを抽出します。
その値をre.searchでJCBAはファイル(JCB),CSRAはファイル(ListenRadio)を読んでmessageboxに出力しています。

$ ps ax | grep mpv
 1639 ?  Sl  0:01 mpv http://musicbird-hls.leanstream.co/musicbird/JCB001.stream/playlist.m3u8?args=web_03
$ ps ax | grep -oP 'JCB.{0,3}' | grep -v {
JCB001

$ ps ax | grep mpv
 1706 ?  Sl  0:01 mpv http://mtist.as.smartstream.ne.jp/30031/livestream/playlist.m3u8
$ ps ax | grep -oP 'jp/3.{0,4}' | grep -v {
jp/30031


検索は最初にJCBAを実行しています。結果が空のときはCSRA(ListenRadio)で検索し直します。
それも空のとき(CSRA(直)やNHKなど)はurlを取得します。


再生開始はCSRA(直)mms://が早いですね。
http(https)はubuntuコンテナで10秒前後かかっています。
RaspberryPi3はもう少し早い
現在のウィンドウは10局表示しています。20局位までにしておくと選局しやすいかな


Area Editボタンは表示中のエリアファイルを編集します。
ID EditボタンはIDファイルJCB(JCBA)ファイル、ListenRadio(CSRA)ファイルを編集します。
選択はmessagebox.askyesnoで簡易に済ませています。
エディタは使いやすいものに変更するといいでしょう。


radiko再生中
killall.shは共通で使っているのでSimul RadioからRadikoまた逆もOKです。
stopボタンはradikoも停止します。


favorite(お気に入り)ボタンは自由に使えます。
エリアリストの中から気に入った局をコピーして再登録します。
mpvは動画を再生できるのでyoutubeのurlをラジオリスト同様に登録しておけば気に入ってる動画を再生することもできます。依存で入ったyoutube-dlは削除して最新のyoutube-dlをインストールする必要があります。

see https://rg3.github.io/youtube-dl/download.html

$ sudo apt remove youtube-dl
$ sudo curl -L https://yt-dl.org/downloads/latest/youtube-dl -o /usr/local/bin/youtube-dl
$ sudo chmod a+rx /usr/local/bin/youtube-dl
youtube-dlは定期的にアップデート
$ sudo youtube-dl -U


再生開始はキャッシュを取得するため多少時間がかかることがあります。

simul.py Station List

内容は無保証です。間違いなどがあれば勝手にバンバンしてください。
リストは220局くらいあると思います。
参考 simul.py

Station List
CSRA
JCBA
NHK

ID List
ListenRadio
JCB


ディレクトリ、ファイルの構成はこんな感じ
pythonプログラムなどは~/bin


ubuntuコンテナで作成したpythonファイル、リストをRaspberriPi3にコピー
音量、音質はラジオ局によって違います。
音量はかなり低めの局もあれば高すぎる局もあります。Suzuka Voice FMはバリバリレッドゾーンに入っていますね。当サイトの環境では歪んでいます。(場所柄難聴ラジオかな?)
時間外などはmusicbirdやj-wave配信の共通番組を流しているところも多いようです。

Python3 サイマルラジオ CSRA JCBA

Wikipediaより

SimulRadio(サイマルラジオ)は、コミュニティFMの自主制作番組をネット配信するサイト、およびそのためのプロジェクトである。

コミュニティ放送の役割の一つとして災害時の情報を提供することが挙げられます。
災害の現地に住んでいなくてもより詳しい情報を知り得たいという場面があるかもしれません。普段からもう少しサイマルラジオを聞くようにしたいと思います。
本当は各地のトーク番組などを聞きたいだけなのですが…ぼそ

聴取方法はPcのwebブラウザからやスマホのアプリケーションなどいろいろありますができるだけ良好な音でしかも軽快に利用したいためRaspberry PiなどのSBCから実行できるものとします。
CSRA、JCBAともurlがわかれば直接再生が可能です。

$ mpv "mms://hdv3.nkansai.tv/chofu"

目標は100局以上のラジオ局をエリア別に簡易なリストを作成、簡単なpythonプログラムで選局、再生するものとします。

ラジオ局リスト

自由に利用できるSimulRadioのプロジェクトにはCSRAとJCBAがあります。
現在JCBAはmusicbirdが配信しているようです。
CSRAは独自で配信している部分もありますがリスラジ(ListenRadio)に誘導されることもあります。実質配信に関してはリスラジが主体という印象があります。
どちらもまとまった形でurlリストを入手することは困難のようですが以下のサイトが参考になりました。
http://fsyublog.blog13.fc2.com/blog-entry-1214.html
JCBAインターネットサイマルラジオの仕様が変更された
CSRAは上記の記事を参考にリスラジ主体のリストを作成、JCBAはブラウザからurlを取得、取り敢えずテストに必要な分だけ揃えました。

Pi3のchromiumから取得
再生を開始
右クリック–検証–Networkタブ–Filter Boxに”m3u8″を打ち込む
chunklist_wxxx 右クリック–Copy–Copy link address

目的のurlはJCBxxxとm3u8が含まれているものです。
必要なアドレスはweb_03まで JCBxxxが固有のIDですね

https://chi-edge2-wow-relay1.leanstream.co/musicbird/_definst_/JCB019.stream/chunklist_w199142625.m3u8?args=web_03

# 追記
Filter Boxに打ち込む文字列はplaylist.m3u8ですね。基本のurlが取得できます。
JCBxxx=ラジオ局を紐付けできます。

https://musicbird-hls.leanstream.co/musicbird/JCB019.stream/playlist.m3u8?args=web_03


取得したurlをエリア別に局名とurlを1行形式で記述
エリアファイルは~/rajio/JCBA/以下に置いています。


ファイル JCB
IDと局名を記載 こちらは再生中の表示(ON AIR)に使います。

Python3 SimulRadio

pythonプログラムは前回作成したdocker container Listboxをベースに作成しました。

Listboxはエリアファイルを読み込むと局名とurlの2行で表示します。再生はurlを選択してPLAY
各エリアは瞬時に切り替えが可能です。
現在の不具合は起動時はスクロールバーが動作するのですがエリアを切り替えると動作しなくなります。但しマウスでのスクロール、及びキーボードでの操作は可能なので1エリア20〜30位の局数であれば問題ないと思います。


EDITボタンはエディタが起動して現在表示しているエリアの編集、新規追加が可能。
ON AIRボタンは再生中の局を表示、Yesでダイアログ終了、Noでファイル(JCB)の編集になります。ID以外はちょっとしたメモの追加など自由に編集できます。

python ~/bin/jcba.py

参考 jcba.py
~/bin/killall.shは前回radikoのものを使います。
Listbox
最初の方に起動時のデフォルトエリアを設定しています。

# default area
t = "/home/pi/radio/CSRA/関東"

mainでそのファイルを読み出しています。
エリアを切り替えるためにdef area_selection():で再度読み直しています。この時スクロールバー設定を引き継げないようです。

    # Listbox
    with open(t, 'r') as f:
        proc = f.read()
        currencies = (proc)
        v1 = StringVar(value=currencies)
        lb = Listbox(frame1, listvariable=v1,height=20,width=60)
        lb.grid(row=0, column=0)

# selection
def area_selection():
    global v1,lb
    with open(t, 'r') as f:
        proc = f.read()
        currencies = (proc)
        v1 = StringVar(value=currencies)
        lb = Listbox(frame1, listvariable=v1,height=20,width=60)
        lb.grid(row=0, column=0)

play
一旦killall.shを実行、Listboxで選択したurlを変数”a”にしてプレーヤー(mpv)で実行

# play
def button1_click():
    subprocess.run("~/bin/killall.sh", shell=True)
    play_selection()

# selection
def play_selection():
    for i in lb.curselection():
        a = (lb.get(i))
        command = ((("mpv ") + (a)) + (" &"))
        subprocess.run(command, shell=True)

ON AIR
ON AIRボタン(再生中の表示)はps axからurlの中のJCB+3文字を拾い出して、改行コードを削除、その値をreモジュールからファイル(JCB)を検索、読み出しています。

import re


コマンドラインから実行確認するとTypeErrorが出てしまいますが結果は正常に検索できているので取り敢えず様子を見ることにします(要調査)
TypeError: first argument must be string or compiled pattern

CSRA FM

CSRAで作成してみました。

単に再生することあればエリアリストをJCBAと共通にできるのですがプロジェクト別に管理、違いを確認したいこともあって別にしています。

まだまだエリアリストはできていないのですがCSRAで100局くらい、JCBAも同じくらいあるものと思います。
エリアリストを別にしたままCSRA,JCBA共通プログラムにしてみようと思います。

Top