Smart HomeをDIYする

Apple HomeKit は対応製品が少なくて高価なのでHomebridgeでがんばります

FFmpegを導入してHomeKitからwebカメラを使う

FFmpegは動画情報を変換したり転送するツールです。セキュリティカメラやビデオドアフォンを利用する上で必要になる場合が多いです。特にHomebridgeのプラグインなどのようにオープンソースのプロジェクトではほとんどFFmpegが利用されます。今回はMacUbuntuFFmpegをインストールして動作確認し、UbuntuのHomebridgeからUSBカメラを使ってみました。

Macにインストール

FFmpegって動画ファイル変換ソフトかと思ってたのですが、とても多機能なツールだったんですね。まずは手近なMacで使ってみました。MacFFmpegを使うためにはHomebrewを使います。Homebrewをインストールした後で、以下のコマンドでFFmpegをインストールできます。

% brew install ffmpeg

動作確認のためにバージョンを表示させました。

% ffmpeg -version

USBカメラ映像をMacで見る

次に、Macに接続された標準的なUSBカメラの映像を、FFmpegを使ってチェックします。Mac標準のPhoto Boothなどのアプリで確認できる映像をみようと思います。UVC(USB Video Class)という規格に対応したUSBカメラなら、Macの色々なアプリケーション、例えばMac標準のPhoto Boothなどで利用できます。Webカメラのほとんどが、またデジカメも一部がUVC規格です。試しに$15くらいのUSB接続顕微鏡を使ってみました。

検索してみると、macOSでは動画・音声の入出力に、avfoundationというフレームワークを使うようです。以下のコマンドでサポートされたデバイス名の一覧がわかるようです。

% ffmpeg -f avfoundation -list_devices true -i ""
[AVFoundation indev @ 0x7fd644104ec0] AVFoundation video devices:
[AVFoundation indev @ 0x7fd644104ec0] [0] USB2.0 Digital Camera
[AVFoundation indev @ 0x7fd644104ec0] [1] Capture screen 0
[AVFoundation indev @ 0x7fd644104ec0] AVFoundation audio devices:
[AVFoundation indev @ 0x7fd644104ec0] [0] USB2.0 Digital Camera
[AVFoundation indev @ 0x7fd644104ec0] [1] Built-in Input

接続したデバイスの名前は"USB2.0 Digital Camera"のようです。これがわかれば、ffmpegコマンドで動画データを扱えます。まずは、ffmpegコマンドの仲間の、ffplayというコマンドを使ってみます。ウィンドウが開いて動画が見られるので動作確認に適してます。

% ffplay -pixel_format uyvy422 -framerate 25 -f avfoundation -i "USB2.0 Digital Camera"

これで画像が出ました。写っているのは100円玉です。上記のコマンド例では、pixel_formatとframerateオプションを追加してます。これらのオプションを指定しないデフォルト設定ではエラーが出たので、エラーメッセージに合わせてこの2つを指定しました。

ffmpegコマンドは、基本的にはビデオフォーマット変換アプリなので、USBカメラから得た動画を、ファイルに保存します。以下のコマンドでQuickTimeで開けるファイルが完成します。キーボードのQを押すと動画取り込みを終了します。

% ffmpeg -pixel_format uyvy422 -framerate 25 -f avfoundation -i "USB2.0 Digital Camera" -pix_fmt yuv420p output2.mp4

結果のファイルをダブルクリックするとQuickTime Playerがファイルを開いてくれます。最後のパラメータはファイル名です。その前にpixel_formatを指定しています。こちらの指定は、出力フォーマットの指定です。これがなくても動画ファイルは作成されますが、その場合、QuickTime Playerでは再生できません。VLCなどの動作再生アプリなら開けます。QuickTime Plaayerで再生するためには、yuv420pに変換しておく必要がありました。

USBカメラ映像をUbuntuで見る

次に、Homebridgeを動かしているUbuntuマシンでもFFmpegを動かします。こちらは

apt install ffmpeg

コマンドでインストールしました。ちなみにRaspberry Piでも同様にffmpegをインストールできました。ここではUbuntuマシンで説明しますが、Raspberry Piでも同様です。

