מדריך למצלמה במכשירי Android

סוג המכשיר 'מצלמה' מיושם באמצעות שתי תכונות: ‫PushAvStreamTransport, שמטפלת בהעברת סטרימינג של אודיו ווידאו באמצעות פרוטוקולים מבוססי-push, ו- ‫WebRtcLiveView, שמספקת את היכולת לשלוט בשידורים חיים ובדיבור חוזר. סוג המכשיר Doorbell, בהטמעות שכוללות יכולות מצלמה, משתמש גם הוא בתכונות האלה.

Home APIs Device Type תכונות אפליקציה לדוגמה ב-Kotlin תרחיש לדוגמה

מצלמה

GoogleCameraDevice

home.matter.6006.types.0158

מכשיר שמצלם תמונות סטילס או סרטונים. יכול להיות שהמצלמות יכללו שידורים חיים נגישים, שיחה משני צידי הדלת או אירועי זיהוי.

מאפיינים נדרשים
     google PushAvStreamTransport
     google WebRtcLiveView

מצלמה

פעמון דלת

GoogleDoorbellDevice

home.matter.6006.types.0113

מכשיר שמפעילים באמצעות לחצן מחוץ לדלת, שמפיק אות קולי או חזותי, ומשמש לבקשת תשומת הלב של אדם שנמצא בצד השני של הדלת. יכול להיות שפעמוני הדלת יכללו שידורים חיים נגישים, תקשורת דו-כיוונית או אירועי זיהוי.

מאפיינים נדרשים
     google PushAvStreamTransport
     google WebRtcLiveView

Doorbell

התחלת שידור חי

כדי להתחיל שידור חי, שולחים את המחרוזת של Session Description Protocol ‏ (SDP) אל השיטה startLiveView() של המאפיין WebRtcLiveView, שמחזירה את WebRtcLiveViewTrait.StartLiveViewCommand.Response עם שלושה ערכים:

  • נתוני ה-SDP של הסשן.
  • משך הביקור בשניות.
  • מזהה הסשן, שאפשר להשתמש בו כדי להאריך או לסיים את הסשן.
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.Active לשיטה setTransportStatus() של מאפיין PushAvStreamTransport. כדי להשבית את האפשרות להקלטה, מעבירים את הערך 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

כדי להפעיל את 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)
  }
}