iOS
おうちハック
homekit
homebridge

Webカメラを使ってiOS ホームアプリで監視する

More than 1 year has passed since last update.


はじめに

おうちにカメラを安くで仕掛けてiOSで監視したい。

iOSを監視(モードに)したいならこちらです。

しかし、Homeの対応製品は高かった。

ならば非公式で作ってやれ


注意事項

試しに構築した手順のため、セキュリティについてはノーガードポリシーです。

継続して利用する場合は、適当に対策してください。


準備したもの

材料名
数量
備考

Linux機
1台
今回はお試しのため、VirtualBoxにCentOS7.3
実運用の場合はRaspberry Piがいいのかもしれない

Webカメラ
1個
V4Lに対応というか、ffmpegで取り込みできるもの。
RTSPに対応したネットワークカメラでもいい。というか本来はそっちを想定している様子
適当に安かったものを買ってきた。UVC対応なら確実なのか。

Apple TVかiPad
1個
実際に見るデバイス以外に、外から使う場合は必須。これがホームハブとなって外からのアクセスを良しなに仲介してくれる


手順


インストール

お試しなので「selinux=0」と習慣で「net.ifnames=0」でminimalをインストール

アドレスはDHCP、ホスト名は「homebridge」に。実運用時は適当に。

面倒なのでrootでやってます。実運用時は適当に。

とりあえずOSを入れてカメラをつなぐ。

VBoxで使うときにWebカメラでなくUSBデバイスでやって悩んだのはさておき、動作確認は後ほど行う。

後ほどmacアドレスを使うのでコピっておく。


パッケージ追加

homebridgeの公式手順にある程度従いながら勝手なことをやっていく。


EPELリポの追加とパッケージ最新化

「nss-mdns」が必須であるかどうかわからぬが、入れるためにepelを入れる。

[root@homebridge ~]# yum -y install epel-release && yum -y update

適当に再起動


mDNS系の導入と動作確認

avahiは依存で入ってくれる。

[root@homebridge ~]# yum -y install nss-mdns avahi-compat-libdns_sd-devel

[root@homebridge ~]# systemctl start avahi-daemon
[root@homebridge ~]# ping -c 4 homebridge.local
PING homebridge.local (192.168.0.1) 56(84) bytes of data.
64 bytes from homebridge (192.168.0.1): icmp_seq=1 ttl=64 time=0.023 ms
64 bytes from homebridge (192.168.0.1): icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from homebridge (192.168.0.1): icmp_seq=3 ttl=64 time=0.032 ms
64 bytes from homebridge (192.168.0.1): icmp_seq=4 ttl=64 time=0.037 ms

--- homebridge.local ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 0.023/0.034/0.046/0.010 ms


Webカメラの確認

[root@homebridge ~]# yum -y install v4l-utils

[root@homebridge ~]# v4l2-ctl --list-devices
VirtualBox Webcam - UCAM-C0220F (usb-0000:00:06.0-1):
/dev/video0


カメラの仕様

[root@homebridge ~]# v4l2-ctl --list-formats

ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : MJPEG
[root@homebridge ~]# v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : MJPEG
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 800x600
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1280x1024
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1600x1200
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 352x288
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 320x240
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 176x144
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 160x120
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)

※VBox経由なのでmjpegになっている様子。実機接続だとrawだった気がします。

800x600以上の解像度で30fpsで取れないのも微妙ですが今回はお試しだし、妥協。

UVCでH264でFHDで30fpsでHDRで安いカメラは無いものか。ああ、高い。


カメラの設定

[root@homebridge ~]# v4l2-ctl -d 0 --set-fmt-video=width=1280,height=720 --set-parm=10

Frame rate set to 10.000 fps

4:3だと配信時に上下が切り取られますので、16:9っぽい解像度に。

細かい設定はここから辿るかググるといいかもしれない。


ffpmegの導入と撮影テスト

ffpmegはビルドした方がHWエンコができていいかもしれませんが、お試しだし面倒なのでビルド済みを入れます。

[root@homebridge ~]# curl -LO https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-64bit-static.tar.xz

