LoginSignup
0
0

More than 1 year has passed since last update.

Raspberry PiでAirMac Expressの代替を目指す (AirPlayの導入まで)

Last updated at Posted at 2021-07-12

背景

自宅では長らくAirMac Expressを愛用してきました。最初は部屋間にLANケーブルを這わせるのはどうしても嫌、という妻の要望を叶える為、WDSモードで部屋同士のネットワークを無線LANで繋げるために購入しましたが、その必要も無くなった後は、AirPlayのレシーバとして重宝していました。

ただ、「諸行無常の響きあり」とあるように、どんなものにも別れの時はあります。最初3台購入していたAirMac Expressも、購入して10年程経ってから、一つ、また一つ壊れていき、今ではついに残り一台となってしまいました。

無線LANのアクセスポイントとしての代替品は世の中にたくさんありますが、AirPlayのレシーバとしての代替品は寡聞にして知りません。いや、ある事はあるようなのですが、私のやりたい事は既存のスピーカと繋げて、Appleご謹製のRemoteで大元のiTunesを操作して、いつでも好きな音楽を枕元で聞くというものなので、そういう目的に見合う物がどうやら世の中には無いようなのです。

長くなりましたが、この文章は、残ったただ一つのAirMac Expressがお亡くなりになる前に代替品をなんとかして準備した手順の備忘録になります。

前提条件

  • Raspberry Pi
  • MicroSDカード
  • HDMI接続のモニター
  • USB接続のキーボード
  • まぁまぁのLinuxの知識

おおまかな手順

何故か家にRaspberry Pi 3Bが一つ余っていたので、これを使ってAirMac Expressの代替品を作成する事にしました。ネットで検索すると、Raspberry PiをAirPlayのレシーバにしようとされた方々が多数いらっしゃったので、特に苦労する事も無いだろうと思ったのがその理由です。

  • Raspberry Piのセットアップ
  • Raspberry Pi OSの初期設定
  • Raspberry Pi OSの追加設定
  • Webminの導入
  • AirPlayレシーバの設定
    • apt経由での導入
    • Dockerコンテナとしての導入
      • Dockerの導入
      • Portainerの導入

Raspberry Piのセットアップ

知らない間にRaspbianがRaspberry Pi OSと名前を変えていました。Raspberry Pi OSはOSイメージをダウンロードしてMicro SDカードに書き込む必要がありますが、この作業を超絶簡単に行ってくれるのがRaspberry Pi Imagerです。これはRaspberry Piの公式ページからダウンロードできました。作業する環境に合わせて、Windows/Mac/Linuxのどれかを選んでからダウンロードします。

もちろんMicroSDカードも必要です。今回は何故か家で余っていた16GBのMicro SDカードを使用する事にしました。

Raspberry Pi Imagerを立ち上げるとこのような画面が表示されます。Operating SystemからインストールするOSの種類を、Storageで書き込み先を選択します。

Raspberry Pi Imager

今回は出来るだけ余計な物をインストールしたくなかったので、Raspberry Pi OS Liteを選びました。Writeを押すと必要なイメージをダウンロードして指定したSDカードに書き込んでくれます。便利な世の中になったものです。

全ての作業が終了したら、もうSDカードを抜いてもいいよ、というメッセージが表示されるので、書き込みが終わったSDカードをRaspberry Piに差し込んで、ついでにモニター・キーボードも接続して電源ケーブルを接続します。何やら色々表示された後、ログインプロンプトが表示されるので、とりあえずデフォルトのユーザであるpiでログインします。パスワードはraspberryです。

Raspberry Pi OSの初期設定

Raspberry Pi OSを使うに当たって最小限必要と思われる設定を行っていきます。必要最小限の設定はraspi-configで行う事が出来ます。

$ sudo raspi-config

日本語環境

まずは日本語環境に変更します。UTF-8をlocaleに追加。ただ、コマンドラインで作業する事もあるので、標準はCにしておきます。また、タイムゾーンは東京にします。今回使用したキーボードが109キーボードなので、それに一番近そうな設定にします。

