Android 向けカメラ デバイス ガイド

カメラ デバイスタイプは、2 つのトレイトを使用して実装されます。PushAvStreamTransport は、プッシュベースのプロトコルを使用して音声と動画のストリーム転送を処理します。WebRtcLiveView は、ライブ ストリーミングとトークバックを制御する機能を提供します。カメラ機能を備えた実装の場合、ドアホン デバイスタイプもこれらのトレイトを使用します。

Google Home の API のデバイスタイプ トレイト Kotlin サンプルアプリ ユースケース

カメラ

GoogleCameraDevice

home.matter.6006.types.0158

静止画像や動画をキャプチャするデバイス。カメラには、アクセス可能なライブ配信、双方向のトークバック、検出アクティビティなどの機能が搭載されている場合があります。

必須のトレイト
     google PushAvStreamTransport
     google WebRtcLiveView

カメラ

ドアホン

GoogleDoorbellDevice

home.matter.6006.types.0113

ドアの外にあるボタンを押すと、音や光の信号を発して、ドアの向こう側にいる人の注意を引くためのデバイス。ドアホンには、アクセシビリティ対応のライブ配信、双方向のトークバック、検出イベントなどの機能が搭載されている場合があります。

必須のトレイト
     google PushAvStreamTransport
     google WebRtcLiveView

ドアホン

ライブ配信を開始する

ライブ配信を開始するには、セッション記述プロトコル(SDP)文字列を WebRtcLiveView トレイトの startLiveView() メソッドに送信します。このメソッドは、次の 3 つの値を含む WebRtcLiveViewTrait.StartLiveViewCommand.Response を返します。

  • セッションの SDP。
  • セッションの長さ(秒数)。
  • セッションの延長または終了に使用できるセッション ID。
suspend fun getWebRtcLiveViewTrait(cameraDevice, cameraDeviceType) {
 return cameraDevice.type(cameraDeviceType).trait(WebRtcLiveView).first {
    it?.metadata?.sourceConnectivity?.connectivityState == ConnectivityState.ONLINE
  }

}

// Start the live view
suspend fun startCameraStream(trait: WebRtcLiveView,offerSdp: String) {
  val response = trait.startLiveView(offerSdp)
  // Response contains three fields (see below)
  return response
}
  ...

// This is used to manage the WebRTC connection
val peerConnection: RTCPeerConnection = ...

   ...

val startResponse = startCameraStream(sdp)
val answerSdp = startResponse?.answerSdp
val sessionDuration = startResponse?.liveSessionDurationSeconds
val mediaSessionId = startResponse?.mediaSessionId

peerConnection.setRemoteDescription(SessionDescription.Type.ANSWER,
                                    answerSdp)

ライブ配信を延長する

ライブ配信には、期限切れになるまでの期間が事前に設定されています。アクティブなストリームの期間を延長するには、WebRtcLiveView.extendLiveView() メソッドを使用して延長リクエストを発行します。

// Assuming camera stream has just been started
suspend fun scheduleExtension(trait: WebRtcLiveView, mediaSessionId: String, liveSessionDurationSeconds: UShort ) {
  delay(liveSessionDurationSeconds - BUFFER_SECONDS * 1000)
  val response = trait.extendLiveView(mediaSessionId)
  // returns how long the session will be live for
  return response.liveSessionDurationSeconds
}

録画機能を有効または無効にする

カメラの録画機能を有効にするには、PushAvStreamTransport トレイトの setTransportStatus() メソッドに TransportStatusEnum.Active を渡します。録画機能を無効にするには、TransportStatusEnum.Inactive を渡します。次の例では、これらの呼び出しを 1 つの呼び出しでラップし、Boolean を使用して録音機能を切り替えます。

// Start or stop recording for all connections.
suspend fun setCameraRecording(isOn: Boolean) {
  val pushAvStreamTransport = getPushAvStreamTransport
  if(isOn) {
    pushAvStreamTransport.setTransportStatus(TransportStatusEnum.Active)
  } else {
    pushAvStreamTransport.setTransportStatus(TransportStatusEnum.Inactive)
  }
}

録画機能が有効になっているかどうかを確認する

カメラの録画機能が有効になっているかどうかを確認するには、接続がアクティブかどうかを確認します。次の例では、これを行う 2 つの関数を定義しています。

// Get the on/off state
suspend fun onOffState(cameraDevice: HomeDevice, cameraDeviceType) {
  // Query the device for pushAvStreamTransport
  val pushAvTrait = getPushAvStreamTransport()
  return pushAvTrait.recordModeActive()
}

// Check to see if the camera's recording capability is enabled
fun PushAvStreamTransport.recordModeActive(): Boolean {
  return currentConnections?.any { it.transportStatus == TransportStatusEnum.Active } ?: false
}

別の方法として、述語を使用して findTransport() 関数を使用することもできます。

// Fetch the current connections
suspend fun queryRecordModeState(cameraDevice: HomeDevice, cameraDeviceType) {
  val pushAvStreamTransport = getPushAvStreamTransport()
  return pushAvStreamTransport.findTransport().let {
      it.transportConfigurations.any { it.transportStatus == TransportStatusEnum.Active
    }
}

TalkBack の開始と停止

TalkBack を開始するには、WebRtcLiveView トレイトの startTalkback() メソッドを呼び出します。停止するには、stopTalkback() を使用します。

// Make sure camera stream is on
suspend fun setTalkback(isOn: Boolean, trait: WebRtcLiveView, mediaSessionId: String) {
  if(isOn) {
    trait.startTalkback(mediaSessionId)
  } else {
    trait.stopTalkback(mediaSessionId)
  }
}