[root@homebridge ~]# tar xvf ffmpeg-git-64bit-static.tar.xz
[root@homebridge ~]# cd ffmpeg-git-yyyymmdd-64bit-static/
[root@homebridge ffmpeg-git-yyyymmdd-64bit-static]# cp ffmpeg ffprobe ffserver /usr/local/bin/.
[root@homebridge ffmpeg-git-yyyymmdd-64bit-static]# cd
[root@homebridge ~]# ffmpeg -i /dev/video0 -t 00:00:10 out.mp4
ffmpeg version N-89208-g8b62647a5f-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 6.4.0 (Debian 6.4.0-10) 20171112
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg
libavutil 56. 2.100 / 56. 2.100
libavcodec 58. 3.105 / 58. 3.105
libavformat 58. 2.102 / 58. 2.102
libavdevice 58. 0.100 / 58. 0.100
libavfilter 7. 2.102 / 7. 2.102
libswscale 5. 0.101 / 5. 0.101
libswresample 3. 0.101 / 3. 0.101
libpostproc 55. 0.100 / 55. 0.100
[mjpeg @ 0x53e4780] EOI missing, emulating
Input #0, video4linux2,v4l2, from '/dev/video0':
Duration: N/A, start: 67101.668689, bitrate: N/A
Stream #0:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 1280x720 [SAR 1:1 DAR 16:9], 10 fps, 10 tbr, 1000k tbn, 1000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (mjpeg (native) -> h264 (libx264))
Press [q] to stop, [?] for help
(以下省略)

録画された「out.mp4」を取ってきて取れているか確認します。


homebridgeとプラグインの導入

[root@homebridge ~]# yum -y install make gcc gcc-c++ npm

(中略)
[root@homebridge ~]# npm install -g homebridge homebridge-camera-ffmpeg


homebridgeの仮起動

設定フォルダの作成と、とりあえず動作確認のために手動で起動

[root@homebridge ~]# homebridge

*** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node>
*** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister>
[2017/11/23 18:03:57] Loaded plugin: homebridge-camera-ffmpeg
[2017/11/23 18:03:57] Registering platform 'homebridge-camera-ffmpeg.Camera-ffmpeg'
[2017/11/23 18:03:57] ---
[2017/11/23 18:03:57] config.json (/root/.homebridge/config.json) not found.
Load homebridge-camera-ffmpeg.Camera-ffmpeg
(中略)
[2017/11/23 18:03:57] Homebridge is running on port 39877.

(Ctrl+Cで終了)
^C[2017/11/23 18:03:59] Got SIGINT, shutting down Homebridge...
[root@homebridge ~]#

色々怒られるが前半は気にしない

「Loaded plugin: homebridge-camera-ffmpeg」と「config.json (/root/.homebridge/config.json) not found.」が出ていればいい。


homebridgeの設定ファイル

サンプルをコピーして設定を書く。

設定ファイルの置場所は、homebridgeを起動するユーザのルート基準

[root@homebridge ~]# cp /usr/lib/node_modules/homebridge/config-sample.json ~/.homebridge/config.json

[root@homebridge ~]# vi ~/.homebridge/config.json

変更箇所とか


項目名
値/備考

3
name
iOSに表示されるブリッジ名、とりあえず現状維持

4
username
NICのMACを大文字で

5
pin
iOSに登録時に用いる認証キー。「000-00-000」は登録時にエラーとなる。

9
Description
とりあえず値を消しておく

11~23
accessories
platforms
サンプルなので消して、カメラ用に書き換え


config.json

{

"bridge": {
"name": "Homebridge",
"username": "08:00:27:41:6D:56",
"port": 51826,
"pin": "123-45-678"
},
"description": "",
"platforms": [
{
"platform": "Camera-ffmpeg",
"cameras": [
{
"name": "サンプルカメラ",
"videoConfig": {
"source": "-re -i /dev/video0",
"stillImageSource": "-i /dev/video0 -v:c 1 -ss 1",
"maxStreams": 2,
"maxWidth": 1280,
"maxHeight": 720,
"maxFPS": 10,
"vcodec": "libx264"
}
}
]
}
]
}