Locale

  1. Localisation Optionsを選択
  2. Localeを選択
  3. ja_JP.UTF-8を追加
  4. Default localeではC.UTF-8を選択

タイムゾーン

  1. Localisation Optionsを選択
  2. Timezoneを選択
  3. Asiaを選択
  4. Tokyoを選択

キーボード

  1. Localisation Optionsを選択
  2. Keyboardを選択
  3. Keyboard modelではGeneric 105-Key PC (intl.)を選択
  4. Keyboard layoutではOtherを、続くCountry of originではJapaneseを選択
  5. もう一度Keyboard layoutに戻るので、今回はJapaneseを選択
  6. AltGrに割り当てるキーにはThe default for the keyboard layoutを選択
  7. ComposeキーはNo Compose keyを選択

無線LAN

  1. Localisation Optionsを選択
  2. WLAN Countryを選択
  3. JPを選択

sshを有効化

後ほどWebminを入れてwebベースで設定を行えるようにしますが、それでもコンソールで作業する場面も出てくると思うので、sshを有効化しておきます。

  1. Interface Optionsを選択
  2. SSHを選択
  3. Yesで有効化する

WiFiの有効化

WiFiでネットワークに接続する場合、下記のようにWiFiを有効化する必要があります。ただしこのままですと少し難があるので、後ほど説明するようにパスフレーズのハッシュ化を行った方が良いと思います。

  1. System Optionsを選択
  2. Wireless Lanを選択
  3. SSIDとパスフレーズを入力

ホスト名の変更

ホスト名の変更は以下のようにおこないます。

  1. System Optionsを選択
  2. Hostnameを選択
  3. 変更したいホスト名を入力

画面サイズ

これはだいぶ余計かもですが、今回準備したモニターは持ち運び可能な小型モニターなので、高解像度のままだととても見にくいため、低解像度にしました。基本的にはリモートで作業を行う事になるので、高解像度にする必要も無いですし。

  1. Display Optionsを選択
  2. Resolutionを選択
  3. CEA Mode 1を選択して解像度を640x480にしておく。

最後にFinishを選択すると再起動するかを聞かれるので、Yesで再起動します。特にホスト名を変更した場合再起動する必要があるので、もし途中でESCキーを押した等でraspi-configを抜け出した場合は自力で再起動して下さい。

Raspberry Pi OSの追加設定

ファイアウォールの設定

apt等でネットワークを使用する前に、まずはファイアウォールの設定を行っておきます。今の時代、たとえ個人で内向けに運用しているサービスでも攻撃を受ける可能性が十分にあります。1

ファイアウォールの設定には通常iptablesを使用しますが、正直難しいです。そこで、今回ファイアウォール設定を簡単に行えるufwを導入してみます。コンソール上から下記のような手順でufwのインストールから有効化までをおこないます。

$ sudo apt install ufw
$ sudo ufw enable

次に基本外から内への通信を遮断します。

$ sudo ufw default DENY

このあと最低限開いておきたいポートを指定します。今回sshを有効化しているので、とりあえずsshのポートだけ開こうと思います。ただし、万が一のため、同じLAN内からの接続のみを許可し、短時間で複数回接続を試みてきた通信を一時拒否するようにします。もし、同一LANが192.168.1.0/24であれば下記のようにします。

$ sudo ufw limit from 192.168.1.0/24 to any port ssh

ここから先はsshを使用してリモートで作業も可能です。

無線LANの追加設定

raspi-configでWiFiの設定を行った場合、WiFiの接続設定ファイルにパスフレーズが平文で書き込まれてしまうので、あまり心情的に宜しくはありません。WiFiの接続設定は/etc/wpa_supplicant/wpa_supplicant.confに保存され、またパスフレーズのハッシュ化にはwpa_passphraseが使用できます。

そこで気になる方は、下記のような手順でパスフレーズをハッシュ化してみて下さい。

まず下記のコマンドを実行して、ハッシュ化されたパスフレーズを含んだ設定をwpa_supplicant.confに保存します。

