余っているスマートフォンを、ペットカメラ/見守りカメラにする。
スマホをカメラとして部屋に置き、PCや別のスマホのブラウザから様子を見る。 カメラのON/OFFも手元から操作できる。外出先からも見られる。
- 見る側に専用アプリは要らない(ブラウザだけ)
- カメラ側にも専用アプリは要らない(ブラウザでページを開くだけ)
- 映像はサーバを経由せず端末同士が直接やりとりするので、遅延が小さく、PCの負荷もほぼゼロ
- 無料。クラウドサービスも契約も不要
| ライブ映像 | 遅延0.1〜0.3秒。1080pまで対応 |
| 音声 | 部屋の音を一緒に送る(既定はオフ) |
| 遠隔ON/OFF | 手元からカメラを止める・動かす |
| スナップショット | 見ている画面を静止画で保存 |
| 呼び出し音 | カメラ端末のスピーカーから音を鳴らす(3種類・音量2段階・手元で試聴可) |
| 画質切替 | 標準 / 省電力 |
| カメラ切替 | 背面 / 前面 |
| 画面消灯 | カメラ端末の画面を消したまま配信を続ける |
| 自動復帰 | 映像が止まっても10秒ほどで自動的につなぎ直す |
| 自動スタンバイ | 誰も見ていないときはカメラを止めて節電する |
| ズーム | カメラ側で寄せるので、拡大しても粗くならない(対応機種のみ) |
| ライト | カメラ端末のLEDライトを遠隔で点ける(対応機種のみ・3分で自動消灯) |
| 自動起動 | パソコンのログイン時に自動で立ち上げる |
| 見張り | トイレやエサ場など、決めた場所に猫がいるかを見る |
| 自動録画 | 見張りに引っかかったら、数秒前から遡って記録しPCへ保存する |
| 外出先から | Tailscale を使って、自宅を公開せずに外から見る |
- カメラにするスマートフォン(Android推奨。Chromeが動けばよい)
- PC(Windows / macOS / Linux)。サーバ役。動かしている間だけ映像を見られる
- 両方が同じWi-Fiにつながっていること
Androidを推奨するのは、iPhoneをカメラにすると画面ロックやアプリ切替で カメラが止まる制約が強いため。見る側はiPhoneでも問題ない。
ClaudeやChatGPTを使っているなら、AI_SETUP.md をAIに読ませると
対話しながら導入できる。つまずきやすい点と、やってはいけないこと
(PINを外に出さない等)も書いてあるので、AIがそこを外さない。
https://github.com/Doushimasho/petcam の AI_SETUP.md を読んで、
ペットカメラの導入を手伝ってください。
start.bat をダブルクリックするだけ。
必要な部品は自動で入る。Pythonが無ければその場で案内が出る。
pip install -r requirements.txt
python server.pyPython 3.10以上が要る。入るのは Flask simple-websocket cryptography の3つ。
黒い画面に、PIN と アクセスするアドレス が表示される。
============================================================
PET CAMERA サーバを起動しました
============================================================
PIN : 123456
スマホ(カメラ): https://192.168.x.x:8443/camera
PC(視聴) : https://192.168.x.x:8443/viewer
============================================================
この黒い画面は閉じない。 閉じるとカメラも止まる。
PINは初回起動時にランダムで作られ、config.json に保存される。
コードには書かれていない。変えたいときは config.json の pin を
書き換えて起動し直す(何桁でもよい)。
初回はOSがネットワークの許可を聞いてくる。 Windowsなら 「プライベートネットワーク」にチェックを入れて許可。 許可しないとスマホからPCに届かない。
- スマホをPCと同じWi-Fiにつなぐ(ゲストネットワークは不可。端末同士の通信が遮断されている)
- Chromeで、表示されたアドレスの
/cameraを開く - 「接続はプライベートではありません」と警告が出る → 詳細設定 → 安全でないページに移動 (自分のPCが発行した証明書なので、この警告は想定どおり。 外出先対応をすると出なくなる)
- PINを入力する
- CAMERA ON を押して、カメラの使用を許可する
- スマホをペットの見える場所に置き、電源につなぐ
カメラの許可は最初の1回だけ。 以後は見る側から遠隔でON/OFFできる。
常設で問題になるのは発熱と電池。効くものだけ挙げる。
| 設定 | 理由 |
|---|---|
| 電源につなぐ | 必須 |
| 画面の明るさを最低にする | 発熱と電力の主因 |
| ケースを外す・直射日光を避ける | 放熱 |
| 画面の自動回転をオフ | 置き方が変わって映像が回るのを防ぐ |
| 通知・着信を切る | 着信画面がページを覆うとカメラが止まる |
| Chromeのタブを1つだけにする | 他タブに切り替わると止まる |
PCやスマホのブラウザで /viewer を開き、同じPINを入力する。
何台からでも同時に見られる。
同じWi-Fiの外から見たい場合。自宅をインターネットに公開せずに済む方法を使う。
Tailscale は、自分の端末同士だけを繋ぐ無料のサービス。 自宅のネットワークを外部に晒さない。
- PC、カメラのスマホ、見る端末の3つにTailscaleを入れ、同じアカウントでログインする
- 管理画面の DNS → HTTPS Certificates を有効にする
- サーバを起動し直す
これだけで、サーバが自動的に正式なHTTPS証明書を取得し、
https://端末名.ネットワーク名.ts.net:8443/ というアドレスで
家でも外でも同じURL、証明書の警告なしで使えるようになる。
証明書は90日で切れるが、期限が近づくと自動で取り直す。 サーバを止める必要はない。
-
カメラのスマホにもTailscaleを入れること。 入れ忘れると、 状態表示は出るのに映像だけ来ない、という状態になる
-
Androidでは Tailscaleをバッテリー最適化の対象外にする (設定 → アプリ → Tailscale → バッテリー → 制限なし)。 そうしないとOSがVPNを勝手に切る
-
見る側の端末にもTailscaleが要る。家族に見せるなら招待リンクを送る。 作り方は次のとおり(2分):
- login.tailscale.com を開く
- 左メニューの Users
- Invite external users を押す
- Copy invite link のタブを選ぶ
- 権限(user role)は Member でよい
- Generate & copy invite link を押す
相手側に事前準備は要らない。 TailscaleにはID/パスワードが存在せず、 Apple・Google・Microsoft・GitHub のいずれか、すでに持っているアカウントで サインインすると、その場で登録まで完了する。 iPhoneユーザーなら Apple ID をそのまま使える。 こちらのアカウント情報を渡す必要はない。
docs/iphone_setup_template.mdを一緒に渡すと、相手側の手順が済む。
| 表示 | 意味 |
|---|---|
| DEVICE ONLINE | カメラ端末がサーバに繋がっている |
| DEVICE OFFLINE | カメラ端末が切れている |
| CAMERA ON | カメラが動いていて映像が流れている |
| CAMERA OFF | カメラは止まっている |
| CAMERA ERROR | カメラを起動できなかった。理由が画面に出る |
DEVICE ONLINE なのに映像が来ない場合、カメラ端末までは繋がっているが 映像の直接接続だけが失敗している。外出先からのときは 「カメラのスマホがTailscaleに入っていない」が最も多い原因。
見る側は、映像が実際に進んでいるかを2秒ごとに見張っている。 8秒進まなければ壊れたと判断し、カメラ側へ作り直しを頼む。 10秒ほどで自動的に戻るので、ページを開き直す必要はない。
通信が一瞬切れただけで映像そのものが生きている場合は、あえて作り直さない。
見る側の「♪ 音を鳴らす」を押すと、カメラを置いた端末のスピーカーから音が出る。 ペットや子どもの反応を見たいときに使う。
| 音 | 内容 | 音域 / 細かさ |
|---|---|---|
| チャイム | やわらかい下降3音を2回。最後を長く響かせる。既定 | 高め / ふつう |
| 呼びかけ | 同じ高さを速く3回。気づいてほしいとき | 中 / 細かい |
| メロディ | 上って下りて最後に高く伸びる5音 | 広い / ゆるやか |
3つは音の高さと間隔の細かさをずらしてあるので、鳴った音で区別できる。
音量は 小 / 大 の2段階(大はかなり大きい)。音の種類も音量も見る側で選ぶ(カメラ端末を 触りに行く必要はない)。選択は端末に記憶される。
音の種類を選ぶと、その場で手元で試聴できる。 向こうの部屋に鳴らしてみるまで音が分からない、という状態にはしていない。
音源ファイルは持たず、その場で合成している(static/sounds.js)。
立ち上がりと消え際をなだらかにしてあるので、同じ音量でも驚かせにくい。
連打しても1.5秒に1回までしか鳴らない。相手のいる部屋なので、鳴らしすぎは害になる。
音が重なっても割れないよう、出口で軽く圧縮をかけている。
-
「カメラ端末が古い画面です」と出たら、カメラ端末のページを再読み込みする。 カメラ側の画面が古いと、新しく増えた音を知らない。 知らない音を受け取っても別の音に差し替えたりはしない(選んだ音と違う音が 鳴るのが、いちばん原因の分かりにくい壊れ方になるため)
-
カメラ端末の音量が下がっていないか。 メディア音量を上げておくこと
-
「カメラ端末の画面を一度タップしてください」と出た場合、 ブラウザが「一度も触られていないページ」に音を出させない決まりのため。 カメラ端末の画面を1回タップすれば、以後は遠隔で鳴らせる (設置時に CAMERA ON を押していれば、通常この状態にはならない)
カメラ端末は、触らずに1分たつと画面が真っ暗になる。配信は止まらない。 映像のプレビューを描き続けるのが発熱と電力の主因なので、描画だけをやめている。 タップで戻る。すぐ消したいときは「画面を消す」ボタン。
消えている間も小さく「● 配信中」と出る。
誰も見ていない状態が1分続くと、カメラを止める。 見る画面を開くと1〜3秒で自動的に起き上がる。 既定で有効。見る側の画面から切り替えられる。
「見ている」の判定は、画面が手前にあるかどうかで行う。 ページを開いたまま裏に回している場合は、見ていない扱いになる。
止めるまでの時間は config.json の standby_after_sec(既定60秒)で変えられる。
スタンバイ中も画面のスリープ止めは解除しない。 画面が消えるとページごと止められ、手元から起こせなくなるため。 撮影・圧縮・描画を止めるだけでも、消費の大部分は落ちる。
見る側の −/リセット/+ でカメラ側のズームを操作する。
カメラ側で寄せるので、見る側で引き伸ばすより映像が精細になる。
対応しているかは機種による。非対応なら、その旨が画面に出る。
見る側の 💡 ライトをつける で、カメラ端末のLEDライト(背面のフラッシュ)を点ける。
主な用途は遠くから猫の気を引くこと。点けると顔を上げたり目を向けたりするので、 「ちゃんと生きて動いている」を旅行先から確かめられる。音を鳴らすのと同じ狙いだが、 音を出せない時間帯でも使える。暗い部屋の様子を一瞬だけ確かめる用途にも使える。
- 3分で自動的に消える。 レンズのすぐ横で光るので熱を持つ。消し忘れると端末が温まる
- カメラを止めると同時に消える
- 対応しているかは機種による。非対応ならボタン自体を出さない
- 近距離の照明なので、ケージのように近いものはよく写るが、部屋全体は明るくならない
部屋の照明そのものを点けたい場合は、この機能ではなくスマートプラグや スマートリモコン(Nature Remo など)を使う。本体には組み込んでいない。
| 解像度 | フレームレート | |
|---|---|---|
| 標準 | 1280×720 | 24fps |
| 省電力 | 640×480 | 15fps |
長時間の見守りなら省電力を推奨。選んだ設定は端末に記憶される。
カメラ端末の電池残量と充電状況は、見る側の画面に出る。 充電が外れていても気づけないのが常設の弱点なので、常に見えるようにしてある。
効く順に並べると次のとおり。
| 手当て | 効き方 |
|---|---|
| 自動スタンバイ | 誰も見ていないときカメラごと止める。いちばん大きい |
| 見ていない相手へは送らない | 画面を裏に回している相手への送信を止める。映像は相手ごとに別々に圧縮しているので、圧縮の手間も電波もまるごと減る |
| 見張り中の自動減量 | 見張りだけのときは 320×240 / 5fps まで落とす。見に来たら戻す |
| 送信量の上限 | 標準1.2Mbps / 省電力500kbps / 見張り150kbps。決めないとブラウザが勝手に高く取る |
| 画面消灯 | 映像の描画をやめる(1分無操作で自動)。消していても見張りは動く |
| 省電力画質 | 640×480 / 15fps |
| 画面の明るさを最低にする | 端末側の設定。効果は大きい |
送信を止めた相手が見に戻ったとき、粗い絵から徐々に戻るのを避けるため、 帯域が足りないときは解像度ではなくコマ数を落とす設定にしてある。
見る側の画面に、カメラ端末の電池残量と充電状況が出る。 設定を変えて1時間ほど放置し、減り方を比べれば効果が分かる。
画面を点けたままにする必要がある。 ブラウザで動かしている以上、画面が消えるとページごと止められ、 カメラも遠隔操作も止まる。この分の消費は、この作りでは避けられない。
本当に電池を切り詰めたい場合は、カメラ側を Android アプリにするしかない。 アプリなら画面を消したまま動かせる。 そのときもサーバと見る側の画面はそのまま使える。
充電器を疑うこと。 消費が 3〜4W あるので、 5V/1A(5W)の古い充電器では追いつかず、つないでいるのに減っていく。 5V/2A 以上のものに替えると解決することが多い。
install_autostart.bat をダブルクリックする。それだけ。
管理者の許可を求める画面が出たら「はい」を押す。
- パソコンの電源を入れれば、ログインしなくても立ち上がる
- Windows Update の再起動のあとも、自分で復帰する
- 黒い画面は出ない
- 落ちても1分後に起動し直す
ログオンを待たずに動かすため、SYSTEM という権限で登録する。 パスワードを保存せずに済み、留守中の再起動でも確実に戻ってくる。
status.bat に「設定済み(PCの起動時 / SYSTEM)」と出れば正しい。
「ログオン時」と出ている場合は古い設定なので、登録し直すこと。
precheck.bat をダブルクリックすると、留守中に止まる原因をまとめて確かめられる。
- サーバが動いているか
- 自動起動が「PCの起動時」になっているか
- 高速スタートアップが無効か(有効だと、電源を入れ直しても起動しないことがある)
- スリープしない設定か
- 証明書の残り日数
- Tailscale がログインしていなくても繋がる設定か
- Tailscale に必要な端末が揃っているか
[NG] が出たら、その下に対処が書いてある。
Windowsの Tailscale は、既定では「誰かがログインしている間」しか繋がらない。 そのままだと、留守中に再起動したとき、サーバは動いているのに カメラ端末から到達できない。サーバ側を疑っても原因が見つからない、 いちばん分かりにくい壊れ方になる。
次を一度だけ実行する(管理者権限は不要)。
"C:\Program Files\Tailscale ailscale.exe" set --unattended=true
タスクトレイの Tailscale アイコン → Preferences → Run unattended でも同じ。
見る画面の「設定を開く」→「パソコンの電源」から操作できる。
| 使いどころ | |
|---|---|
| 再起動する | 動きが怪しいとき。2〜3分で自分で戻ってくる。プラグは要らない |
| 電源を切る | 長期間使わないとき。スマートプラグで入れ直すまで戻らない |
押し間違いでカメラが止まると帰宅まで戻せないので、 二度押しで実行し、さらに20秒の猶予を置く。 その間は「やっぱりやめる」で取り消せる。
誰かが押すと、見ている全員の画面に出る。
パソコンが落ちてしまったとき、外から起こせるようにしておく。
- 高速スタートアップを無効にする —
fix_startup.batをダブルクリックし、 許可の画面で「はい」を押す。 これをしないと、電源を入れ直しても完全な起動をせず、自動起動が走らない。 「再起動」は常に完全な起動をするので、再起動のテストだけでは気づけない - BIOSで Restore on AC/Power Loss を
Power Onにする (ASRockなら Advanced → ACPI Configuration。起動時にDeleteでBIOSへ、F6で詳細表示) - スマートプラグにパソコンの電源を挿す
- 必ず試す: シャットダウン → プラグをオフ → オン → 自分で起動するか
動いているパソコンの電源を切るのは、コンセントを抜くのと同じ。 普段はプラグを入れたままにし、オフ→オンは落ちているときの最後の手段にする。
status.batで「PCの起動時」になっているか確かめる- Windows Update を一時停止する(設定 → Windows Update → 更新の一時停止)。 再起動そのものを減らせる
- パソコンがスリープしない設定になっているか確かめる (電源プラン → スリープ → 「なし」)
- BIOSに「電源復帰時に自動起動」があれば入れておく。停電から戻れる
黒い画面が出ないぶん、状態とアドレスは status.bat で確認する。
止めたいときは stop.bat、やめたいときは uninstall_autostart.bat。
パソコンの電源を入れた直後は、Tailscale がまだ立ち上がっていないことがある。 そのときはいったん自己署名の証明書で動き始め、用意ができ次第、 サーバを止めずに正式なものへ差し替える。利用者の操作は要らない。
また、手元の証明書に十分な期限が残っていれば、Tailscale に問い合わせず そのまま使う。問い合わせが通らない環境でも、警告なしで動き続ける。
ケージの「トイレ」「エサ場」のように、映像の中の決まった場所を見張り、 そこに猫がいるかどうかを判定する。
見る側の画面で トイレの範囲 エサ場の範囲 を押し、映像の上をなぞって囲む。
見張り を「する」にすると、反応値がリアルタイムで出る。
見張りは覚えた景色との違いを見ている。 覚えたときに猫が写っていると、判定が逆になる(いるのが普通、いないと反応する)。
そのため、猫がいない状態で「いまの景色を覚え直す」を押すこと。 これを忘れると、いくら待っても反応値が 0 のままになる。
「検知が見ているもの」に、変わったと判断した点が橙色で出る。 猫がいるのに塗られないなら、覚え直しが要るというサイン。
その範囲の何%が変わったか(0〜100)。 範囲の半分を猫が占めていれば 50 前後になる。
平均の差ではなく割合にしているのは、広い範囲に小さな猫がいても 薄まって埋もれないようにするため。
画像認識で猫を探すのではなく、「そこに何かいる」を見ている。 カメラは固定でケージの中で動くのは猫だけなので、実用上これで足りる。 画像認識より、はるかに軽く、暗いところでも粘る。 (手を入れても掃除をしても反応する、という性質はある)
前のコマとの差分ではなく、誰もいないときの背景との差を見ている。 差分方式だと、トイレでじっとしている猫を見逃す。 用を足している間はほとんど動かないので、そこが取れないと意味がない。
背景は照明の変化に合わせて少しずつ覚え直すが、 「いる」と判定している区画だけは覚え直さない。 そこを更新すると、居座っている猫が背景に溶けて見えなくなる。
見張りは24時間カメラを動かし続ける必要があり、自動スタンバイは正反対の機能。 見張りを入にすると、自動スタンバイは自動的に止まる(切ると元に戻る)。
見る側で「見つけたら録画」を入にすると、区画に猫が入ったときに自動で記録し、 PCへ送って保管する。スマホに溜めると容量を圧迫し、取り出すのも面倒になる。
入った8秒前から記録する。反応してから録り始めると、 肝心の「入ってくるところ」が写らないため、常に直近の数秒を手元に持っておき、 反応があった時点でそこから遡って1本にまとめている。 出ていってから5秒後まで録り、1本は最大90分…ではなく90秒で切る。
録画は /recordings で一覧・再生・削除できる。見る画面からも辿れる。
古いものから自動で消える(既定200本 / 合計2GB)。
config.json の recordings_keep と recordings_keep_mb で変えられる。
録画するときは、あとで見返せるように 640×480 / 10fps まで画質を戻す (検知だけなら 320×240 / 5fps で足りるが、それでは見返しに耐えない)。
録画まで動く。通知はまだ。 しきい値は仮の値(入 15% / 出 8%)なので、実際の設置場所での値を見て詰める。
古い端末を常時通電で回すので、熱を溜め込ませないための決まりを置ける。 見る側の「運転のきまり」で設定する。
決めた時間の外では自動で止まる。22:00 〜 08:00 のように日をまたぐ指定もできる。
時刻の判断はカメラ端末自身が行うので、サーバが落ちていても止まるべきものは止まる。
時間帯の変わり目でだけ入れ直すので、その間は手で操作してよい。
上限(3 / 6 / 12時間)に達すると 30分休む。 見ている人がいる間は中断しない。見終わってから休みに入る。 休み明けは自動で戻る。
見る側には 休止中 あと N分 と出る。
ブラウザに端末温度を取得する手段は無い。 電池は残量と充電状況しか読めないので、温度による緊急停止は作れない。 ここはハードウェア側で対処する(下記)。
充電しっぱなしが、電池にとって最も過酷な状態。 スマートプラグで充電を時間で区切ると、高い電圧に晒され続ける時間が大きく減る。
月に一度は本体の裏を触って、膨らみがないか確かめること。 画面が浮いてきたら、すぐ使用をやめる。
- PINを知らないと、映像も操作画面も見られない
- PINはコードに書かれていない。初回起動時にランダム生成され
config.jsonに入る - PINを5回続けて間違えると、そのIPを5分締め出す(繰り返すと最大1時間)
- 通信はすべてHTTPSで暗号化。映像もWebRTCの規格で暗号化される
- Tailscaleを使う構成では、自宅はインターネットに公開されない
config.json と certs/ は秘密なので、gitに含めないこと(.gitignore済み)。
スマホでページが開かない
- PCとスマホが同じWi-Fiか。ゲストネットワークではないか
- OSのファイアウォールで許可し忘れていないか
カメラが起動しない / ERROR になる
- ブラウザのアドレスバー左のアイコンからカメラを「許可」にする
- 他のアプリがカメラを使っていると起動できない
CAMERA ON なのに映像が黒いまま
- カメラ端末が他のアプリに切り替わっていないか、画面が消えていないか
- 外出先からの場合、カメラ端末がTailscaleに繋がっているか
- iPhoneで「タップして再生」と出たら、映像部分を1回タップする
ページを直したのに表示が変わらない
- サーバが二重に起動している可能性がある。黒い画面をすべて閉じてから 起動し直す(二重起動は検出して止まるようにしてある)
黒い画面が固まって、どこからも繋がらなくなった
- Windowsのコンソールは、クリックすると出力が止まりプログラムごと停止する。 対策済みだが、古い版では起きる。文字をコピーしたいときは 右クリック → 編集 → 範囲指定 を使う
- 通信の記録は画面ではなく
petcam.logに書いているので、 画面側で何が起きてもカメラは動き続ける
カメラのスマホ 見る端末
│ │
│ ←──── 映像は直接 ────→ │ WebRTC
│ │
└──────────┬───────────────────┘
│
server.py
(引き合わせと状態の通知だけ)
映像はサーバを通らず、端末同士が直接やりとりする(WebRTC)。 サーバがするのは、お互いを引き合わせることと状態を伝えることだけ。
そのおかげで、
- 遅延が小さい(0.1〜0.3秒)
- サーバのCPUをほとんど使わない
- スマホは映像の圧縮に専用の回路を使うので、発熱と電池の減りが抑えられる
外出先から見るとき、映像はインターネット経由の直接接続になる
(config.json の ice_servers に設定したSTUNサーバで経路を見つける。
STUNは「自分が外からどう見えるか」を答えるだけで、映像は通らない。
不要なら [] にできる)。
petcam/
├ start.bat 起動用(Windows・ダブルクリック。部品も自動で入る)
├ AI_SETUP.md AIに読ませて導入を手伝ってもらうためのファイル
├ recordings/ 自動録画の保管先(自動生成・gitに含めない)
├ server.py サーバ本体
├ make_cert.py 自己署名証明書を作る
├ ts_cert.py Tailscaleの正式な証明書を取る・更新する
├ selftest.py 壊れていないか確かめる
├ precheck.bat 出かける前の確認(ダブルクリック)
├ fix_startup.bat 高速スタートアップを無効にする(ダブルクリック)
├ config.json PINなど(自動生成・gitに含めない)
├ petcam.log 通信と診断の記録(自動生成・gitに含めない)
├ certs/ 証明書(自動生成・gitに含めない)
├ templates/
│ ├ login.html PIN入力
│ ├ camera.html カメラ端末の画面
│ └ viewer.html 見る側の画面
└ static/
├ style.css
├ conn.js サーバとの接続(切れたら自動でつなぎ直す)
└ sounds.js 呼び出し音の合成(カメラ端末と見る側で共通)
python selftest.py認証・締め出し・状態通知・遠隔操作・つなぎ直し・シグナリング中継を確認する。 映像そのものは実機でしか確かめられない。
python server.py --http --port 8444このPCの中だけで http://127.0.0.1:8444/ として動く。
localhost はHTTPでもブラウザが安全な文脈として扱うのでカメラが開ける。
証明書の警告を抜ける手間がない。本番を止めずに試せる。
templates/ と static/ の変更は、ページを再読み込みすれば反映される
(サーバの再起動は不要)。
両端がどんな経路の候補を出し合ったかが petcam.log に残る。
[診断 camera/xxxxxx] 自分の候補 host udp 192.168.0.13 51234
[診断 viewer/yyyyyy] 自分の候補 srflx udp 122.133.x.x 49067
[診断 viewer/yyyyyy] 採用された経路 自分[srflx 122.133.x.x] -> 相手[prflx ?]
採用された経路 が出ていれば接続は成立している。
出ないまま ICE failed が続く場合は、候補が足りていない。
MIT