Leitfaden für Kamerageräte für Android

Der Gerätetyp „Kamera“ wird mit zwei Traits implementiert: PushAvStreamTransport, das den Transport von Audio- und Videostreams über Push-basierte Protokolle übernimmt, und WebRtcLiveView, das die Steuerung von Livestreams und Gegensprechen ermöglicht.

Prüfen Sie immer, ob ein Gerät Attribute und Befehle unterstützt, bevor Sie Funktionen verwenden oder versuchen, Attribute zu aktualisieren. Weitere Informationen finden Sie unter Geräte aufAndroid steuern.

Gerätetyp für Home-APIs Merkmale Kotlin-Beispiel-App Anwendungsfall

Kamera

GoogleCameraDevice

home.matter.6006.types.0158

Ein Gerät, mit dem Standbilder oder Videos aufgenommen werden. Kameras können zugängliche Livestreams, Zweiwege-Audio oder Erkennungsereignisse bieten.

Erforderliche Attribute
     google PushAvStreamTransport
     google WebRtcLiveView

Kamera

Livestream starten

Wenn Sie einen Livestream starten möchten, senden Sie den SDP-String (Session Description Protocol) an die Methode startLiveView() des Traits WebRtcLiveView. Diese gibt ein WebRtcLiveViewTrait.StartLiveViewCommand.Response mit drei Werten zurück:

  • Das SDP für die Sitzung.
  • Die Sitzungsdauer in Sekunden.
  • Die Sitzungs-ID, die zum Verlängern oder Beenden der Sitzung verwendet werden kann.
suspend fun getWebRtcLiveViewTrait(cameraDevice: HomeDevice) {
 return cameraDevice.type(GoogleCameraDevice).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)

Livestream verlängern

Livestreams haben eine voreingestellte Dauer, nach der sie ablaufen. Wenn Sie die Dauer eines aktiven Streams verlängern möchten, senden Sie eine Verlängerungsanfrage mit der Methode 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
}

TalkBack starten und beenden

Rufen Sie die Methode startTalkback() des Traits WebRtcLiveView auf, um TalkBack zu starten. Verwenden Sie stopTalkback(), um die Aufnahme zu beenden.

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

Aufzeichnungsfunktion aktivieren und deaktivieren

Um die Aufnahmefunktion der Kamera zu aktivieren, übergeben Sie TransportStatusEnum.Active an die Methode setTransportStatus() des Traits PushAvStreamTransport. Wenn Sie die Aufnahmefunktion deaktivieren möchten, übergeben Sie sie TransportStatusEnum.Inactive. Im folgenden Beispiel fassen wir diese Aufrufe in einem einzigen Aufruf zusammen, der ein Boolean verwendet, um die Aufnahmefunktion zu aktivieren oder zu deaktivieren:

// Start or stop recording for all connections.
suspend fun setCameraRecording(trait: PushAvStreamTransport, isOn: Boolean) {
  if(isOn) {
    trait.setTransportStatus(TransportStatusEnum.Active)
  } else {
    trait.setTransportStatus(TransportStatusEnum.Inactive)
  }
}

Das Aktivieren oder Deaktivieren der Aufnahmefunktion der Kamera entspricht dem Ein- oder Ausschalten des Kameravideos. Wenn das Video einer Kamera aktiviert ist, wird es aufgezeichnet (für Ereignisse und zugehörige Clips).

Wenn die Aufzeichnungsfunktion deaktiviert ist (das Kameravideo ist deaktiviert):

  • Die Kamera kann gemäß dem connectivityState des Gerätetyps weiterhin als online angezeigt werden.
  • Auf den Livestream kann nicht zugegriffen werden und die Kamera erkennt keine Cloud-Ereignisse.

Prüfen, ob die Aufzeichnungsfunktion aktiviert ist

Wenn Sie prüfen möchten, ob die Aufnahmefunktion einer Kamera aktiviert ist, sehen Sie nach, ob Verbindungen aktiv sind. Im folgenden Beispiel werden zwei Funktionen definiert, um dies zu tun:

// Get the on/off state
suspend fun onOffState(pushAvStreamTransport: PushAvStreamTransport) {
  return pushAvStreamTransport
    .currentConnections?.any { it.transportStatus == TransportStatusEnum.Active } ?: false
}

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