$ sudo sh -c "wpa_passphrase <SSID> <パスフレーズ> >> /etc/wpa_supplicant/wpa_supplicant.conf"

こうする事で下記のような行がwpa_supplicant.confに追加されているはずです。

network={
        ssid="<SSID>"
        #psk="<平文のパスフレーズ>"
        psk=<ハッシュ化されたパスフレーズ>
}

上記から平文のパスフレーズの行を削除してください。また、raspi-configによって書き込まれた下記のような行も上記の行の前にあると思うので、丸ごと削除してください。

network={
        ssid="<SSID>"
        psk="<平文のパスフレーズ>"
}

SWAP領域の停止

Raspberry Piは基本SDカードで運用するので、頻繁な書き込みにはあまり強く無いと思います。そのため、SWAP領域を無効化して少しでも寿命を伸ばそうと思います。

$ sudo swapoff --all
$ sudo systemctl stop dphys-swapfile
$ sudo systemctl disable dphys-swapfile

パッケージとファームウェアのアップグレード

これでいろいろ作業するための最低限の設定が終わりましたので、一度
パッケージとファームウェアのアップグレードを行っておきます。

$ sudo apt update
$ sudo apt full-upgrade
$ sudo apt-get autoremove
$ sudo apt-get autoclean
$ sudo reboot

Webminの導入

ここまでで基本的な設定は全て終了しましたが、今後リモートで色々と設定作業を行う際、sshで接続してというよりはWebベースで設定が行えると便利です。そんな環境を提供してくれるのがWebminです。Webminの導入も昔に比べるとだいぶ楽になりました。

まず、Webminが提供されているリポジトリのソース元をaptsources.listに追加します。

$ sudo vi /etc/apt/sources.list

sources.listを開いて、下記のような行を追加します。

## webmin
deb https://download.webmin.com/download/repository sarge contrib

次に、上記リポジトリのパッケージを認証するためのキーを追加しまします。

$ wget https://download.webmin.com/jcameron-key.asc
$ sudo apt-key add jcameron-key.asc
$ rm jcameron-key.asc

また、上記リポジトリにはhttps経由で接続するので、https経由でaptが使用できるようapt-transport-httpsもインストールします。

$ sudo apt install apt-transport-https

最後にWebminをインストールします。

$ sudo apt update
$ sudo apt install webmin

これでWebminに接続してWebベースで各種設定が行えるようになっています。Webminにはデフォルトでは下記のように10000番ポートを指定して接続します。

https://<接続先IP>:10000

そのため下記のように10000番ポートを開いておきます。

sudo ufw allow from 192.168.1.0/24 to any port 10000

なお、接続するポート番号はもちろん変更出来ます。その際には上記のufwへの指定も変更したポート番号に応じて変更して下さい。

Webmin上で新規ユーザ設定

せっかくWebminを導入してみたので、デフォルトの作業ユーザであるpiに代わるユーザを作成してみます。

なお、Webminで使用しているSSL証明書はいわゆるオレオレ証明書なので、接続した際に下記のように警告される筈です。まぁ、無視しても良いのですが、もし気になるようでしたらLet's EncryptからSSL証明書を入手しても良いかも知れません。

スクリーンショット 2021-07-10 14.12.33.png

Webmin上ではSystemから選択できるUsers and Groupsでユーザ情報の管理が出来ます。Create a new userボタンを選択する事で新規ユーザを作成出来ます。新規ユーザ名とパスワードを入力し、シェルは/bin/bashを選んでみます。所属グループはpiと同じ物を選択します。Createボタンでユーザ作成を終了し、新規ユーザでのログインに支障が無い事が確認出来たら、piユーザを無効化しておきます。

shairport-syncの導入

さて、そろそろ本題の、AirPlayのレシーバの設定をおこないます。ここからは大分試行錯誤が入ります。

aptを使用しての導入

AirPlayのレシーバとして使用するには、shairport-syncというソフトウェアを導入すると良いらしいです。shairport-syncはDebianのパッケージとしても提供されているので、早速aptを使ってインストールしてみました。

$ sudo apt install shairport-sync

