Тип устройства «Камера» реализован с использованием двух трейтов: PushAvStreamTransportTrait
, который обрабатывает передачу аудио- и видеопотоков с помощью push-протоколов, и WebRtcLiveViewTrait
, который обеспечивает возможность управления прямыми трансляциями и обратной связью. Тип устройства «Дверной звонок» (Doorbell) для реализаций с поддержкой камеры также использует эти трейты.
API для дома Тип устройства | Черты | Пример приложения Swift | Вариант использования |
---|---|---|---|
Камера Устройство для записи неподвижных изображений или видео. Камеры могут поддерживать прямую трансляцию, двустороннюю связь или фиксировать события. | Требуемые черты Google PushAvStreamTransportTrait Google WebRtcLiveViewTrait | Камера | |
Дверной звонок Устройство, активируемое кнопкой снаружи двери и подающее звуковой и/или визуальный сигнал, используемое для привлечения внимания человека, находящегося по ту сторону двери. Дверные звонки могут поддерживать прямую трансляцию, двустороннюю связь или распознавать события. | Требуемые черты Google PushAvStreamTransportTrait Google WebRtcLiveViewTrait | Дверной звонок |
Начать прямую трансляцию
Чтобы начать прямую трансляцию, отправьте строку протокола описания сеанса (SDP) методу startLiveView(offerSdp:)
свойства WebRtcLiveViewTrait
, который возвращает три значения:
- СДП для сессии.
- Длительность сеанса в секундах.
- Идентификатор сеанса, который может использоваться для продления или завершения сеанса.
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
}
}
Продлить прямую трансляцию
У прямых трансляций есть предустановленная продолжительность, по истечении которой они истекают. Чтобы увеличить продолжительность активной трансляции, отправьте запрос на продление с помощью метода 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
}
}
Включить и отключить возможность записи
Чтобы включить возможность записи камеры, передайте TransportStatusEnum.Active
методу setTransportStatus(transportStatus:optionalArgsProvider:)
трейта PushAvStreamTransportTrait
. Чтобы отключить возможность записи, передайте TransportStatusEnum.Inactive
. В следующем примере мы объединяем эти вызовы в один вызов, который использует Boolean
для включения/выключения возможности записи:
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)")
}
}
}
Проверьте, включена ли возможность записи.
Чтобы определить, включена ли функция записи камеры, проверьте наличие активных подключений. В следующем примере определены две функции для этого:
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
}
Запуск и остановка двусторонней связи
Чтобы начать обратную связь, вызовите метод startTalkback(mediaSessionId:optionalArgsProvider:)
трейта WebRtcLiveViewTrait
. Чтобы остановить, используйте 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)")
}
}