1 of 11

1

AndroidとUSBカメラでWebRTC

2018/10/9

インフィニテグラ株式会社 馬場 鉄平

2 of 11

自己紹介

2

  • 主にプログラミング、たまに回路・基板設計、筐体設計しています

モデリングマシン

液体窒素実験

3Dプリンタデータ

サーマルカメラ

RasPi

LED栽培

3 of 11

ウェアラブルなビデオチャットシステム RazVision WR

3

  • Android端末 + USBカメラ でウェアラブル
  • Androidは専用アプリ、PCはChrome専用
  • Ruby on Rails
  • PeerJS リプレースしたい…。 参考:「PeerJSを今後も使い続けるのは危険」@Nakaさん

4 of 11

AndroidでUSBカメラを使用するには

4

  • Android ~8.0

USBカメラは非対応、外部ライブラリで対応

      • 弊社開発のライブラリ「AndCam-ULib」
      • オープンソースのライブラリ

  • Android 9.0

ついにUSBカメラ標準対応

5 of 11

MediaStreamを生成するまで(1)- 画像の取得

5

  • アプリはWebView 使用(実体はChrome)

WebView

AndCam-ULib

USB Camera

USB

WebResourceResponse

WebViewClient

フレームデータ

特定URLをカメラ画像に割り当て

WebViewClient.shouldInterceptRequest()

(例) http://localhost/camera.jpg

<img>

JPEG

HTML/JavaScript

Java

6 of 11

MediaStreamを生成するまで(2) - Canvasの利用

6

<canvas>に描画

<img src=“http://localhost/camera.jpg”>

で画像を取得

①画像の更新

Canvas.captureStream()

のMediaStream

getUserMedia({audio:true})

のMediaStream

②MediaStreamの生成

ピアに送信する

MediaStream

getVideoTracks()[0]

getAudioTracks()[0]

CanvasRenderingContext2D.drawImage()

7 of 11

応用

7

  • 画像のソースがUSBカメラでなくても応用可
  • 画像を生成して送信する手法

カメラ画像

背景除去

送信

例)

8 of 11

問題発生:時間が経過すると解像度が落ちる

8

chrome://webrtc-internals

受信された画像の解像度の推移

1280

960

480

640

  • 通信開始後、数分で画素数が1/16以下に低下
  • 機種ごとに低下速度が異なる
  • SDPのVP8独自オプション

x-google-start-bitrate,

x-google-min-bitrate,

x-google-max-quantization

なども試したが解決せず

9 of 11

原因:CPU負荷が高いとき解像度を下げる処理がある

9

  • 弊社アプリではUSBカメラの画像を取得する分、(内蔵カメラに比べて)CPU使用率が高い
  • WebRTCのモジュールにおいて

CPU負荷が高いとき画像エンコードの量を調整する処理を発見

video_stream_encoder.cc, overuse_frame_detector.cc

CPU負荷情報

OveruseFrameDetector

フレーム落ち情報

QualityScaler

エンコード量を調整

1) フレームレートの維持優先

2) 解像度の維持優先

3) バランス型

enum RTCDegradationPreference {

"maintain-framerate",

"maintain-resolution",

"balanced"

};

10 of 11

解決:RTCPeerConnection に googCpuOveruseDetection:false を渡す

10

new RTCPeerConnection(…,

{ optional: [{googCpuOveruseDetection:false}] })

【参考】

  • 他の非公式オプションについては mediaconstraintsinterface.cc を参照。

Chrome/ChromiumでCPU負荷検出の処理を無効にする

// TODO(ronghuawu): Remove once cpu overuse detection is stable.

const char MediaConstraintsInterface::kCpuOveruseDetection[] =

"googCpuOveruseDetection";

11 of 11

MOVERIO BT-35E対応

11

スマホ

BT-35E

コントローラ

USB Type-C オルタネートモード使用

  • RazVision WRが動くようにしてみました!
  • 休憩時間に試してください

MOVERIO BT-35E

市販ヘッドセット

(BT-35Eには

含まれない)

一緒にモノづくりしませんか?