これで、RemoteのAirPlay一覧にRaspberry Piのホスト名が表示されますが、このままでは使用出来ません。

shairport-syncは外からの接続要求やデータのやりとりに特定のポートを使用しており、この設定は/etc/shairport-sync.conに記述します。デフォルトでは以下のように、TCPの5000番と、UDPの6001-6101番を使用するようです。

general = 
{
//      port = 5000; // Listen for service requests on this port
//      udp_port_base = 6001; // start allocating UDP ports from this port number when needed
//      udp_port_range = 100; // look for free ports in this number of places, starting at the UDP port base. Allow at least 10, though only three are needed in a steady state.
}

shairport-syncが使用するポートを開くため、ufwで以下のように指定します。

$ sudo ufw allow from 192.168.1.0/24 to any port 5000 proto tcp
$ sudo ufw allow from 192.168.1.0/24 to any port 6001:6101 proto udp

これでAirPlayの接続先として選べます。なお、このままですと、人によっては音が出ずに悩むかも知れません。Raspberry Piは音声の出力先は2種類あり、一つは本体についているイヤフォンジャックから、もう一つはHDMI経由での出力になります。で、どうも標準ではHDMI経由の出力になっているようです。

$ amixer
Simple mixer control 'HDMI',0
  Capabilities: pvolume pvolume-joined pswitch pswitch-joined
  Playback channels: Mono
  Limits: Playback -10239 - 400
  Mono: Playback 0 [96%] [0.00dB] [on]

これを変えるには、例えばraspi-configを立ち上げて、

  1. System Optionsを選択
  2. Audioを選択
  3. 1 Headphonesを選択してOKを押す

とする事で標準の音声出力先をイヤフォンジャックに変更出来ます。変更後、例えば

$ aplay /usr/share/sounds/alsa/Front_Center.wav

とすると、どちらから音が出ているか直接確認出来ます。

ただ、この方法はshairport-syncには反映されません。shairport-syncでは出力先は/etc/shairport-sync.confに記述する必要があります。

alsa =
{
//      output_device = "default"; // the name of the alsa output device. Use "alsamixer" or "aplay" to find out the names of devices, mixers, etc.
}

で、上記output_devicemixer_deviceの記述方法ですが、ちゃんと書かれた文書が見つからなかったのですが、

$ man shairport-sync

によると、記述例として

alsa = {
output_device = "hw:0";
mixer_control_name = "PCM";
};

とあるので、多分、"hw:<カード番号>"のように指定すればいいのではと推測しています。カード番号はaplay -lで分かります。

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: b1 [bcm2835 HDMI 1], device 0: bcm2835 HDMI 1 [bcm2835 HDMI 1]
  Subdevices: 4/4
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
card 1: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
  Subdevices: 4/4
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3

これによるとイヤフォンジャックのカード番号は1なので、

alsa = 
{
        output_device = "hw:1";
}

として、

$ sudo systemctl restart shairport-sync

でサービスを再起動させます。これで、イヤフォンジャックから音楽が流れるようになっている筈です。

Dockerコンテナとしての導入

これでうまく行ったかと思ったら、そうは問屋が卸してくれませんでした。標準ではスピーカー名がホスト名になるので味気がありません。そこでスピーカー名を変えようと

general =
{
        name = "AirPlay";
}

としてサービスを再起動させると、何故かエラーで落ちてしまいます。

$ sudo systemctl restart shairport-sync
Job for shairport-sync.service failed because a fatal signal was delivered to the control process.
See "systemctl status shairport-sync.service" and "journalctl -xe" for details.

理由がさっぱりわからなかったのですが、このサイトでも同様のエラーが報告されていて、作者による返事では理由がいまいちはっきりせず、とりあえず3.3.5以上にしてくれ、というものでした。aptでとってきたのは3.2.2でした。

$ shairport-sync -V
3.2.2-OpenSSL-Avahi-ALSA-pa-dummy-stdout-pipe-soxr-convolution-metadata-sysconfdir:/etc