Eine weitere Möglichkeit, dies zu prüfen, ist die Verwendung der Funktion findTransport() mit einem Prädikat:

// Fetch the current connections
suspend fun queryRecordModeState(trait: PushAvStreamTransport) {
  return trait.findTransport().let {
      it.transportConfigurations.any { it.transportStatus == TransportStatusEnum.Active
    }
}

Audioeinstellungen

Über die Home-APIs lassen sich verschiedene Audioeinstellungen der Kamera steuern.

Mikrofon ein- und ausschalten

Aktualisieren Sie das Attribut microphoneMuted des Traits CameraAvStreamManagement mit der integrierten Kotlin-Funktion setMicrophoneMuted, um das Mikrofon des Geräts zu aktivieren oder zu deaktivieren:

// Turn the device's microphone on or off
suspend fun turnOffMicrophone(disableMicrophone: Boolean, trait: CameraAvStreamManagement) {
  trait.update { setMicrophoneMuted(disableMicrophone) }
}

Audioaufnahme ein- oder ausschalten

Wenn Sie die Audioaufnahme für das Gerät aktivieren oder deaktivieren möchten, aktualisieren Sie das Attribut recordingMicrophoneMuted des Traits CameraAvStreamManagement mit der integrierten Kotlin-Funktion setRecordingMicrophoneMuted:

// Turn audio recording on or off for the device
suspend fun turnOffAudioRecording(disableAudioRecording: Boolean, trait: CameraAvStreamManagement) {
  trait.update { setRecordingMicrophoneMuted(disableAudioRecording) }
}

Lautsprecherlautstärke anpassen

Wenn Sie die Lautstärke des Lautsprechers für das Gerät anpassen möchten, aktualisieren Sie das Attribut speakerVolumeLevel des Traits CameraAvStreamManagement mit der integrierten Kotlin-Funktion setSpeakerVolumeLevel:

// Adjust the camera speaker volume
suspend fun adjustSpeakerVolume(volume: Int, trait: CameraAvStreamManagement) {
  trait.update { setSpeakerVolumeLevel(volume.toUbyte()) }
}

Weitere Einstellungen

Über die Home-APIs lassen sich verschiedene andere Kameraeinstellungen steuern.

Bildausrichtung ändern

Die Ausrichtung des Kamerabilds (Videos) kann gedreht werden. Das Video kann nur um 180 Grad gedreht werden.

Wenn Sie die Bildausrichtung der Kamera ändern möchten, aktualisieren Sie das Attribut imageRotation des Traits CameraAvStreamManagement mit der integrierten Kotlin-Funktion setImageRotation:

// Change the camera's image orientation
val isRotated = false

cameraAvStreamManagement.update { setImageRotation(if (isRotated) 180.toUShort() else 0.toUShort()) }

Nachtsichtmodus aktivieren oder deaktivieren

Wenn Sie die Nachtsicht für die Kamera aktivieren oder deaktivieren möchten, verwenden Sie TriStateAutoEnum, um das Attribut nightVision des Traits CameraAvStreamManagement mit der integrierten Kotlin-Funktion setNightVision zu aktualisieren:

// Turn night vision on
cameraAvStreamManagement.update {
  setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.On)
}

// Turn night vision off
CameraAvStreamManagement.update {
  setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.Off)
}

Helligkeit der Status-LED ändern

Wenn Sie die Helligkeit der Status-LED ändern möchten, verwenden Sie ThreeLevelAutoEnum, um das Attribut statusLightBrightness des Traits CameraAvStreamManagement mit der integrierten Kotlin-Funktion setStatusLightBrightness zu aktualisieren:

// Set the LED brightness to high
cameraAvStreamManagement.update {
  setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.High)
}

// Set the LED brightness to low
cameraAvStreamManagement.update {
  setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.Low)
}

Kamera-Darstellungsbereich ändern

Die Kameraansicht entspricht der Funktion „Zoomen und zuschneiden“, die im Hilfeartikel zum Zoomen und Optimieren von Nest-Kameravideos beschrieben wird.

Der Viewport wird in einem ViewportStruct definiert, das vier Werte enthält, die als Koordinaten des Viewports verwendet werden. Die Koordinaten sind so definiert:

