Guía del dispositivo de cámara para iOS

El tipo de dispositivo Cámara se implementa con dos rasgos: PushAvStreamTransportTrait, que controla el transporte de transmisiones de audio y video con protocolos basados en la transmisión, y WebRtcLiveViewTrait, que proporciona la capacidad de controlar transmisiones en vivo y la función de intercomunicador. El tipo de dispositivo Doorbell, para aquellas implementaciones que tienen capacidades de cámara, también usa estos rasgos.

Tipo de dispositivo de las APIs de Home Rasgos App de ejemplo de Swift Caso de uso

Cámara

GoogleCameraDeviceType

home.matter.6006.types.0158

Dispositivo que captura imágenes fijas o videos. Las cámaras pueden incluir transmisiones en vivo accesibles, intercomunicador bidireccional o eventos de detección.

Required Traits
     google PushAvStreamTransportTrait
     google WebRtcLiveViewTrait

Cámara

Timbre

GoogleDoorbellDeviceType

home.matter.6006.types.0113

Dispositivo que se acciona con un botón fuera de una puerta y que emite una señal audible o visual para solicitar la atención de una persona que se encuentra al otro lado de la puerta. Los timbres pueden incluir transmisiones en vivo accesibles, respuesta bidireccional o eventos de detección.

Required Traits
     google PushAvStreamTransportTrait
     google WebRtcLiveViewTrait

Timbre

Cómo iniciar una transmisión en vivo

Para iniciar una transmisión en vivo, envía la cadena del Protocolo de descripción de sesión (SDP) al método startLiveView(offerSdp:) del rasgo WebRtcLiveViewTrait, que devuelve tres valores:

  • Es el SDP de la sesión.
  • Es la duración de la sesión en segundos.
  • Es el ID de sesión, que se puede usar para extender o finalizar la sesión.
public func sendOffer(offerSdp: String) async throws 
-> (answerSdp: String, mediaSessionId: String, liveViewDuration: TimeInterval) 
{
  do {
    Logger.info("Sending StartLiveView command...")
    let response = try await liveViewTrait.startLiveView(
      offerSdp: offerSdp
    )
    Logger.info("Received StartLiveView response: \(response)")
    return (
      answerSdp: response.answerSdp,
      mediaSessionId: response.mediaSessionId,
      liveViewDuration: TimeInterval(response.liveSessionDurationSeconds)
    )
  } catch {
    Logger.error("Failed to send StartLiveView command: \(error)")
    throw error
  }
}

Cómo extender una transmisión en vivo

Las transmisiones en vivo tienen una duración predeterminada después de la cual vencen. Para extender la duración de una transmisión activa, emite una solicitud de extensión con el método extendLiveView(mediaSessionId:optionalArgsProvider:):

public func extendLiveView(mediaSessionId: String) async throws {
  do {
    Logger.info("Extending live view...")
    let extendedDuration = try await liveViewTrait.extendLiveView(mediaSessionId: mediaSessionId)
    Logger.info("Extended live view for \(extendedDuration.liveSessionDurationSeconds) seconds.")
  } catch {
    Logger.error("Failed to extend live view: \(error)")
    throw error
  }
}

Cómo habilitar e inhabilitar la capacidad de grabación

Para habilitar la capacidad de grabación de la cámara, pasa TransportStatusEnum.Active al método setTransportStatus(transportStatus:optionalArgsProvider:) del rasgo PushAvStreamTransportTrait. Para inhabilitar la capacidad de grabación, pasa TransportStatusEnum.Inactive. En el siguiente ejemplo, incluimos estas llamadas en una sola llamada que usa un Boolean para activar o desactivar la capacidad de grabación:

public func toggleIsRecording(isOn: Bool) {
  self.uiState = .loading

  guard let pushAvStreamTransportTrait else {
    Logger.error("PushAvStreamTransportTrait not found.")
    return
  }
  Task {
    do {
      Logger.debug("Toggling onOff to \(isOn ? "ON" : "OFF")...")
      try await pushAvStreamTransportTrait.setTransportStatus(
        transportStatus: isOn ? .active : .inactive)
      if isOn {
        do {
          self.player = try self.createWebRtcPlayer()
        } catch {
          Logger.error("Failed to initialize WebRtcPlayer: \(error)")
          self.uiState = .disconnected
          return
        }
        await self.player?.initialize()
        self.uiState = .live
      } else {
        self.player = nil
        self.uiState = .off
      }
    } catch {
      Logger.error("Failed to toggle onOff: \(error)")
    }
  }
}

Comprueba si la capacidad de grabación está habilitada

Para determinar si la capacidad de grabación de una cámara está habilitada, verifica si hay conexiones activas. En el siguiente ejemplo, se definen dos funciones para realizar esta acción:

public func isDeviceRecording() -> Bool {
  guard let pushAvStreamTransportTrait else {
    Logger.error("PushAvStreamTransportTrait not found.")
    return false
  }
  guard
    let hasActiveConnection =
      pushAvStreamTransportTrait
      .attributes
      .currentConnections?
      .contains(where: { $0.transportStatus == .active })
  else {
    return false
  }
  return hasActiveConnection
}

Cómo iniciar y detener TalkBack

Para iniciar TalkBack, llama al método startTalkback(mediaSessionId:optionalArgsProvider:) del rasgo WebRtcLiveViewTrait. Para detenerla, usa stopTalkback(mediaSessionId:).

public func toggleTwoWayTalk(isOn: Bool, mediaSessionId: String) async throws {
  do {
    Logger.info("Toggling twoWayTalk to \(isOn ? "ON" : "OFF")...")
    if isOn {
      try await liveViewTrait.startTalkback(mediaSessionId: mediaSessionId)
    } else {
      try await liveViewTrait.stopTalkback(mediaSessionId: mediaSessionId)
    }
  } catch {
    throw HomeError.commandFailed("Failed to toggle twoWayTalk: \(error)")
  }
}