UbuntuマシンにUSBカメラを接続すると、/dev/video0に接続されました。これをffmpegコマンドの入力に指定します。ただ、/dev/video0のユーザ:グループは、root:videoになっていて、それ以外のユーザは読み込みが許可されていませんので、変更する必要があります。今回は、自分のアカウント(以下の例ではfoo)と、Homebridgeを実行するときに使用されるアカウントhomebridgeを、videoグループに割り当てました。/etc/groupの該当する行を以下のように書き換えます。

video:x:44:foo,homebridge

こうして/dev/video0を読める設定にしておけば、以下のコマンドでUSBカメラの映像を動画ファイルに保存することができます。

% ffmpeg -i /dev/video0 -pix_fmt yuv420p output.mp4

UbuntuにもGUI環境をインストールしておけばffplayコマンドで確認できたのかもしれません。しかしサーバーとしてGUIなしで動かしているので、ファイルを転送してMacで動作確認しました。これでFFmpeg動作を確認できました。

HomebridgeでUSBカメラを使う

Apple HomeKitでは、セキュリティカメラやビデオドアフォン(英語ではビデオドアベルというらしいです)の映像を利用できます。HomebridgeではFFmpegで取得できる動画データを、HomeKitで利用できるように提供するプラグインが用意されています。その中の一つ、Homebridge Camera FFmpegを使用しました。

github.com

これをインストールして、ffmpegの設定をすると、コンフィグファイルに以下の記述が追記されました。名前はMicroscopeとしました。

{
    "name": "Camera FFmpeg",
    "cameras": [
        {
            "name": "Microscope",
            "videoConfig": {
                "source": "-i /dev/video0"
            }
        }
    ],
    "platform": "Camera-ffmpeg"
}

その結果、iPhoneMacのホーム.appの画面に、以下のように動画が現れます。

この画面には、最後に取得された動画が静止画として表示されてます。この画像をクリックすると、全画面表示になり、現在の動画が表示されます。

以上はUbuntuでHomebridgeを動かしている場合です。Raspberry Piへのインストール方法が以下のサイトで説明されていましたが、こちらも同じような手順でした。github.crookster.org

エラーへの対応

以上で、大体すんなり動くのですが、たまにエラーが出て、ライブ映像が表示できなくなる場合がありました。Homebridgeのwebページのログに、「デバイスがビジーである」というようなメッセージも出ます。/dev/video0が、他のプロセスに使用されていて使えないという意味です。このような場合は、fuserコマンドをルート権限で使用すると、様子がわかります。

$ sudo fuser /dev/video0
/dev/video0:          1257m

ライブ映像を表示していない時は、video0は誰も使用していないはずなのですが、プロセスIDが1257番のプロセスが使用し続けているようです。psコマンドで調べると、

$ ps -aux | grep 1257
homebri+    1257 99.5  0.1  66008  8236 ?        R    17:49   2:44 /var/lib/homebridge/node_modules/homebridge-camera-ffmpeg/node_modules/ffmpeg-for-homebridge/ffmpeg -i /dev/video0 -frames:v 1 -f image2 - -hide_banner -loglevel error

homebridgeが使っているようでした。試行錯誤して、動画が表示されなくて、homebridgeを再起動したりした場合に、発行済みのFFmpegプロセスがそのまま残ってしまうようです。この場合は、sudo kill 1257で中断することで正常に動くようになりました。

まとめ

USB接続カメラからの動画データをFFmpegを使って取り込み、HomeKitでカメラ画像として使用できることを確認しました。今回使用したHomebridge Camera FFmpegプラグインは、機能豊富で、MQTTブローカーとの連携機能もあります。MQTT経由でモーションセンサや呼び鈴ボタンのイベントを受け付けることができるので、センサ付きセキュリティカメラやビデオドアフォンとして機能させることができます。Homebridgeサーバに安価なUSBカメラを取り付けるだけでサーバ周辺の映像を世界中から確認できるのは便利かと思いました。

ただ、エラーで止まってしまったときの対応が面倒なので、あまり実用的ではないかもしれません。RTSPプロトコルを使ったIPカメラの方が使いやすいかと思います。そのうち試したいと思ってます。