(x1,y1) -- (x2,y1)
   |          |
(x1,y2) -- (x2,y2)

Die Werte für ViewportStruct hängen von der Benutzeroberfläche und der Kameraimplementierung einer App ab. Um den Viewport des Kameravideos festzulegen, müssen Sie das Attribut viewport des CameraAvStreamManagement-Traits mit einem ViewportStruct aktualisieren. Verwenden Sie dazu die integrierte Kotlin-Funktion setViewport:

cameraAvStreamManagement
  .update { setViewport(
    CameraAvStreamManagementTrait.ViewportStruct(
      x1 = horizontalRange.rangeStart.roundToInt().toUShort(),
      x2 = horizontalRange.rangeEnd.roundToInt().toUShort(),
      y1 = verticalRange.rangeStart.roundToInt().toUShort(),
      y2 = verticalRange.rangeEnd.roundToInt().toUShort(),
    )
) }

Empfindlichkeit für die Beendigung des Ruhemodus anpassen

Die Aufwachsensibilität des Geräts wird verwendet, um den Akku zu schonen. Dazu wird der Bereich verkleinert, in dem das Gerät Aktivitäten erkennen kann, und die Zeit bis zum Aufwachen nach Erkennen einer Aktivität verlängert.

In den Home APIs kann dies mit dem Attribut motionSensitivity des triggerOptions im transportOptions des Geräts festgelegt werden. Diese Optionen werden für jedes Gerät im PushAvStreamTransport-Trait definiert.

Die Weckempfindlichkeit kann nur auf die folgenden Werte eingestellt werden:

  • 1 = Niedrig
  • 5 = Mittel
  • 10 = Hoch

Um die Konfiguration zu aktualisieren, suchen Sie mit dem Befehl findTransport nach der Transportkonfiguration für aktive Aufzeichnungsstreams und ändern Sie die Konfiguration dann mit dem neuen Empfindlichkeitswert mit dem Befehl modifyPushTransport:

// Create a struct with the new wake-up sensitivity
val toUpdate =  TransportOptionsStruct(
  triggerOptions =
    TransportTriggerOptionsStruct(
      motionSensitivity =
        OptionalValue.present(wakeUpSensitivity.toUByte())
    )
  )

// Get the configurations for active connections
val connections  = pushAvStreamTransport.findTransport().transportConfigurations
  // Update all recording streams with the new transport options.
  for (connection in connections) {
    if (connection.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording) {
      trait.modifyPushTransport(
        connectionId = connection.connectionId,
        transportOptions = toUpdate,
      )
    }
  }

Maximale Ereignisdauer anpassen

Die maximale Ereignisdauer gibt an, wie lange die Kamera einen Clip für ein Ereignis aufzeichnet. Über die Home APIs kann dies pro Gerät auf die gleiche Länge wie über die GHA konfiguriert werden, in Intervallen von Sekunden:

  • 10 Sekunden
  • 15 Sekunden
  • 30 Sekunden
  • 60 Sekunden (1 Minute)
  • 120 Sekunden (2 Minuten)
  • 180 Sekunden (3 Minuten)

In den Home APIs kann dies mit dem Attribut motionTimeControl des triggerOptions im transportOptions des Geräts festgelegt werden. Diese Optionen werden für jedes Gerät im PushAvStreamTransport-Trait definiert.

Suchen Sie zuerst mit dem Befehl findTransport nach der Transportkonfiguration für aktive Aufzeichnungsstreams und ändern Sie dann die Konfiguration mit dem neuen Wert für die Ereignislänge mit dem Befehl modifyPushTransport:

// Create a struct with the new max event length
// where maxDuration is the length in seconds
val toUpdate =  TransportOptionsStruct(
  triggerOptions =
    TransportTriggerOptionsStruct(
      motionTimeControl =
        OptionalValue.present(
          TransportMotionTriggerTimeControlStruct(maxDuration = it.toUInt())
        )
    )
  )

// Get the configurations for active connections
val connections  = pushAvStreamTransport.findTransport().transportConfigurations
  // Update all recording streams with the new transport options.
  for (connection in connections) {
    if (connection.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording) {
      trait.modifyPushTransport(
        connectionId = connection.connectionId,
        transportOptions = toUpdate,
      )
    }
  }