noraworld / scraps

Just my scraps, like Zenn scraps feature
0 stars 0 forks source link

Raspberry Pi を AirPlay サーバ化する計画 #49

Open noraworld opened 1 year ago

noraworld commented 1 year ago

今まで Bluetooth で音声をミキシングすることばかりにこだわっていたが、音声を聴くデバイスは Mac や iPhone と、Apple 製品に限られているので AirPlay で音声を取れば良いのでは? と思った。というか AirPlay でも音声が拾えそう、というのがネットサーフィンしていて分かった。

これを参考にしながら進めてみる。

https://101010.fun/iot/raspberry-pi-airplay-server.html

noraworld commented 1 year ago

インストールすべきパッケージがたくさんあったので、どれをすでにインストールしていてどれを新しくインストールするべきか調べるために apt list コマンドを実行したのだが、[installed] という項目を見落としていて表示されたものはすべてインストール済みだと勘違いして先に進んでしまったら、案の定 autoreconf -i -f のところでコケた。のちに [installed] と書かれていないパッケージはまだインストールされていないものだということに気づき必要なパッケージをインストールしたら無事コマンドが成功した。

noraworld commented 1 year ago

サービスの自動起動設定のところまでは特につまづくこともなく順調に構築できていたのだが、再起動しても iPhone に AirPlay の候補が表示されない。デーモンは起動していることを確認済み。

noraworld commented 1 year ago

トラブルシューティングを見てみたけど、そもそも AirPlay が認識されない的なものがない。

https://github.com/mikebrady/shairport-sync/blob/f5c4b51da827a7f8d9a72a1b6f986807aba47bfc/TROUBLESHOOTING.md

ファイアーウォールでブロックしてしまっているならそもそもデーモンの起動に失敗するはずだが特にそれはなく、デーモンを使わずに shairport-sync コマンドを手動で実行してもエラーで落ちたりはしない。

noraworld commented 1 year ago

そういえば AirPlay って同じ Wi-Fi ネットワークにいないといけないとかなんとかというのを思い出したので、Raspberry Pi を Wi-Fi に接続してみた。

https://kkkw.hatenablog.jp/entry/20220502/1651471611

何気に Raspberry Pi で Wi-Fi を使うのは今回が初めてだ。

しかしそれでもやはり AirPlay の候補に表示されない……。

noraworld commented 1 year ago

再起動しても同じ。

https://support.apple.com/ja-jp/HT204291

noraworld commented 1 year ago

全く分からんので質問してみた。

https://github.com/mikebrady/shairport-sync/discussions/1668

noraworld commented 1 year ago

とりあえずもう一度 sudo systemctl start shairport-sync しようとしたら Failed to start shairport-sync.service: Unit avahi-daemon.service is masked. と言われてしまったので、sudo systemctl unmask avahi-daemon しておいた。そしたら再び起動できるようになった。そもそも最初はこんな現象になっていなかったのになぜ途中からこんなことになってしまったのか不明だが。

noraworld commented 1 year ago

回答が来た。

https://github.com/mikebrady/shairport-sync/discussions/1668#discussioncomment-5695971

回答の中にある別の Issue を辿ってみると、avahi-daemon とかのコマンドを実行して調査してみてとか書いてあったけどそもそもそんなコマンドないからおかしいなと思っていた。

そういえば必要なパッケージをインストールしたといったけど、あれは公式ではなくここの記事のものをインストールしただけにすぎなかった。

なので、ちゃんと公式で明記されているパッケージをすべてインストールすることにした。

https://github.com/mikebrady/shairport-sync/blob/acdae45549aedc0262471829c7aefaeff43f68d3/BUILD.md

以下のパッケージがまだ未インストールだったのでインストールした。

avahi-daemon/jammy,now 0.8-5ubuntu5 arm64 [residual-config]
libavcodec-dev/jammy-updates,jammy-security 7:4.4.2-0ubuntu0.22.04.1 arm64
libavformat-dev/jammy-updates,jammy-security 7:4.4.2-0ubuntu0.22.04.1 arm64
libavutil-dev/jammy-updates,jammy-security 7:4.4.2-0ubuntu0.22.04.1 arm64
libplist-dev/jammy 2.2.0-6build2 arm64
libsodium-dev/jammy 1.0.18-1build2 arm64
noraworld commented 1 year ago

そして再起動した。

