Тип устройства «Камера» реализован с использованием двух трейтов: PushAvStreamTransport , который обрабатывает передачу аудио- и видеопотоков с использованием протоколов на основе push-уведомлений, и WebRtcLiveView , который предоставляет возможность управления прямыми трансляциями и обратной связью.
Перед использованием каких-либо функций или попыткой обновления атрибутов всегда проверяйте поддержку атрибутов и команд для устройства. См. раздел «Управление устройствами» .Android для получения дополнительной информации.
| Главная API Тип устройства | Черты | Пример приложения на Kotlin | Вариант использования |
|---|---|---|---|
Камера Устройство, позволяющее делать снимки или записывать видео. Камеры могут иметь функции прямой трансляции, двусторонней связи или обнаружения событий. | Необходимые характеристики google PushAvStreamTransport google WebRtcLiveView | Камера |
Начать прямую трансляцию
Для запуска прямой трансляции отправьте строку протокола описания сессии (SDP) в метод startLiveView() трейта WebRtcLiveView , который вернет объект WebRtcLiveViewTrait.StartLiveViewCommand.Response , содержащий три значения:
- План развития науки и техники для данной сессии.
- Продолжительность сессии в секундах.
- Идентификатор сессии, который может использоваться для продления или завершения сессии.
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)
Продлить прямую трансляцию
Прямые трансляции имеют заданную продолжительность, по истечении которой они завершаются. Чтобы продлить продолжительность активной трансляции, отправьте запрос на продление, используя метод 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 }
Запуск и остановка обратной связи
Чтобы запустить обратную связь, вызовите метод startTalkback() трейта WebRtcLiveView . Чтобы остановить её, используйте 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) } }
Включение и отключение функции записи
Чтобы включить запись с камеры, передайте 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) } }
Включение или выключение функции записи камеры аналогично включению или выключению видеозаписи. Когда видеозапись камеры включена, она ведется (для целей фиксации событий и создания связанных видеороликов).
Когда функция записи отключена (видео с камеры выключено):
- Камера по-прежнему может отображаться как подключенная к сети в соответствии с параметром
connectivityStateтипа устройства . - Прямая трансляция недоступна, камера также не обнаруживает никаких событий, связанных с облачными сервисами.
Проверьте, включена ли функция записи.
Чтобы определить, включена ли функция записи на камере, проверьте наличие активных подключений. В следующем примере определены две функции для выполнения этой задачи:
// Get the on/off state suspend fun onOffState(cameraDevice: HomeDevice, cameraDeviceType) { // Query the device for pushAvStreamTransport val pushAvTrait = getPushAvStreamTransport() return pushAvTrait.recordModeActive() } // Check 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 } }
Настройки звука
Различные настройки звука камеры можно контролировать с помощью API Home.
Включение или выключение микрофона
Чтобы включить или выключить микрофон устройства, обновите атрибут microphoneMuted трейта CameraAvStreamManagement , используя встроенную функцию Kotlin setMicrophoneMuted :
// Turn the device's microphone on or off suspend fun turnOffMicrophone(disableMicrophone: Boolean, trait: CameraAvStreamManagement) { trait.update { setMicrophoneMuted(disableMicrophone) } }
Включение или выключение записи звука
Чтобы включить или выключить запись звука на устройстве, обновите атрибут recordingMicrophoneMuted трейта CameraAvStreamManagement , используя встроенную функцию Kotlin setRecordingMicrophoneMuted :
// Turn audio recording on or off for the device suspend fun turnOffAudioRecording(disableAudioRecording: Boolean, trait: CameraAvStreamManagement) { trait.update { setRecordingMicrophoneMuted(disableAudioRecording) } }
Отрегулируйте громкость динамиков
Для регулировки громкости динамика устройства обновите атрибут speakerVolumeLevel трейта CameraAvStreamManagement , используя встроенную функцию Kotlin setSpeakerVolumeLevel :
// Adjust the camera speaker volume suspend fun adjustSpeakerVolume(volume: Int, trait: CameraAvStreamManagement) { trait.update { setSpeakerVolumeLevel(volume.toUbyte()) } }
Другие настройки
Различные другие настройки камеры можно контролировать через API Home.
Изменить ориентацию изображения
Ориентацию изображения с камеры (видео) можно поворачивать. Видео можно повернуть только на 180 градусов.
Чтобы изменить ориентацию изображения с камеры, обновите атрибут imageRotation трейта CameraAvStreamManagement , используя встроенную функцию Kotlin setImageRotation :
// Change the camera's image orientation val isRotated = false cameraAvStreamManagement.update { setImageRotation(if (isRotated) 180.toUShort() else 0.toUShort()) }
Включение или выключение ночного видения
Чтобы включить или выключить ночное видение для камеры, используйте TriStateAutoEnum для обновления атрибута nightVision трейта CameraAvStreamManagement с помощью встроенной функции Kotlin setNightVision :
// Turn night vision on cameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.On) } // Turn night vision off CameraAvStreamManagement.update { setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.Off) }
Изменить яркость индикатора состояния
Чтобы изменить яркость светодиода состояния, используйте ThreeLevelAutoEnum для обновления атрибута statusLightBrightness трейта CameraAvStreamManagement с помощью встроенной функции Kotlin setStatusLightBrightness :
// Set the LED brightness to high cameraAvStreamManagement.update { setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.High) } // Set the LED brightness to low cameraAvStreamManagement.update { setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.Low) }
Изменить область просмотра камеры
Окно просмотра камеры идентично функции масштабирования и кадрирования, описанной в статье «Масштабирование и улучшение качества видео с камер Nest» .
Область просмотра определяется в структуре ViewportStruct , которая содержит четыре значения, используемые в качестве координат области просмотра. Координаты определяются следующим образом:
(x1,y1) -- (x2,y1) | | (x1,y2) -- (x2,y2)
Определение значений для ViewportStruct зависит от пользовательского интерфейса приложения и реализации камеры. На самом базовом уровне, чтобы установить область просмотра видео с камеры, обновите атрибут viewport трейта CameraAvStreamManagement , указав ViewportStruct , используя встроенную функцию Kotlin 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(), ) ) }
Отрегулируйте чувствительность пробуждения устройства.
Чувствительность устройства к пробуждению используется для экономии заряда батареи за счет уменьшения диапазона, в котором устройство может обнаруживать активность, и увеличения времени пробуждения после обнаружения этой активности.
В API Home это можно установить с помощью свойства motionSensitivity объекта triggerOptions в transportOptions устройства. Эти параметры определены в трейте PushAvStreamTransport для каждого устройства.
Чувствительность к пробуждению можно установить только на следующие значения:
- 1 = Низкий
- 5 = Средний
- 10 = Высокий
Процесс обновления заключается в следующем: с помощью команды findTransport необходимо найти конфигурацию транспорта для активных потоков записи, а затем изменить конфигурацию, указав новое значение чувствительности, с помощью команды 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, ) } }
Отрегулируйте максимальную продолжительность события.
Максимальная продолжительность события — это время, в течение которого камера будет записывать видеоролик для данного события. Через API Home это можно настроить для каждого устройства отдельно, установив ту же продолжительность, что и через GHA , с интервалом в секундах:
- 10 секунд
- 15 секунд
- 30 секунд
- 60 секунд (1 минута)
- 120 секунд (2 минуты)
- 180 секунд (3 минуты)
В API Home это можно установить с помощью свойства motionTimeControl объекта triggerOptions в transportOptions устройства. Эти параметры определены в трейте PushAvStreamTransport для каждого устройства.
Процесс обновления заключается в следующем: с помощью команды findTransport необходимо найти конфигурацию транспорта для активных потоков записи, а затем изменить конфигурацию, указав новое значение длины события, используя команду 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, ) } }