The Camera device type is implemented using two traits:
[`PushAvStreamTransport`](https://developers.home.google.com/reference/kotlin/com/google/home/google/PushAvStreamTransport),
which handles audio and video stream transport using push-based protocols, and
[`WebRtcLiveView`](https://developers.home.google.com/reference/kotlin/com/google/home/google/WebRtcLiveView),
which provides the ability to control livestreams and talkback.
The Doorbell device type, for those implementations that have
camera capabilities, also uses these traits.
| **Warning:** These traits are restricted and not available for general use.

<br />


|                                                                                                                                                                                                           Home APIs Device Type                                                                                                                                                                                                            |                                                                                                                               Traits                                                                                                                                | Kotlin Sample App |                                 Use Case                                 |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------:|:------------------------------------------------------------------------:|
| ### Camera [GoogleCameraDevice](https://developers.home.google.com/reference/kotlin/com/google/home/google/GoogleCameraDevice) `home.matter.6006.types.0158` A device that captures still images or video. Cameras may feature accessible livestreams, two-way talkback, or detection events.                                                                                                                                              | Required Traits google [PushAvStreamTransport](https://developers.home.google.com/reference/kotlin/com/google/home/google/PushAvStreamTransport) google [WebRtcLiveView](https://developers.home.google.com/reference/kotlin/com/google/home/google/WebRtcLiveView) |                   |   [Camera](https://developers.home.google.com/use-cases?device=camera)   |
| ### Doorbell [GoogleDoorbellDevice](https://developers.home.google.com/reference/kotlin/com/google/home/google/GoogleDoorbellDevice) `home.matter.6006.types.0113` A device actuated by a button outside a door that makes an audible and/or visual signal, used to request the attention of a person who is somewhere on the other side of the door. Doorbells may feature accessible livestreams, two-way talkback, or detection events. | Required Traits google [PushAvStreamTransport](https://developers.home.google.com/reference/kotlin/com/google/home/google/PushAvStreamTransport) google [WebRtcLiveView](https://developers.home.google.com/reference/kotlin/com/google/home/google/WebRtcLiveView) |                   | [Doorbell](https://developers.home.google.com/use-cases?device=doorbell) |

<br />

| **Note:** The Automation API doesn't support these traits.

## Start a livestream

To start a livestream, send the Session Description Protocol (SDP) string
to the
[`WebRtcLiveView`](https://developers.home.google.com/reference/kotlin/com/google/home/google/WebRtcLiveView)
trait's
[`startLiveView()`](https://developers.home.google.com/reference/kotlin/com/google/home/google/WebRtcLiveViewCommands#startLiveView(kotlin.String)) method, which returns a
[`WebRtcLiveViewTrait.StartLiveViewCommand.Response`](https://developers.home.google.com/reference/kotlin/com/google/home/google/WebRtcLiveViewTrait.StartLiveViewCommand.Response)
containing three values:

- The SDP for the session.
- The session duration in seconds.
- The session ID, which may be used to extend or terminate the session.

```kotlin
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)
```

## Extend a livestream

Livestreams have a preset duration after which they expire. To lengthen the
duration of an active stream, issue an extension request using the
[`WebRtcLiveView.extendLiveView()`](https://developers.home.google.com/reference/kotlin/com/google/home/google/WebRtcLiveViewCommands#extendLiveView(kotlin.String,kotlin.Function1))
method:  

```kotlin
// 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
}
```

## Enable and disable recording capability

To enable the camera's recording capability, pass
[`TransportStatusEnum.Active`](https://developers.home.google.com/reference/kotlin/com/google/home/google/PushAvStreamTransportTrait.TransportStatusEnum#Active)
to the
[`PushAvStreamTransport`](https://developers.home.google.com/reference/kotlin/com/google/home/google/PushAvStreamTransport)
trait's
[`setTransportStatus()`](https://developers.home.google.com/reference/kotlin/com/google/home/google/PushAvStreamTransportCommands#setTransportStatus(com.google.home.google.PushAvStreamTransportTrait.TransportStatusEnum,kotlin.Function1))
method. To disable the recording capability, pass it
[`TransportStatusEnum.Inactive`](https://developers.home.google.com/reference/kotlin/com/google/home/google/PushAvStreamTransportTrait.TransportStatusEnum#Inactive).
In the following example, we wrap these calls in a single call that uses a
`Boolean` to toggle the recording capability:  

```kotlin
// 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)
  }
}
```

## Check to see if recording capability is enabled

To determine if a camera's recording capability is enabled, check to see if any
connections are active. The following example defines two functions to do this:  

```kotlin
// 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
}
```

Another way to check is using the `findTransport()` function with a predicate:  

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

## Start and stop talkback

To start talkback, call the
[`WebRtcLiveView`](https://developers.home.google.com/reference/kotlin/com/google/home/google/WebRtcLiveView)
trait's [`startTalkback()`](https://developers.home.google.com/reference/kotlin/com/google/home/google/WebRtcLiveViewCommands#startTalkback(kotlin.String,kotlin.Function1))
method. To stop, use
[`stopTalkback()`](https://developers.home.google.com/reference/kotlin/com/google/home/google/WebRtcLiveViewCommands#stopTalkback(kotlin.String)).  

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