NanoPi NEOにインストールしたMPDでradikoを聞く

f:id:lathe00744:20190222101956j:plain
NanoPi NEO / M.A.L.P. PlayList
有名な音楽再生サーバーのMusic Player Daemon (MPD)でradikoを聞けるように、簡単な中継サーバーアプリを作りました。スマホなどで操作して快適に選局できます。作ったものはこちらにあります。超小型・安価なLinuxボード NanoPi NEOで動かします。NanoPi NEO2でも動作確認済み、Raspberry Piなど、他の環境でも使えると思います。

NanoPi NEOにOSインストール

NanoPi NEO - FriendlyARM WiKi
こちらのページの5.3 Install OSにしたがって
nanopi-neo_sd_friendlycore-xenial_4.14_armhf_YYYYMMDD.img.zip
をインストールします。具体的には、download linkからGoogle Driveを選択、official-ROMsの
nanopi-neo_sd_friendlycore-xenial_4.14_armhf_20181119.img.zip
をダウンロードします。
つぎに、SDカードにこのOSイメージを書き込みます。SDカードは壊れやすいので産業用のものをお薦めします。RaspberryPiで何枚か壊しました。イメージの書き込みにはUbuntuのノートPCでETCHERを使いました。zipを解凍せずにそのまま書き込めるので便利です。
イメージを書き込んだら、SDカードの中の/etc/networks/interfacesを以下のように書き換えてIPアドレスを設定します。以下の例ではIPアドレス192.168.0.2、ルータのアドレスが192.168.0.1です。

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.0.2
netmask 255.255.255.0
gateway 192.168.0.1
dns-nameservers 192.168.0.1

ubuntuではroot権限が必要でしたが、他のOSではどうか把握していません。
これでsshで接続できるはずです。NanoPi NEOにSDカードを挿して電源投入し、青のLEDが点滅するのを待ち、PCからsshで接続します。

ssh -l pi 192.168.0.2

user: pi, password: piでログインできます。パスワードは変更しておきましょう。

pi@NanoPi-NEO:~$ passwd
Changing password for pi.
(current) UNIX password: 
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully

タイムゾーンを設定します。

pi@NanoPi-NEO:~$ sudo timedatectl set-timezone Asia/Tokyo

システムを最新の状態にアップデートします。

pi@NanoPi-NEO:~$ sudo apt-get update
...
Fetched 3,667 kB in 7s (461 kB/s)
Reading package lists... Done
pi@NanoPi-NEO:~$ sudo apt-get upgrade
...
216 upgraded, 0 newly installed, 0 to remove and 10 not upgraded.
Need to get 125 MB/125 MB of archives.
After this operation, 930 kB disk space will be freed.
Do you want to continue? [Y/n] Y
...
Installing new version of config file /etc/issue ...

Configuration file '/etc/issue.net'
 ==> Modified (by you or by a script) since installation.
 ==> Package distributor has shipped an updated version.
   What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
 The default action is to keep your current version.
*** issue.net (Y/I/N/O/D/Z) [default=N] ? Y
...
done.
pi@NanoPi-NEO:~$

Music Player Daemon (MPD)のインストール

pi@NanoPi-NEO:~$ sudo apt-get install mpd
...
After this operation, 129 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y

radikoを聞くだけなら必要ありませんが、MPD本来の使い方として、WindowsLinuxのSambaサーバーで共有している音楽ファイルを聞けるように設定します。
まずは、cifsプロトコルを扱えるようにcifs-utilsをインストール。

pi@NanoPi-NEO:~$ sudo apt-get install -y cifs-utils

起動時に自動マウントされるように、マウントポイントを設定します。

pi@NanoPi-NEO:~$ sudo vi /etc/fstab
/dev/mmcblk0p1    /boot vfat defaults 0 0
/mnt/512MB.swap    none    swap    sw    0    0
//192.168.0.3/music /media/music1 cifs username=guest,password=,uid=pi,gid=pi,iocharset=utf8 0 0
//192.168.0.4/music /media/music2 cifs credentials=/home/pi/.smbcredentials,iocharset=utf8,uid=pi,gid=pi,vers=1.0,sec=ntlmv2 0 0

最後の2行を追加しました。パスワードなしで共有されている場合の設定とパスワードが必要な場合の例です。サーバーのアクセスに必要なユーザ名とパスワードはつぎのようにファイルに保存しておきます。

pi@NanoPi-NEO:~$ vi ~/.smbcredentials
username=xxxxx
password=hogehoge

自分以外がアクセスできないようにします。

pi@NanoPi-NEO:~$ chmod 600 ~/.smbcredentials

続いてMPDの設定をしたいのですが、その前に音声出力用のUSBオーディオを接続し、MPDで指定するデバイス名を確認しておきます。

pi@NanoPi-NEO:~$ cat /proc/asound/cards
 0 [Dummy          ]: Dummy - Dummy
                      Dummy 1
 1 [Loopback       ]: Loopback - Loopback
                      Loopback 1
 2 [Codec          ]: H3_Audio_Codec - H3 Audio Codec
                      H3 Audio Codec
 3 [allwinnerhdmi  ]: allwinner_hdmi - allwinner,hdmi
                      allwinner,hdmi
 4 [UW10           ]: USB-Audio - YAMAHA UW10
                      YAMAHA Corporation . YAMAHA UW10 at usb-1c1d400.usb-1, full speed

YAMAHAのUW10を繋いだときの例です。
続いてMPDの設定です。