noraworld commented 1 year ago

パッケージ全部インストールしたら表示されるようになった!

image

やっぱりそこらへんの記事だけじゃなくてちゃんと公式ドキュメント読むべきだな......。

noraworld commented 1 year ago

しかし接続しようとすると Unable to connect to AirPi となってしまい接続できない……。

noraworld commented 1 year ago

Wi-Fi のパワーセーブモード (低電力モード) がオンになっていると正しく動作しない可能性があると公式のトラブルシューティングに書いてあったのでオフにした。

sudo iw dev wlan0 set power_save off

https://github.com/mikebrady/shairport-sync/blob/acdae45549aedc0262471829c7aefaeff43f68d3/BUILD.md

しかし解決せず。

noraworld commented 1 year ago

次にドキュメントに書いてあったのはファイアーウォールを無効にすることなので、これも試してみたらなんとこれがビンゴ。見事、接続することができた!

ただしネットワークの関係上、ファイアーウォールはオフにはしたくないので AirPlay は許可されるように設定しておこう。いや、オフにしたくないというか、オフにするとフォワーディングされないからネットワークが使えなくなるのか、完全に忘れてた。

noraworld commented 1 year ago

しかし AirPi のほうにつないでもふつうに iPhone 本体から音が聞こえてくる。全く意味をなしていない……。

noraworld commented 1 year ago

とりあえず UFW オンにした状態でも AirPlay が使えるようにポート許可した。

https://github.com/mikebrady/shairport-sync/blob/master/TROUBLESHOOTING.md#wifi-adapter-running-in-power-saving--low-power-mode:~:text=sudo%20ufw%20allow%20319%3A320/udp%0Asudo%20ufw%20allow%203689/tcp%0Asudo%20ufw%20allow%205353%0Asudo%20ufw%20allow%205000/tcp%0Asudo%20ufw%20allow%207000/tcp%0Asudo%20ufw%20allow%206000%3A6009/udp%0Asudo%20ufw%20allow%2032768%3A60999/udp%0Asudo%20ufw%20allow%2032768%3A60999/tcp

本当は "Classic AirPlay" のほうで良いけど今後のことを考えて "AirPlay 2" のほうを設定した。AirPlay 2 が Classic AirPlay をすべて含んでいるので問題ないはず。

無事、UFW をオンにしたまま AirPlay にもつなぐことができた。なんかときどき設定に失敗するけど。あと音声が iPhone から流れている問題は依然としてあるけど。

noraworld commented 1 year ago

翌日、Raspberry Pi の 3.5 mm ステレオミニプラグにケーブルをつなぎ送信機側の Bluetooth トランスミッターと接続して AUX モードにしたら音声が流れるようになった。ただし最初は全く音声が聞こえなくて、alsamixer を使って音量を上げたりすることで聞こえるようになった。

もともと 3.5 mm ステレオミニプラグだと小さい音が消えてしまう問題があることを数年以上前に経験しているのでそれが影響していたのだろう。

noraworld commented 1 year ago

ただ、予想していなかったのは、いわゆる『ちゃんとした音声』じゃないと再生されない。たとえば英単語の音声のように、一瞬しか再生されない、というよりは音声データとして認識されないような音声はそのまま iPhone から音が出てしまう。これが昨日言っていた現象だろう。うーむ、これが使えないとなるとちょっと実用的じゃないな……。

noraworld commented 1 year ago

あと音がめちゃくちゃ遅延している。これはトラブルシューティングにあったので調整次第で直せるかもしれない。

noraworld commented 1 year ago

Mac と iPhone を同時に接続できないのも問題かもしれない。片方で接続されていて音声が再生されていると、もう片方で接続しようとしたときにエラーになる。ただこれはそういう仕様なのだろうと思う。

今使っているのは Classic AirPlay で、AirPlay 2 にすれば改善されるかも?

https://www.phileweb.com/review/column/201904/03/692.html#:~:text=%E4%BB%A5%E5%89%8D%E3%81%AEAirPlay%E3%81%AF%E3%80%81iPhone,%E3%81%AE%E9%96%A2%E4%BF%82%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82

noraworld commented 1 year ago

いや、「同時再生」っていうのは、たとえば 1 台の iPhone から複数の AirPlay 2 対応デバイスに同時に音を出力できる、って意味なのか。逆は無理なのかな。