Android 카메라 기기 가이드

카메라 기기 유형은 푸시 기반 프로토콜을 사용하여 오디오 및 동영상 스트림 전송을 처리하는 PushAvStreamTransport와 라이브 스트림 및 토크백을 제어하는 기능을 제공하는 WebRtcLiveView의 두 가지 특성을 사용하여 구현됩니다. 카메라 기능이 있는 구현의 경우 초인종 기기 유형도 이러한 특성을 사용합니다.

Home API 기기 유형 특성 Kotlin 샘플 앱 사용 사례

카메라

GoogleCameraDevice

home.matter.6006.types.0158

정지 이미지나 동영상을 캡처하는 기기 카메라에는 접근 가능한 라이브 스트림, 양방향 대화 또는 감지 활동이 포함될 수 있습니다.

필수 특성
     google PushAvStreamTransport
     google WebRtcLiveView

카메라

초인종

GoogleDoorbellDevice

home.matter.6006.types.0113

문 밖에 있는 버튼으로 작동하며, 문 반대편에 있는 사람의 주의를 끌기 위해 사용되는 청각 및/또는 시각 신호를 내는 장치입니다. 초인종에는 접근 가능한 라이브 스트림, 양방향 TalkBack 또는 감지 활동이 포함될 수 있습니다.

필수 특성
     google PushAvStreamTransport
     google WebRtcLiveView

초인종

라이브 스트림 시작

라이브 스트림을 시작하려면 세션 설명 프로토콜 (SDP) 문자열을 WebRtcLiveView 특성의 startLiveView() 메서드로 전송합니다. 이 메서드는 다음 세 값을 포함하는 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
}

녹화 기능 사용 설정 및 중지

카메라의 녹화 기능을 사용 설정하려면 TransportStatusEnum.ActivePushAvStreamTransport 특성의 setTransportStatus() 메서드에 전달합니다. 녹음 기능을 사용 중지하려면 TransportStatusEnum.Inactive을 전달합니다. 다음 예에서는 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)
  }
}

녹음 기능이 사용 설정되어 있는지 확인

카메라의 녹화 기능이 사용 설정되어 있는지 확인하려면 연결이 활성 상태인지 확인하세요. 다음 예에서는 이를 수행하는 두 함수를 정의합니다.

// 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 시작 및 중지

토크백을 시작하려면 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)
  }
}