極めて限定的なシチュエーションなので、参考になる人が他にいるのか謎だが、
- GoPro (Hero 8 以上) で映した
- バイクの車載動画を
- Raspberry Pi を使って
- リアルタイムで Discord に流す
という環境を作る事があったので、そのときのメモ。
なお、タイトルでは "Discord" としているが、ブラウザから Webカメラを扱うものであれば YouTube Live, Zoom, Slack, Google Meet, Teams, Skype, Twitch などでも同様に使える。
また、バイクの車載動画を念頭に置いて構築したが、バイク固有の事情はないので、ライブ配信 VLOG 的な用途にも参考になるかもしれない。
背景
全国からバイクで集まってキャンプする、いわゆる「グループソロキャンプ」というモノに時々参加している。
それぞれバラバラにバイクで走行しているので、各々がリアルタイムで車載動画を共有して、一つにまとめたら面白いんじゃね?となったのが始まり。
普段から、走行中に Discord で通話状態にし、自宅のサーバー(便宜上サーバーといっているが、ただのPC)で録画・録音しているので、そこに車載映像流せばいいじゃんと考えた。
手っ取り早くは、スマホをくくりつけて Discord 配信すれば良いのだが、おそらく私の持っている安物スマホでは直射日光に耐えられないだろうし、せっかくならアクションカメラの広角映像で撮りたい。
ということで、画面割れした GoPro Hero 8 を安く調達してきて、なんとか車載で Discord にリアルタイム配信しようとした…というのが、今回の構築の背景だ。
環境設計
まずスマホで何とかする方法を検討したが、 Android 版の Discord で共有できるのはスマホ内蔵のカメラか画面のみであり、Webカメラの映像を配信することはできない。
USB Webカメラの映像を画面上に表示させて、それを Discord で画面共有する手もあるが、GoPro は直接 Webカメラになれない。
GoPro の公式アプリ (GoPro Quik) ではリアルタイム映像をスマホに映せるが、これを使うとスマホが GoPro 以外と通信できなくなり Discord に繋がらなくなるため、やりたいことを満たせない。
そこでスマホを使う方法は早々に諦め、 Raspberry Pi を活用する方針で構築を進めることにした。
端的に言えば、Raspberry Pi OS を入れた Raspberry Pi に GoPro を繋いで Webカメラとして認識させ、リモートデスクトップ (VNC) 経由でブラウザを操作し、Discord にアクセスして映像を流すという方法である。
思いついてから準備するまでの時間がなかったため、力業な方法になっているが、次回までにはもう少しスマートにしたい。
GoPro Webcam を Raspberry Pi で扱う
GoPro Hero 8 以上には GoPro Webcam という仕組みがある。
前述の通り GoPro 自身は直接 Web カメラになれないが、GoPro Webcam を使うとPC上に仮想Webカメラがインストールされ、そこに GoPro の映像が流し込まれる。
すると、ブラウザなどの別のアプリケーションから Webカメラとして扱えるようになる。
しかし、GoPro Webcam は Windows と Mac 向けにしか提供されておらず、 Linux 版が存在しない。
GoPro の仕様は全体的に開かれているため、第三者による Linux 版の実装が存在するだろうと探してみたところ、 やはり誰かが実装していた 。
なるほどねぇ…
GoPro 側で "GoPro Connect" を有効にして USB 接続すると、 GoPro 自身が USB NIC としてOSに認識され、 HTTP 経由で GoPro 側を操作したり、 UDP Stream で映像が取得できるようになるらしい。
これを ffmpeg にてエンコードしながら v4l2loopback で作成した仮想カメラに流し込んでいるようだ。
まぁ、詳しい仕組みはわからなくても使うことはできるので、こいつを使っていこう。
環境構築
ということで、 GoPro as WebCam on Linux (gopro_as_webcam_on_linux) を Raspberry Pi OS で使えるようにしていく。
手順は以下の通り。
-
Terminal を開いて、以下のコマンドで依存パッケージをインストールする
sudo apt install ffmpeg v4l2loopback-dkms curl vlc git
- Raspberry Pi OS 以外の場合、ディストリビューションによっては、
v4l2loopback-dkms
が提供されていないために v4l2loopback を自分でビルドしなくてはならない場合もある。 ただ、make
コマンド実行するだけなのでさほど難しくない。
- Raspberry Pi OS 以外の場合、ディストリビューションによっては、
-
以下のコマンドで、
gopro_as_webcam_on_linux
をインストールするgit clone https://github.com/jschmid1/gopro_as_webcam_on_linux cd ./gopro_as_webcam_on_linux/ sudo ./install.sh
-
Raspberry Pi OS では GoPro に繋がるネットワークデバイス名の自動取得がうまくいかないので、デバイス名パターンを調べる
-
以下のコマンドで、 GoPro as WebCam on Linux をサービスとして登録する
sudo tee /etc/systemd/system/gopro_webcam.service << 'EOF' > /dev/null [Unit] Description=GoPro Webcam start script After=network-online.target Wants=network-online.target systemd-networkd-wait-online.service [Service] ExecStartPre=/usr/bin/bash -c "sleep 5s;" ExecStart=/usr/local/sbin/gopro webcam --device usb0 --resolution 720 --fov wide --non-interactive --auto-start Restart=always RestartSec=10s [Install] WantedBy=multi-user.target EOF sudo systemctl enable gopro_webcam.service
--device usb0
の部分は、手順 (3) で調べたデバイス名に置き換える。- その他
--resolution
や--fov
などのオプションについては、goproコマンドのヘルプ を参照。
-
Raspberry Pi が GoPro に繋がるネットワークデバイス経由でインターネットに接続しようとして失敗しないようにする
- (引き続き GoPro が繋がっている状態で) ターミナル上で
nmcli connection
と実行し、DEVICE
列が手順 (3) で調べたものと同じ行のNAME
列の名前をメモる。
- 例えば上記の場合、
DEVICE
列がussb0
のものを探すとそのNAME
列はWired connection 2
となる
- 例えば上記の場合、
-
シェルで以下のコマンドを実行する
sudo nmcli connection modify "Wired connection 2" ipv4.never-default yes ipv6.never-default yes
"Wired connection 2"
の所は、前項で調べたNAME
列の値に置き換えて実行する
- (引き続き GoPro が繋がっている状態で) ターミナル上で
ここまでで準備完了だ。
試しに、ターミナルで sudo gopro webcam --user $USER --preview
と打って実行してみよう。
VLC が立ち上がり GoPro で映している映像がプレビューされれば、キチンと Raspberry Pi 側に GoPro が認識されていることが確認できる。
利用方法
さて、実際に GoPro を Webカメラ として使うには以下のように実行する。
-
"GoPro Connect モード" となっている GoPro を Raspberry Pi につなぎ、以下のコマンドを実行する
sudo systemctl start gopro_webcam.service sudo systemctl status gopro_webcam.service
- これらのコマンドを実行するシェルスクリプトファイルをデスクトップなどに置いておくと便利。
v4l2loopback is loaded!
と表示されていることを確認する
- あとはブラウザなどのツールから Web カメラとして GoPro のストリーミング映像を取り出す
基本的な使い方は以上だ。
バイクツーリングで使う場合
実際にバイク上で使う場合、外出先でこの操作を行う必要がある。
Raspberry Pi はモバイルバッテリーなどで動かし、スマホでテザリングさせてインターネットに接続するとしても、ディスプレイや操作用のキーボード・マウスなどまで携帯したくない。
そこで、スマホから Raspberry Pi にリモートでアクセスして操作すると良い。
ざっと簡単に2つほど方法を紹介しよう。
- Raspberry Pi Connect を使って、スマホのブラウザからアクセス
- Raspberry Pi で VNC を有効にして、テザリングしているスマホから RealVNC Viewer 等を使ってリモートアクセス
- スマホから Raspberry Pi のローカル IP アドレスを調べるには、 Network Analyzer の LAN Scan 等が使える。
ただし、スマホの機種によってはテザリング子機に割り当てるサブネットアドレス範囲が広すぎて、現実的な時間でスキャンしきれない可能性がある。
- スマホから Raspberry Pi のローカル IP アドレスを調べるには、 Network Analyzer の LAN Scan 等が使える。
そのほか
実際に使ってみた所感を雑多に書き連ねてみる。
同じことをする方への参考になれば。
- WEBCAM モードの GoPro HERO8 Black は USB から供給された電力を使わないため、連続撮影時間は GoPro バッテリーに依存してしまう
- micro SD にエンコードして保存しないせいか、持ちは長めではあった。
- Raspberry Pi 5 を使う場合、電源供給に使うモバイルバッテリーはかなり安定したモノを使わないと、すぐ電力不足で落ちてしまう
- cheero Power Deluxe CHE-094 の Type-C 出力だと安定したが、ほかの激安モバイルバッテリーだとダメだった。
- ファンを回さないと処理的にかなりキツい。 炎天下だとファン回してもキツいので、設置場所に悩む。
- Raspberry Pi 4 までならハードウェアエンコーダがチップに含まれているので、そちらの方が安定するかもしれない(試していないが)。
- GoPro 起動時に
gopro_webcam.service
立ち上げ、自動的にブラウザ操作して Discord のビデオ通話を ON にするくらい作り込んだ方が良いかもしれない- GoPro の電池切れや不安定さで途切れることがあり、再起動することがまぁまぁあるので。
- GoPro as WebCam on Linux の
gopro
コマンドは、デーモン化しなくても Webカメラ を有効にできるのだが、 VNC で遠隔操作から有効にした場合、デーモン化しとかないと VNC 切ったときに映像を継続して流し続けられない - 当初、 Raspberry Pi OS ではなく Ubuntu で構築しようとした。
しかし、 Ubuntu だとヘッドレス起動でリモートデスクトップさせたり、リモートデスクトップ切断後もブラウザのプロセスを維持させることが困難だったので、 Raspberry Pi OS に切り替えた経緯がある。