pi@NanoPi-NEO:~$ sudo vi /etc/mpd.conf
...
# 音楽ファイルの場所をサーバーをマウントしたディレクトリに変更します。
# music_directory               "/var/lib/mpd/music"
music_directory                 "/media"            
...
# スマホなど、NanoPi NEOの外からMPDに接続できるようにします。
# bind_to_address               "localhost"                                    
bind_to_address                 "any"
...
# ポート設定のコメントをはずします。
port                            "6600"
...
# プレイリストの場所を確認しておきます。
playlist_directory              "/var/lib/mpd/playlists"
...
# 確認したUSBオーディオを設定します。(audio_outputは複数あってもよいので追記します。)
audio_output {                                                                            
       type            "alsa"                                                             
       name            "USB YAMAHA"                                                       
       device          "hw:UW10,0"                                                        
       mixer_type      "software"                                                         
}   

設定を反映させるためにMPDを再起動します。

pi@NanoPi-NEO:~$ sudo service mpd restart

適当なMPDクライアントから接続できるか確認します。私はスマホアプリのM.A.L.P.を使っています。
NanoPi NEOのIPアドレスとMPDのポート番号6600を設定して、接続を確認します。
ここまでの手順は多くの方が解説されていますので、不明点は別途検索してみてください。

radiko中継サーバーのセットアップ

ここからがradikoを聞くための手順です。
最初から入っているffmpegは古すぎるので、新しいffmpegをインストールします。

pi@NanoPi-NEO:~$ sudo apt-get install ffmpeg

つぎに、Pythonの仮想環境を準備します。

pi@NanoPi-NEO:~$ sudo apt-get install -y python3-pip
pi@NanoPi-NEO:~$ sudo -H pip3 install --upgrade pip
pi@NanoPi-NEO:~$ sudo -H pip3 install virtualenv
pi@NanoPi-NEO:~$ virtualenv -p /usr/bin/python3 ~/radio

仮想環境radioの中にradiko中継サーバーをセットアップします。

pi@NanoPi-NEO:~$ source ~/radio/bin/activate
(radio) pi@NanoPi-NEO:~$ pip install django==2.1.5
(radio) pi@NanoPi-NEO:~$ git clone https://github.com/burrocargado/RadioRelayServer.git
(radio) pi@NanoPi-NEO:~$ cd RadioRelayServer/
(radio) pi@NanoPi-NEO:~/RadioRelayServer$ python manage.py migrate

radikoプレミアムの会員であれば、アカウント情報を設定します。

(radio) pi@NanoPi-NEO:~/RadioRelayServer$ cp settings/account_sample.py settings/account.py
(radio) pi@NanoPi-NEO:~/RadioRelayServer$ vi settings/account.py
RADIKO_MAIL='xxx@yyy.zzz'
RADIKO_PASS='foobarhogehoge'

空のプレイリストファイルを予め作成して書き込み許可を与えておきます。

(radio) pi@NanoPi-NEO:~/RadioRelayServer$ sudo touch /var/lib/mpd/playlists/00_radiko.m3u
(radio) pi@NanoPi-NEO:~/RadioRelayServer$ sudo chmod 666 /var/lib/mpd/playlists/00_radiko.m3u

最後に中継サーバーを起動します。Djangoの開発用サーバーですが、自宅で使う分には問題ないと思います。

(radio) pi@NanoPi-NEO:~/RadioRelayServer$ python manage.py runserver 0.0.0.0:9000

プレイリストが起動時に更新されます。これをMPDクライアントから読み込んでください。
聴取可能な放送局がリストになっていますので、そこから選局してください。放送局の切り替えは1秒ちょっとなので、そこそこ快適に使えると思います。

Supervisorで自動起動を設定

NanoPi NEOの電源投入後、自動起動するように設定します。まず、起動用スクリプトを作成します。

pi@NanoPi-NEO:~$ mkdir bin
pi@NanoPi-NEO:~$ cd bin
pi@NanoPi-NEO:~/bin$ vi radio_relay
#!/bin/bash
ENV_NAME=radio
VIRTUALENV_PATH=$HOME/$ENV_NAME
source $VIRTUALENV_PATH/bin/activate
cd $HOME/RadioRelayServer
python manage.py runserver 0.0.0.0:9000

プロセス管理ツールをインストールします。

pi@NanoPi-NEO:~/bin$ sudo apt-get install supervisor

設定します。

pi@NanoPi-NEO:~/bin$ sudo vi /etc/supervisor/conf.d/radio_relay.conf
[program:radio_relay]
environment=HOME=/home/pi
command=/home/pi/bin/radio_relay
directory=/home/pi/RadioRelayServer
user=pi
numprocs=1
stopasgroup=true
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/supervisor/radio_relay.log
stdout_logfile_maxbytes=1MB  
stdout_logfile_backups=7

設定を読み込ませます。

pi@NanoPi-NEO:~/bin$ sudo supervisorctl update

関係ありませんが、NanoPiのLEDが気になるようなら、/etc/rc.localのexit 0の手前に

/bin/sleep 5s      
/bin/echo none > /sys/class/leds/nanopi:blue:status/trigger                                               
/bin/echo heartbeat > /sys/class/leds/nanopi:green:pwr/trigger
/bin/echo none > /sys/class/leds/nanopi:green:pwr/trigger 

これを挿入すると消えます。

最後に

以前ほぼ同じ機能のスクリプトが公開されているのを見つけて試したのですが、NanoPiには荷が重すぎたため、PythonDjangoというWebフレームワークを使って作成してみました。Djangoはデータベースを駆使してインスタグラムなど大規模なサイトを構築するのに使われているようですが、今回のサーバーではデータベースは使っていません。ちょっともったいない使い方かもしれませんが、かんたんに目的を実現できたので、ありがたく使わせてもらいました。プログラミングは趣味の独学ですので、いろいろ指摘事項はあるかと思います。また、radikoの認証周りの処理は公開されているコードを借用しました。