3.3.5以上にあげるには自分で最新版のソースコードを持ってきてbuildするか、Debianのbackportsとやらから持ってくるといいらしいのですが、前者は面倒だし、後者はいまいち不信感があるのであまりやりたくないです。どうしたものかと悩んでいたら、shairport-syncのDockerイメージがあることを発見。Dockerも導入しようかと思っていたところなので、渡に舟と、Dockerコンテナとしてshairport-syncを導入する事にしました。

その前にもったいないけど、まずインストール済みのshairport-syncと関連するパッケージを削除しました。

$ sudo apt purge shairport-sync
$ sudo apt autoremove

Dockerの導入

Dockerのサイトによると、Raspberry Pi OSへはDebianで通常推奨しているインストール方法は使用出来ないらしい。

Raspbian users cannot use this method!

For Raspbian, installing using the repository is not yet supported. You must instead use the convenience script.

そこで、ここに書かれている手順に沿って導入してみました。

まず、念の為、既存のDockerがらみのパッケージを全て削除して欲しいらしい。多分そんなものは一つも入っていない無い筈だけど、念の為下記のコマンドを実行。

sudo apt-get purge docker docker-engine docker.io runc

次にconvenienceなスクリプトをダウンロードします。

curl -fsSL https://get.docker.com -o get-docker.sh

ダウンロード後スクリプトを実行すると、勝手に必要なファイルのダウンロードとインストール作業を行ってくれます。

sudo sh get-docker.sh

Portainerの導入

追加でWebベースでDokerコンテナの管理が出来るようPortainerも導入します。PortainerはDockerイメージがあるので、

sudo docker pull portainer/portainer-ce:linux-arm

としてDockerイメージを入手しておいて、

sudo docker run -d -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:linux-arm

というように起動させます。この例ではポート9000番を使ってPortainerに接続するので、下記のように9000番を開けておきます。

sudo ufw allow from 192.168.1.0/24 to any port 9000

これで以下のようなURLでPortainerに接続できます。

https://<接続先IP>:9000

最初に接続した際に、管理者ユーザの作成が必要になります。これはPortainerだけで使用されるユーザのようです。

shairport-syncコンテナ

shairport-syncのDockerイメージはmikebrady/shairport-sync:latestです。

PortinerのContainersタブを選択して、コンテナ名を入力し、Dockerイメージにmikebrady/shairport-sync:latestを指定してDeploy the containerボタンを押すと、Dockerイメージのダウンロードからコンテナ起動までを行ってくれます。

他に指定すべきオプションはこちらの説明をみると、

  • NetworkはHost
  • Restart policyはUnless stopped
  • Deviceに/dev/snd
  • その他、shairport-syncとALSAに渡す引数をCommandに指定する。
    • -a AirPlayでスピーカー名を指定
    • -- -d hw:1でイヤフォンジャックを出力先に指定

これで好みのスピーカ名で接続できるようになっています。

今後の予定

本当はAirMac Expressの本来の目的であるWiFiアクセスポイントとしての設定まで行いたかったのだけど、自宅ではブリッジモードでWiFiのアクセスポイントを作成したいのでbridge-utilsをインストールしてゴニョゴニョしましたが、結論として現在WiFi側とLAN側をブリッジさせる事は出来なくなっているらしい。とりあえずRaspberry Piに搭載されているWiFiを使用してブリッジは出来ないっぽい。

$ sudo brctl addif br0 wlan0
can't add wlan0 to bridge br0: Operation not supported

解決策としては、ここにあるように、無線LAN側を4addr(WDS)モードにするか、もしくは外付けUSBのWiFiアダプターを用いると良いようだ。ただ、前者は理由が完全に理解出来ていないし(WDSモードってイーサコンバータとして使う場合に使用するのではなかったのかな?)、後者は、余っている筈のWiFiアダプターが行方不明になってしまったので、とりあえず今後の課題としました。

また、イヤフォンジャック経由ですと音が悪いとのことでUSB-DACを使用すると良いというもあるので、こちらも試してみようと思う。

その他参考にしたサイト


  1. 特にちょうど今Qlockerが話題になっていて他人事では無いです。 

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0