Scribble at 2021-02-02 14:57:43 Last modified: 2021-02-02 18:12:52

添付画像

さて、Raspberry Pi zero W に接続した USB のマイクから音を拾うまでは上手くいった。次は Raspberry Pi から別の機器に音声データを伝送する方法を検討しよう。探してみると、Wi-Fi を使う方法と Bluetooth を使う方法があり、Bluetooth はスマートフォンで受けようにも受けられるように作られていないとのことで、アプリケーションを探しても大半はスマートフォンで Bluetooth 対応のスピーカーを制御するようなものだけで、スマートフォンを逆に Bluetooth の受信側としてスピーカーにするという方法はない。

ということで、次は Raspberry Pi から音声データをストリーミングするという方法を探してみると、gstreamer というソフトウェアが使えるようだ。ただし、検索するとトップに出てくるのは大半が実際の手順を何も説明していない、俺ってこんなソフト使えるぜ的な下らない自慢話みたいな記事ばかりで、こういうのはたいてい実は全く使ったこともなくて公式サイトのドキュメントからコピペしたコマンドを書き並べているだけの「ハッカー」小僧や「ものづくり」エンジニア諸君だ。こういう連中が、あと20年くらいするとクライアント企業へ納品したソースコードを GitHub で公開して「オープンソース」だの「シェア」だの「集合知」だのと開き直ったりするのだろう。くわばら、くわばら。

また、海外の記事でも大半は gstreamer を使う必要など最初からない、GPIO(汎用入出力)ピンに対応した拡張ボードで音声をストリーミングするなんていう、幼稚園児でもできるような工作の話を書いているにすぎない。こういうのも、自覚があるのかないのかはともかくタイトルで釣っているだけのことだから、GPIO のボードを撮影した写真が見えた時点で即座にページを閉じたほうが時間の節約になる。

ということで、ここはオーソドックスな手法として昔から使われている ffmpeg を導入してみる。Raspberry Pi OS は Debian ベースなので、apt (apt-get) というパッケージ管理ツールを使う。これで ffmepg をスタンダードな手順でインストールしてから(パッケージの全体だと 700 MB くらいあるので、インストールには少し時間がかかる)、マイクの受信テストでも使って WAV 形式のファイルを出力するのに使った ALSA のオプションを付けて ffmpeg を起動すると、いちおうストリーミングで音声を配信し始めているようには見えるのだが、Windows のマシンに入れた VLC Media Player で rtc://192.168.1.26:4444 へアクセスしても「入力を開くことができません: VLCはMRL 'rtp://@192.168.1.26:4444'を開けません。詳細はログを確認してください。」となってしまう。これはパソコン側の ESET でファイアーウォールを停止しても結果は同じだった。もう少し手間をかけないといけないらしい。それはそうと、「詳細はログを確認」とあるが、そもそも VLC Media Player のログなんてどこにあるのか。インストール・フォルダにも /logs なんて下層フォルダはないし、アプリケーションのメニューにもログに関する項目はない。(後から分かったのだが、そもそも設定でログを残すようにしておかないといけないらしい。場所も指定できるため、インストールフォルダ内にパーミションを設定してログを保存するようにした・・・のだが、ぜんぜんログ・ファイルなんて保存してないじゃないか。こういう細かいところでちゃんと動かないソフトって、ほんとうに扱いが面倒臭いよなぁ。)

それと、何日か Raspberry Pi へ ssh でアクセスしていると、どうもパワーセーブがいまだに働いているのか、コマンドを打ち込んでも翌日になると ssh サーバが反応しなくなる。調べてみて幾つか設定は変えてあるのだが、そもそも ssh サーバは USB のパワーセーブと関係ないのかもしれない(ssh は別に USB で接続している何かの上で動いているわけではないからだ)。ともかく、原因がよく分からないので、ssh で接続できないと headless にしている意味がないため、電源コードを引き抜いて挿し直すという、やや荒っぽい対処しかなくなる。

ffmpeg のドキュメントを読んでいて分かったことがあり、接続は解決した。rtp://@192.168.1.26:4444 のように設定する IP アドレスは配信側、つまり Raspberry Pi のサーバとしての IP アドレスを設定するわけではなく、送信先であるパソコン側の IP アドレスをターゲットとして設定するもののようだ。そこで、受け手のパソコンの IP アドレスである 192.168.1.2 に変更したら、何の問題もなく接続はできた。しかし、音が出ない。

[追記]

とかなんとか試行錯誤しているうちに、

# ffmpeg -ar 8000 -f alsa -i plughw:1,0 -acodec mp2 -b:a 64k -f rtp rtp://192.168.1.2:4444

という感じでプロセスを立ち上げてから、あらためて ESET のログを見ると、ファイアーウォールではなく「ホームネットワーク保護」で Raspberry Pi から 4444 番ポートのアクセスが遮断されていた。これを許可すると、すぐに音声が出るようになった。やれやれ・・・とは言え、実際にマイクに喋った後に目の前のスピーカーから音が出てくるまでに1秒くらいの遅延がある。幾つか ffmpeg のオプションを追加して delay を調整してみたが、あまり改善しないので、これはこれでよしとしておく。

こうして、実際にどうやって玄関のチャイムの音を受信するかはともかく、Raspberry Pi を玄関に置いてから、離れたパソコンの VLC Media Player でストリーミングの音声を受けてみないと、どれくらいチャイムの音が聞こえるか分からないので、Raspberry Pi を玄関に置いてから TeraTerm でアクセスしようとするのだが、今度は「ホストへ接続できません」というエラーが出て通信できない。ping も通らないため、そもそもネットワーク通信が確立していないのだろう。NURO のルータの真横に置いたのに、いったいなんなんだろう。電源コードをつなぎ直して、強制的に起動しなおすしかない・・・いや、電源コードをつなぎ直そうと思って玄関で暫く確認すると、そもそも電源ケーブルを挿しているタップの、ソケットごとの電源スイッチが入っていなかった・・・。

これで音声のストリーミングはテストできたのだが、いまのところあまり実用性は感じられない。理由の第一は、雑音が酷すぎて、スピーカーから常にこんな音が出ているのでは生活騒音でしかないからだ。そして第二は、マイクの拾っている音が予想外に小さくて(alsa で100%入力に設定してから、VLC Media Player で125%で再生してすら、雑音と大して変わらない大きさの音だ)、これを自分の部屋で聞いても分からない可能性がある。たとえばテレビを観ていたりゲームしているときは聞こえないかもしれない。更には、まだ Bluetooth での受信と再生を試していないので、実際に無線対応のスピーカーでどう聞こえるかが分からない。とりあえず、雑音や入力レベルの問題はマイクが安物すぎることにあるのだろうから、取り換えを検討しなくてはいけない。ただ、無線対応の Raspberry Pi の場合は、Wi-Fi や Bluetooth のチップが原因の場合もあるらしいので、かなり手間取るのかもしれない。コーデックやサンプリング・レートは、

ffmpeg -f alsa -i plughw:1,0 -acodec libmp3lame -b:a 256k -ar 44100 -f rtp rtp://192.168.1.2:4444

のように、かなり高品質にしてある(ロスレスのコーデックはエラーが出た)。これでもノイズはぜんぜん消えないので、マイク自体の性能と無線チップの影響があるのだろう。

  1. もっと新しいノート <<
  2. >> もっと古いノート

冒頭に戻る


※ 以下の SNS 共有ボタンは JavaScript を使っておらず、ボタンを押すまでは SNS サイトと全く通信しません。

Twitter Facebook