攝影機裝置類型是透過兩種特徵實作:
PushAvStreamTransportTrait,可使用以推送為基礎的通訊協定處理音訊和影片串流傳輸;以及
WebRtcLiveViewTrait,可控制即時串流和對講功能。
使用任何功能或嘗試更新屬性之前,請務必先檢查裝置是否支援屬性和指令。詳情請參閱「透過iOS 控制裝置」。
| Home API 裝置類型 | 特徵 | Swift 範例應用程式 | 用途 |
|---|---|---|---|
相機
可拍攝靜態圖像或影片的裝置。攝影機可能提供無障礙即時串流、雙向通話或偵測事件。 |
必要特徵 google PushAvStreamTransportTrait google WebRtcLiveViewTrait |
相機 |
開始直播
如要開始直播,請將工作階段描述通訊協定 (SDP) 字串傳送至 WebRtcLiveViewTrait
特徵的 startLiveView(offerSdp:)
方法,該方法會傳回三個值:
- 工作階段的 SDP。
- 工作階段時間長度 (以秒為單位)。
- 工作階段 ID,可用於延長或終止工作階段。
public func sendOffer(offerSdp: String) async throws
-> (answerSdp: String, mediaSessionId: String, liveViewDuration: TimeInterval)
{
do {
// Sending StartLiveView command
let response = try await liveViewTrait.startLiveView(
offerSdp: offerSdp
)
// Received StartLiveView response
return (
answerSdp: response.answerSdp,
mediaSessionId: response.mediaSessionId,
liveViewDuration: TimeInterval(response.liveSessionDurationSeconds)
)
} catch {
// Failed to send StartLiveView command
throw error
}
}
延長直播時間
直播有預設時限,超過時限就會過期。如要延長有效串流的時長,請使用 extendLiveView(mediaSessionId:optionalArgsProvider:) 方法發出延長要求:
public func extendLiveView(mediaSessionId: String) async throws {
do {
// Extending live view
let extendedDuration = try await liveViewTrait.extendLiveView(mediaSessionId: mediaSessionId)
} catch {
// Failed to extend live view
throw error
}
}
啟動及停止 TalkBack
如要啟動 TalkBack,請呼叫 WebRtcLiveViewTrait 特徵的 startTalkback(mediaSessionId:optionalArgsProvider:) 方法。如要停止,請使用 stopTalkback(mediaSessionId:)。
public func toggleTwoWayTalk(isOn: Bool, mediaSessionId: String) async throws {
do {
if isOn {
try await liveViewTrait.startTalkback(mediaSessionId: mediaSessionId)
} else {
try await liveViewTrait.stopTalkback(mediaSessionId: mediaSessionId)
}
} catch {
throw HomeError.commandFailed("Failed to toggle twoWayTalk: \(error)")
}
}
啟用及停用錄製功能
如要啟用攝影機的錄影功能,請將
TransportStatusEnum.Active
傳遞至
PushAvStreamTransportTrait
特徵的
setTransportStatus(transportStatus:optionalArgsProvider:)
方法。如要停用錄製功能,請傳遞 TransportStatusEnum.Inactive。
在以下範例中,我們將這些呼叫包裝在單一呼叫中,並使用 Boolean 切換錄音功能:
public func toggleIsRecording(isOn: Bool) {
self.uiState = .loading
guard let pushAvStreamTransportTrait else {
// PushAvStreamTransportTrait not found.
return
}
Task {
do {
try await pushAvStreamTransportTrait.setTransportStatus(
transportStatus: isOn ? .active : .inactive)
if isOn {
do {
self.player = try self.createWebRtcPlayer()
} catch {
// Failed to initialize WebRtcPlayer
self.uiState = .disconnected
return
}
await self.player?.initialize()
self.uiState = .live
} else {
self.player = nil
self.uiState = .off
}
} catch {
// Failed to toggle onOff
}
}
}
啟用或停用攝影機的錄影功能,等同於開啟或關閉攝影機影像。攝影機影像開啟時,攝影機會錄影 (用於事件和相關影像片段)。
錄製功能停用時 (攝影機影片關閉):
- 攝影機仍會顯示為
connectivityState裝置類型的線上狀態。 - 無法存取即時串流影像,攝影機也未偵測到任何雲端事件。
確認是否已啟用錄製功能
如要判斷攝影機是否已啟用錄影功能,請檢查是否有任何連線處於啟用狀態。以下範例定義了兩個函式來執行這項操作:
public func isDeviceRecording() -> Bool {
guard let pushAvStreamTransportTrait else {
// PushAvStreamTransportTrait not found.
return false
}
guard
let hasActiveConnection =
pushAvStreamTransportTrait
.attributes
.currentConnections?
.contains(where: { $0.transportStatus == .active })
else {
return false
}
return hasActiveConnection
}
音訊設定
你可以透過 Home API 控制各種攝影機音訊設定。
開啟或關閉麥克風
如要開啟或關閉裝置麥克風,請使用內建的 setMicrophoneMuted 函式,更新 CameraAvStreamManagementTrait 特徵的 microphoneMuted 屬性:
// Turn the device's microphone on or off
func setMicrophone(on: Bool) async {
do {
_ = try await self.cameraAvStreamManagementTrait?.update {
$0.setMicrophoneMuted(!on)
}
} catch {
// Error
}
}
開啟或關閉錄音功能
如要開啟或關閉裝置的錄音功能,請使用內建的 setRecordingMicrophoneMuted 函式,更新 CameraAvStreamManagementTrait 特徵的 recordingMicrophoneMuted 屬性:
// Turn audio recording on or off for the device
func setAudioRecording(on: Bool) async {
do {
_ = try await self.cameraAvStreamManagementTrait?.update {
$0.setRecordingMicrophoneMuted(!on)
}
} catch {
// Error
}
}
調整音箱音量
如要調整裝置的音箱音量,請使用內建的 setSpeakerVolumeLevel 函式,更新 CameraAvStreamManagementTrait 特徵的 speakerVolumeLevel 屬性:
// Adjust the camera speaker volume
func setSpeakerVolume(to value: UInt8) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setSpeakerVolumeLevel(value)
}
} catch {
// Error
}
}
其他設定
您也可以透過 Home API 控制其他攝影機設定。
變更圖片方向
你可以旋轉攝影機影像 (影片) 的方向,影片只能旋轉 180 度。
如要變更攝影機的影像方向,請使用內建的 setImageRotation 函式,更新 CameraAvStreamManagementTrait 特徵的 imageRotation 屬性:
// Change the camera's image orientation
// Value must be 0 or 180
func setImageRotation(to value: UInt16) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setImageRotation(value)
}
} catch {
// Error
}
}
開啟或關閉夜視模式
如要開啟或關閉攝影機的夜視功能,請使用 TriStateAutoEnum 更新 CameraAvStreamManagementTrait 特徵的 nightVision 屬性,方法是使用內建的 setNightVision 函式:
// Turn night vision on or off
func setNightVision(
to value: Google.CameraAvStreamManagementTrait.TriStateAutoEnum
) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setNightVision(value)
}
} catch {
// Error
}
}
變更狀態 LED 燈的亮度
如要變更狀態 LED 的亮度,請使用 ThreeLevelAutoEnum 更新 CameraAvStreamManagementTrait 特徵的 statusLightBrightness 屬性,方法是使用內建的 setStatusLightBrightness 函式:
// Set the LED brightness
func setStatusLightBrightness(
to value: Google.CameraAvStreamManagementTrait.ThreeLevelAutoEnum
) async {
do {
_ = try await cameraAvStreamManagementTrait.update {
$0.setStatusLightBrightness(value)
}
} catch {
// Error
}
}
變更攝影機可視區域
攝影機檢視區塊與「縮放加強 Nest 攝影機影像」支援文章中說明的「縮放及裁剪」功能相同。
視埠定義於包含四個值的 ViewportStruct 中,這些值會做為視埠的座標。座標定義如下:
(x1,y1) -- (x2,y1) | | (x1,y2) -- (x2,y2)
判斷 ViewportStruct 的值取決於應用程式的 UI 和相機實作方式。在最基本的層級,如要設定攝影機影片的檢視區塊,請使用內建的 setViewport 函式,透過 ViewportStruct 更新 CameraAvStreamManagementTrait 特徵的 viewport 屬性。
func setCrop(x1: UInt16, y1: UInt16, x2: UInt16, y2: UInt16) {
let viewport = Google.CameraAvStreamManagementTrait.ViewportStruct(
x1: x1,
y1: y1,
x2: x2,
y2: y2
)
Task {
do {
try await cameraAvStreamManagementTrait.update {
$0.setViewport(viewport)
}
} catch {
// Error
}
}
}
產生 TransportOptionsStruct
部分設定需要修改 TransportOptionsStruct 中的屬性,然後傳遞至串流連線的傳輸選項。如果是 Swift,更新任何屬性前,必須先產生這個結構體。
使用這個輔助函式產生結構體,以便用於下列設定變更:
func getTransportOptions(
transportOptions: Google.PushAvStreamTransportTrait.TransportOptionsStruct,
wakeUpSensitivity: UInt8?,
maxEventLength: UInt32?
) async throws
-> Google.PushAvStreamTransportTrait.TransportOptionsStruct
{
var newMotionTimeControl:
Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct? = nil
if let maxEventLength {
guard let motionTimeControl = transportOptions.triggerOptions.motionTimeControl else {
throw HomeError.failedPrecondition(
// Error - cannot update max event length without motion time control
}
newMotionTimeControl =
Google.PushAvStreamTransportTrait.TransportMotionTriggerTimeControlStruct(
initialDuration: motionTimeControl.initialDuration,
augmentationDuration: motionTimeControl.augmentationDuration,
maxDuration: maxEventLength,
blindDuration: motionTimeControl.blindDuration
)
}
return Google.PushAvStreamTransportTrait.TransportOptionsStruct(
streamUsage: .recording,
videoStreamID: nil,
audioStreamID: nil,
tlsEndpointID: transportOptions.tlsEndpointID,
url: transportOptions.url,
triggerOptions: Google.PushAvStreamTransportTrait.TransportTriggerOptionsStruct(
triggerType: .motion,
motionZones: nil,
motionSensitivity: wakeUpSensitivity,
motionTimeControl: newMotionTimeControl,
maxPreRollLen: nil
),
ingestMethod: .cmafIngest,
containerOptions: Google.PushAvStreamTransportTrait.ContainerOptionsStruct(
containerType: .cmaf,
cmafContainerOptions: nil
),
expiryTime: nil
)
}
private func getRecordingConnection() async throws
-> Google.PushAvStreamTransportTrait.TransportConfigurationStruct?
{
guard let pushAvStreamTransportTrait else {
// Error - PushAvStreamTransport trait not available
return nil
}
let connections = try await pushAvStreamTransportTrait.findTransport().transportConfigurations
for connection in connections {
guard let transportOptions = connection.transportOptions,
transportOptions.streamUsage == .recording
else {
continue
}
return connection
}
return nil
}
調整裝置喚醒敏感度
裝置的喚醒敏感度可縮減裝置感應活動的範圍,並延長偵測到活動後喚醒裝置的時間,藉此節省電量。
在 Home API 中,這項屬性可透過裝置 transportOptions 中的 motionSensitivity 屬性設定。triggerOptions這些選項是在各裝置的 PushAvStreamTransportTrait 特徵中定義。
喚醒敏感度只能設為下列值:
- 1 = 低
- 5 = 中
- 10 = 高
更新程序是使用 findTransport 指令找出有效錄製串流的傳輸設定,然後使用 modifyPushTransport 指令,以新的感應度值修改設定。
modifyPushTransport 指令需要傳遞完整的 TransportOptionsStruct,因此您必須先從目前的設定複製現有值。如要瞭解如何產生執行這項操作的輔助函式,請參閱「產生 TransportOptionsStruct」。
func setWakeUpSensitivity(to value: UInt8) async {
do {
let connection = try await getRecordingConnection()
guard let connection,
let transportOptions = connection.transportOptions
else {
// Error - Transport options not available
return
}
guard transportOptions.triggerOptions.motionSensitivity != nil else {
// Error - Motion sensitivity not available to be updated for this device
return
}
try await pushAvStreamTransportTrait.modifyPushTransport(
connectionID: connection.connectionID,
transportOptions: self.getTransportOptions(
transportOptions: transportOptions,
wakeUpSensitivity: value,
maxEventLength: nil
)
)
} catch {
// Error
}
}
調整事件錄影時間上限
事件錄製時間上限是指攝影機錄製事件影像片段的時間長度上限。透過 Home API,您可以為每個裝置設定與透過 Google Home app (GHA) 相同的長度,間隔為秒:
- 10 秒
- 15 秒
- 30 秒
- 60 秒 (1 分鐘)
- 120 秒 (2 分鐘)
- 180 秒 (3 分鐘)
在 Home API 中,這項屬性可透過裝置 transportOptions 中的 motionTimeControl 屬性設定。triggerOptions這些選項是在各裝置的 PushAvStreamTransportTrait 特徵中定義。
更新程序如下:使用 findTransport 指令找出有效錄製串流的傳輸設定,然後使用 modifyPushTransport 指令,以新的事件長度值修改設定。
modifyPushTransport 指令需要傳遞完整的 TransportOptionsStruct,因此您必須先從目前的設定複製現有值。如要瞭解如何產生執行這項操作的輔助函式,請參閱「產生 TransportOptionsStruct」。
func setMaxEventLength(to value: UInt32) async {
do {
let connection = try await getRecordingConnection()
guard let connection,
let transportOptions = connection.transportOptions
else {
// Error - Transport options not available
return
}
guard transportOptions.triggerOptions.motionTimeControl != nil else {
// Error - Motion time control not available to be updated for this device
return
}
try await pushAvStreamTransportTrait.modifyPushTransport(
connectionID: connection.connectionID,
transportOptions: self.getTransportOptions(
transportOptions: transportOptions,
wakeUpSensitivity: nil,
maxEventLength: value
)
)
} catch {
// Error
}
}