ハードウェアエンコを使うのであればvcodecを適当にいじる。「h264_omx」とか「h264_nvenc」とか。

H264対応のカメラなら「copy」で軽くできるのか。

「stillImageSource」は一覧画面(最初に出した画面)に表示される画像の出力設定。Wi-Fiで10秒、3G/4Gで30秒ごとぐらいに更新される。Webカメラ直結の場合、即撮影は真っ暗になるので、「-SS 1」で少し遅延を入れている。


homebridge起動

[root@homebridge ~]# homebridge

(中略)
[2017/11/23 18:38:11] Homebridge is running on port 51826.
[2017/11/23 18:38:11] サンプルカメラ is running on port 43430.

作ったカメラの名前とポートが出てくれば良い。


iOS側の設定

ブリッジとカメラが別機器として出てくるので、いきなりQRを読ませるとブリッジしか登録されない。

登録手順


「コードがないか、スキャンできませんか?」をタップ


設定したカメラがここで出てきているので、それをタップ


認定されていないが気にしない


ここでQRを読ませるか、pinを手入力


完了


最後に

このプラグインの公式サイトでは、RTSPで読みに行くサンプルとなっている。

また、起動後にiOSでカメラを登録して視聴すると

Snapshot -i /dev/video0 -v:c 1 -ss 1 -t 1 -s 480x270 -f image2 -

-re -i /dev/video0 -threads 0 -vcodec libx264 -an -pix_fmt yuv420p -r 10 -f rawvideo -tune zerolatency -vf scale=1280:720 -b:v 299k -bufsize 299k -payload_type 99 -ssrc 1 -f rtp -srtp_out_suite AES_CM_128_HMAC_SHA1_80 -srtp_out_params usQEf+DVAKfu+wfhrC2SpfueUkpDlZfgnO+2EhXt srtp://192.168.0.2:54828?rtcpport=54828&localrtcpport=54828&pkt_size=1378

とログが出るが、実態はffmpegで処理をしている。

ライブ視聴時はiOSデバイスに直接、外からの場合はApple TVかiPadに対してSRTPでデータを送り付けている。

ffmpegでの処理なので、RTSPに対応したカメラや、他の配信システムとか、とにかくffmpegで対応できればいい様子。

最初は「/dev/video0 → ffmpeg → ffserver → homebridge」と考えたが、しょっぱなからffmpegを使っているなら直でいいやとやっちまっています。

それに前者だと撮りっぱなしのLED点きっぱなしになるので。

複数台かつ各所に設置するのであれば、LAN内ストリーミングをffmpegで取り込みか。


おまけ(たぶん自動起動)

[root@homebridge ~]# npm install -g pm2

[root@homebridge ~]# pm2 start /usr/bin/homebridge
[root@homebridge ~]# pm2 status 0
lqqqqqqqqqqqqwqqqqwqqqqqqwqqqqqqqwqqqqqqqqwqqqqqqqqqwqqqqqqqqwqqqqqwqqqqqqqqqqqwqqqqqqwqqqqqqqqqqk
x App name x id x mode x pid x status x restart x uptime x cpu x mem x user x watching x
tqqqqqqqqqqqqnqqqqnqqqqqqnqqqqqqqnqqqqqqqqnqqqqqqqqqnqqqqqqqqnqqqqqnqqqqqqqqqqqnqqqqqqnqqqqqqqqqqu
x homebridge x 0 x fork x 15053 x online x 1 x 5s x 0% x 53.3 MB x root x disabled x
mqqqqqqqqqqqqvqqqqvqqqqqqvqqqqqqqvqqqqqqqqvqqqqqqqqqvqqqqqqqqvqqqqqvqqqqqqqqqqqvqqqqqqvqqqqqqqqqqj
Use `pm2 show <id|name>` to get more details about an app
[root@homebridge ~]# pm2 save
[root@homebridge ~]# pm2 startup centos
(中略)
[root@homebridge ~]# systemctl enable pm2-root

2行目がもう少しマトモな方法がありそう。

再起動でカメラの設定が飛ぶ。暇なときに見直そう。