犬の見守りカメラ映像をWebRTCでFirefoxへ配信し、その映像をブラウザ内AIでリアルタイム姿勢推定したい場合、重要なのは「映像表示」と「AI推論」を同じ速度で無理に処理しないことです。WebRTC映像が30fpsだからといってAIも30fpsで実行すると、CPU負荷が上がり、映像表示のカクつきや推論遅延につながりやすくなります。
2026年時点のFirefoxを主対象にするなら、WebRTC映像は通常の<video>で再生し、requestVideoFrameCallback()でフレーム到着を検知し、AI用には低解像度へ縮小したフレームを別経路で処理する構成が扱いやすく安定しています。推論エンジンはFirefoxとの互換性を重視するならONNX Runtime WebのWebAssembly(WASM)を第一候補にし、犬専用の姿勢推定モデルをONNX形式で利用する設計が現実的です。
この記事では、WebRTC、Firefox、ブラウザAIを組み合わせた犬の見守りカメラについて、処理パイプライン、Workerの使い方、推論FPS、モデル選択、WebGPUを前提にしない理由、低遅延化のポイントまで実装者向けに解説します。
- 最初に結論:映像表示とAI推論を分離する構成が最も扱いやすい
- WebRTC映像はそのままvideo要素へ流す
- フレーム取得にはrequestVideoFrameCallback()が使いやすい
- AI推論は5~15fps程度から始める
- 「推論中なら次のフレームを捨てる」設計が重要
- AI用画像は元の1080pをそのまま渡さない
- 犬専用モデルなら「検出→クロップ→姿勢推定」の2段構成も有効
- MediaPipe Pose Landmarkerは犬用モデルではない点に注意
- FirefoxではONNX Runtime WebのWASMを第一候補にする
- FirefoxでWebGPU前提の設計を避ける理由
- ONNX Runtime WebのWASMでもブラウザ内推論のメリットは大きい
- AI推論はWeb Workerへ分離する
- OffscreenCanvasを使って縮小・前処理をWorker側へ寄せる
- MediaStreamTrackProcessorを前提にしすぎないほうが互換性を確保しやすい
- 姿勢推定結果は毎フレーム描き直す必要がない
- 犬の「姿勢」を分類するならキーポイント推定と状態分類を分ける
- 犬の動きが少ないときは推論頻度をさらに下げられる
- WebRTC自体の受信品質をAI処理で悪化させない設計にする
- WebRTCのgetStats()も監視すると原因を切り分けやすい
- 推奨する実装構成をまとめる
- 実装イメージ:メインスレッドでは推論を待たない
- 処理負荷を下げる優先順位
- プライバシー面でもブラウザ内推論にはメリットがある
- まとめ:FirefoxならWebRTC表示とWASM推論を分離し「最新フレームだけ」を処理する
最初に結論:映像表示とAI推論を分離する構成が最も扱いやすい
Firefox上で犬の見守り映像を表示しながら姿勢推定する場合、基本構成は「WebRTC受信 → video表示」と「videoフレーム取得 → 縮小 → AI推論 → 結果描画」を分離する形がおすすめです。
概念的には次のようなパイプラインになります。
WebRTC → RTCPeerConnection → MediaStream → <video> → requestVideoFrameCallback()
↓
推論対象フレームを間引く
↓
低解像度化 → Worker → ONNX Runtime Web
↓
犬のキーポイント座標
↓
Canvasで骨格を重ね描画
この構成なら、動画は30fpsや60fpsで滑らかに表示しながら、AIは5~15fps程度で処理できます。見守り用途の姿勢推定では、AI結果を動画と同じ30fpsで計算する必要はほとんどありません。
WebRTC映像はそのままvideo要素へ流す
WebRTCで受信した映像は、まず通常どおりRTCPeerConnectionから取得したMediaStreamをHTMLVideoElement.srcObjectへ設定します。AI処理のためにWebRTCストリーム自体を書き換える必要はありません。
例えば次のような考え方です。
peerConnection.ontrack = event => { video.srcObject = event.streams[0]; };
この方法ではFirefox自身のWebRTCデコード・映像表示パイプラインをそのまま利用できるため、AI処理が多少遅くても映像再生へ直接影響させにくくなります。表示用映像と解析処理を同じ同期処理へ入れないことが重要です。
AI結果は動画そのものを書き換えるのではなく、video要素の上に透明なcanvasを重ね、犬の関節点や骨格線だけ描画する方法がシンプルです。これなら元映像の再エンコードも不要です。
フレーム取得にはrequestVideoFrameCallback()が使いやすい
動画フレームをAIへ渡すタイミングには、setInterval()よりHTMLVideoElement.requestVideoFrameCallback()が適しています。このAPIは実際に新しい動画フレームがコンポジタへ送られるタイミングでコールバックされるため、動画解析との相性がよいAPIです。
MDNではrequestVideoFrameCallback()について、動画フレームごとの処理、Canvas描画、動画解析などに利用できると説明しています。2024年以降は主要ブラウザで利用しやすいBaseline機能となっており、Firefoxでも利用できます。
[参照] MDN:HTMLVideoElement.requestVideoFrameCallback()
ただしコールバックされるたびに推論する必要はありません。30fps映像なら、例えば3フレームに1回だけAIへ送れば約10fpsになります。
AI推論は5~15fps程度から始める
犬の姿勢推定では、映像そのものが30fpsでも推論を30回/秒行う必要はないケースが多くあります。寝ている、立っている、歩いている、座っているなどの状態監視なら5~10fpsでも十分なことがあります。
例えば30fpsのWebRTC映像を受信している場合、3フレームに1回推論すれば約10fps、6フレームに1回なら約5fpsになります。
実装では固定フレーム数よりも、前回の推論時刻から一定時間が経ったかを見る方式も便利です。例えばperformance.now()を使い、100ms以上経過していれば推論するようにすれば、おおむね10fpsへ制限できます。
このように映像FPSとAI FPSを分離することが、ブラウザAIを安定させる最大のポイントです。
「推論中なら次のフレームを捨てる」設計が重要
リアルタイムAIで最も避けたいのが、処理できないフレームをキューへ延々と溜める設計です。例えばAI推論に150msかかるのに100msごとに画像を投入すると、処理待ちフレームが蓄積し、数秒前の犬の姿勢を表示する状態になります。
見守りカメラでは過去の全フレームを解析することより、常に最新フレームを解析することのほうが重要です。そのため推論中なら次のフレームは捨て、推論が終わった時点の最新フレームだけ処理する「latest-frame-wins」の考え方が向いています。
例えばinferenceBusyフラグを用意し、推論中なら何もせず次のrequestVideoFrameCallback()へ進みます。これだけでもAI処理の遅延蓄積を防ぎやすくなります。
AI用画像は元の1080pをそのまま渡さない
見守りカメラが1920×1080で配信していても、姿勢推定モデルの入力サイズが256×256や384×384なら、1080p画像をそのままAIへ渡す意味はほとんどありません。
videoフレームからAIへ渡す直前に、モデル入力サイズへ縮小します。例えば犬が映っている領域を384×384へ変換して推論するだけでも、ピクセルコピーや前処理の負荷を大幅に減らせます。
実際のシステムでは「WebRTC表示は1080p」「AI処理は320~512px程度」と役割を分けるとよいでしょう。ユーザーは高画質映像を見られ、AIは必要最低限の解像度だけ処理します。
犬専用モデルなら「検出→クロップ→姿勢推定」の2段構成も有効
カメラ映像の中で犬が画面の一部にしか映らない場合、フレーム全体を毎回姿勢推定モデルへ入力するより、最初に犬を検出して、その領域だけ切り出して姿勢推定する方法が効率的です。
処理は次のようになります。
WebRTCフレーム → 犬検出 → Bounding Box → ROIクロップ → 犬姿勢推定 → キーポイント
例えば1920×1080の部屋全体に犬が小さく映っている場合、画像全体を256×256へ縮小すると犬自体が非常に小さくなり、キーポイント精度が落ちます。先に犬を検出して周囲を切り出せば、モデル入力の大部分を犬が占めるため精度を上げやすくなります。
犬がほぼ常に画面中央へ大きく映る固定カメラなら検出段を省略し、直接姿勢推定する構成でも構いません。
MediaPipe Pose Landmarkerは犬用モデルではない点に注意
ブラウザ姿勢推定というとMediaPipe Pose Landmarkerが候補に挙がります。MediaPipe Tasks VisionはWeb版を提供しており、Firefoxを含むブラウザから姿勢推定を実行できます。また2026年時点のMediaPipe Tasksでは、画像などの入力処理はデバイス上で行われると説明されています。
[参照] Google AI Edge:MediaPipe Tasks Vision for Web
ただし、標準のMediaPipe Pose Landmarkerは人間の身体姿勢を推定するモデルです。犬の四肢、尾、耳、鼻、背骨などを正しく推定する目的でそのまま使用するのは適切ではありません。
犬の見守り用途では、Animal Pose、AP-10Kなど動物キーポイントデータセットを使って学習したモデルや、自分のカメラ条件に合わせて犬専用キーポイントモデルを学習し、ONNXへ変換してブラウザ実行する構成が適しています。
FirefoxではONNX Runtime WebのWASMを第一候補にする
ブラウザ内で独自の犬姿勢推定モデルを動かすなら、ONNX Runtime Webは有力な選択肢です。PyTorchなどで学習したモデルをONNXへ変換し、JavaScriptからブラウザ上で推論できます。
2026年8月時点のONNX Runtime公式互換性表では、Firefox on WindowsはWebAssembly(WASM)実行に対応しています。一方、ONNX Runtime WebのWebGPU Execution ProviderについてはFirefoxは公式対応表でサポート対象になっていません。
[参照] ONNX Runtime公式:ONNX Runtime Web
そのためFirefox対応を必須条件にするなら、最初からWebGPUだけを前提にするより、WASMを基準実装として作り、将来的にWebGPU対応ブラウザではGPUへ切り替える設計のほうが安全です。
FirefoxでWebGPU前提の設計を避ける理由
WebGPUはブラウザAIを高速化できる有力な技術ですが、ブラウザごとの対応状況やAIランタイム側の対応状況を確認する必要があります。
ONNX Runtime Web公式では、WebGPUはChrome・EdgeなどChromium系ブラウザで利用可能とされる一方、FirefoxについてはWebGPU Execution Providerの対応表で未対応となっています。そのため「Firefoxで動くこと」が必須なら、WebGPUを唯一の実行経路にしてしまうと互換性の問題が発生します。
構成としては、WebGPUが利用できればWebGPU → それ以外はWASMというフォールバック方式が理想です。ただしFirefox専用システムであれば、最初はWASMで性能目標を満たせるモデルサイズへ最適化するほうが開発コストを抑えられます。
ONNX Runtime WebのWASMでもブラウザ内推論のメリットは大きい
WASMというとGPUより遅いイメージがありますが、小型の姿勢推定モデルなら十分実用的な速度を得られる場合があります。ONNX Runtime公式も、ブラウザ内推論には低遅延、プライバシー、オフライン利用、クラウド推論コスト削減といったメリットがあると説明しています。
[参照] ONNX Runtime公式:In-browser inference
犬の見守り映像の場合、カメラ映像そのものを推論サーバーへ送る必要がなく、WebRTCで視聴端末へ届いた映像をその場で解析できます。映像プライバシーを重視する家庭内カメラ用途とも相性があります。
モデルを軽量化し、入力解像度を抑え、推論FPSを5~10fps程度へ制限すれば、CPUベースでも十分なケースがあります。
AI推論はWeb Workerへ分離する
推論処理をメインスレッド上で同期的に実行すると、UI操作、スクロール、Canvas描画、WebRTC映像表示などに影響する可能性があります。そのため可能な範囲でWeb WorkerへAI処理を分離する設計がおすすめです。
概念的にはメインスレッドが「映像表示・フレーム選択・結果描画」、Workerが「前処理・ONNX推論・後処理」を担当します。
| 処理 | 推奨実行場所 |
|---|---|
| WebRTC接続管理 | メインスレッド |
| video表示 | メインスレッド |
| requestVideoFrameCallback() | メインスレッド |
| モデル前処理 | Worker |
| ONNX推論 | Worker |
| キーポイント後処理 | Worker |
| 骨格オーバーレイ描画 | メインスレッドまたはOffscreenCanvas |
これにより推論に多少時間がかかっても、ページ全体の操作感を維持しやすくなります。
OffscreenCanvasを使って縮小・前処理をWorker側へ寄せる
画像のリサイズやピクセル変換も意外にCPU負荷がかかります。そのため対応環境ではOffscreenCanvasを利用し、画像縮小や前処理をWorker側へ移す方法が有効です。
例えばメインスレッドで現在の動画フレームを取得し、Worker側のOffscreenCanvasへ描画して320×320へ縮小します。その後RGBAデータをモデル入力用RGBテンソルへ変換し、正規化してONNX Runtimeへ渡します。
ただしフレームごとに巨大なImageDataをコピーすると、それ自体がボトルネックになります。解像度を最初から小さくする、転送可能オブジェクトを利用する、不要な配列生成を避ける、といった工夫が重要です。
MediaStreamTrackProcessorを前提にしすぎないほうが互換性を確保しやすい
WebRTCのMediaStreamTrackから直接VideoFrameを取得できるMediaStreamTrackProcessorは、リアルタイム映像処理に向いたAPIです。Mozillaも標準化されたMediaStreamTrackProcessorとVideoTrackGeneratorについて、リアルタイムのMediaStreamTrackをVideoFrameのストリームへ変換できるAPIとして紹介しています。
[参照] Mozilla:MediaStreamTrackProcessor and VideoTrackGenerator
ただしブラウザ間では歴史的に実装差があり、Chromeには早期の独自実装も存在します。そのためFirefoxだけでなくChromeやSafariへの展開も考えているなら、最初はvideo + requestVideoFrameCallback()を基本経路として実装し、利用可能な環境ではMediaStreamTrackProcessorへ最適化する段階的アプローチが扱いやすいでしょう。
姿勢推定結果は毎フレーム描き直す必要がない
AIが10fpsの場合でも、WebRTC動画は30fpsで表示できます。AI結果は最後に得られたキーポイントを保持し、次の推論結果が到着するまで同じ骨格をCanvasへ描画すればよいでしょう。
さらに犬の関節座標にはEMA(指数移動平均)などの簡単な時間方向フィルタを適用すると、推論ごとの細かな座標揺れを軽減できます。
例えば現在座標をそのまま使うのではなく、filtered = α × new + (1 - α) × previousのように平滑化すれば、骨格表示が安定します。ただし強く平滑化しすぎると犬が動いたときの追従が遅れるため、実際の映像で調整します。
犬の「姿勢」を分類するならキーポイント推定と状態分類を分ける
「姿勢推定」といっても、関節座標を表示することが目的なのか、「立つ・座る・伏せる・寝る」を判定したいのかで構成が変わります。
後者の場合は、画像から直接「座る」などを分類するより、まず犬のキーポイントを取得し、その時系列を小型の分類器へ入力する二段構成が扱いやすい場合があります。
映像 → 犬キーポイント → 1~2秒分の時系列 → 姿勢・行動分類
例えば肩、腰、前脚、後脚などの相対座標を正規化し、過去15~30フレーム分を小さなMLP、1D CNN、TCNなどへ入力すれば、「立位」「座位」「伏せ」「歩行」のような状態を分類できます。
犬の動きが少ないときは推論頻度をさらに下げられる
見守りカメラでは、犬が何時間も寝ているケースがあります。その間も10fpsで姿勢推定を続けるのはCPUやバッテリーの無駄になる可能性があります。
簡単なフレーム差分や犬Bounding Boxの移動量を見て、変化が少ない間は推論を1~2fpsまで下げ、動き始めたら10fpsへ戻す適応型スケジューリングも有効です。
例えば「直近のBounding Box中心位置の変化が一定値以下」「キーポイント変化が小さい」といった条件を満たす状態が数秒続いたら低FPSモードへ切り替えます。見守り用途では体感性能を維持しながら負荷を大きく減らせます。
WebRTC自体の受信品質をAI処理で悪化させない設計にする
ブラウザ内AIを追加したことでCPU使用率が100%近くになると、映像デコードやWebRTC処理まで影響を受け、フレーム落ちや遅延増大が起きることがあります。
そのためAIの目標FPSは「推論モデルが出せる最大FPS」ではなく、WebRTC再生を安定させた状態で維持できるFPSに設定するべきです。
例えば推論単体では20fps出せても、WebRTC映像と同時に動かすとCPU使用率が90%になるなら、AIを8~10fpsへ抑えたほうがシステム全体として優秀です。見守りカメラでは瞬間的なベンチマーク値より、長時間安定して動作することが重要です。
WebRTCのgetStats()も監視すると原因を切り分けやすい
実運用ではRTCPeerConnection.getStats()を定期的に取得し、受信FPS、デコードFPS、packet loss、jitter、framesDropped、framesDecodedなどを監視すると便利です。
AIをオンにした瞬間にframesDroppedが増える場合、推論負荷が映像再生へ影響している可能性があります。逆にWebRTC側は安定しているのにAI FPSだけ落ちるなら、モデル推論や画像前処理がボトルネックです。
このように動画品質とAI性能を別々のメトリクスで測定することで、「映像回線が悪いのか」「AIが重いのか」を切り分けられます。
推奨する実装構成をまとめる
Firefoxを主対象に犬のWebRTC見守りカメラへブラウザAIを組み込む場合、実装の第一候補は次のようになります。
| レイヤー | 推奨構成 |
|---|---|
| 映像受信 | WebRTC / RTCPeerConnection |
| 映像表示 | HTMLVideoElement |
| フレーム同期 | requestVideoFrameCallback() |
| AIフレームレート | 5~15fps程度から調整 |
| 入力画像 | モデル入力サイズへ縮小 |
| 犬検出 | 必要なら軽量Object Detector |
| 姿勢推定 | 犬用キーポイントモデル |
| 推論ランタイム | ONNX Runtime Web / WASM |
| スレッド | 可能な処理をWeb Workerへ分離 |
| 描画 | video上のCanvasオーバーレイ |
| フレームキュー | 溜めずに最新フレーム優先 |
まずこの構成で動作させ、その後プロファイリング結果を見ながら最適化するのが堅実です。
実装イメージ:メインスレッドでは推論を待たない
設計イメージとしては、メインスレッドでは新しい動画フレームを受け取り、AI Workerが空いている場合だけフレームを渡します。
let busy = false;
function onFrame(now, metadata) { if (!busy && now - lastInference >= 100) { busy = true; sendLatestFrameToWorker(); lastInference = now; } video.requestVideoFrameCallback(onFrame); }
Workerから推論結果が返ってきたらbusy = falseに戻し、次の最新フレームを受け付けます。この方式なら推論が遅くなっても待ち行列が増えません。
10fpsを狙うなら100ms、5fpsなら200msを目安にします。実際には推論時間を測定しながら自動調整する方法もあります。
処理負荷を下げる優先順位
性能不足になった場合、いきなり別のGPU APIへ移行するより、まず処理量そのものを減らすほうが効果的です。
- AI FPSを下げる
- モデル入力解像度を下げる
- より軽量なモデルへ変更する
- 犬のROIだけ推論する
- 動いていないときの推論頻度を下げる
- Workerへ処理を分離する
- モデルを量子化する
- その後にGPUバックエンドを検討する
例えば512×512・30fpsで動かないモデルでも、320×320・8fpsへ変更すれば見守り用途では十分な精度を保ったまま大幅に軽くなる可能性があります。
プライバシー面でもブラウザ内推論にはメリットがある
犬の見守りカメラには室内映像が含まれるため、クラウドAIへ画像を送信する設計ではプライバシーや通信コストも考える必要があります。
ブラウザ内AIなら、WebRTCでユーザー端末まで届いた映像をその端末内で推論し、サーバーへはキーポイントや「犬が立った」「転倒の疑い」といった結果だけ送る構成にもできます。
ONNX Runtime Webも、ブラウザ内推論についてデータを端末外へ出さず推論できること、低遅延化やクラウドコスト削減につながることを利点として挙げています。
まとめ:FirefoxならWebRTC表示とWASM推論を分離し「最新フレームだけ」を処理する
Firefox上で犬の見守りカメラをWebRTC配信しながらブラウザAIで姿勢推定する場合、最も重要なのはWebRTC映像表示とAI推論を別パイプラインとして扱うことです。映像は通常どおりHTMLVideoElementで再生し、requestVideoFrameCallback()を使ってAI対象フレームだけ取り出す構成が分かりやすくなります。
AIはWebRTCと同じ30fpsで動かす必要はなく、まず5~15fps程度を目標にします。推論中に次のフレームが来た場合はキューへ積まず破棄し、常に最新フレームを処理する設計にすると、数秒遅れた姿勢結果が表示される問題を防げます。
Firefoxとの互換性を重視するなら、2026年8月時点ではONNX Runtime WebのWASM Execution Providerを基準にするのが安全です。ONNX Runtime公式の対応表ではFirefoxでWASMが利用できる一方、WebGPU Execution ProviderはFirefoxを正式な対応ブラウザとしていません。Chromeなども対応する場合はWebGPUを追加し、利用できない環境ではWASMへフォールバックする設計が適しています。
また、一般的なMediaPipe Pose Landmarkerは人間用なので、犬の姿勢推定には犬・動物用キーポイントモデルを利用する必要があります。部屋全体が映るカメラなら「犬検出 → ROIクロップ → 犬姿勢推定」とし、Worker上で軽量ONNXモデルを実行、結果だけをメインスレッドへ戻してCanvasへ重ね描画する構成が実用的です。
最終的には、「WebRTCは高画質・30fpsで表示」「AIは低解像度・5~15fps」「推論はWorker」「キューを作らず最新フレーム優先」「FirefoxではWASMを基準」という設計から始めるのがおすすめです。この構成ならFirefoxの互換性を確保しつつ、映像の滑らかさ、AIのリアルタイム性、CPU負荷のバランスを取りやすくなります。


コメント