يتم تنفيذ نوع الجهاز "الكاميرا" باستخدام سمتَين:
PushAvStreamTransportTrait
،
التي تتعامل مع نقل بث الصوت والفيديو باستخدام بروتوكولات مستندة إلى الإرسال،
وWebRtcLiveViewTrait
،
التي تتيح التحكّم في البث المباشر ووظيفة "التحدث المباشر".
يستخدم نوع الجهاز Doorbell هذه السمات أيضًا في عمليات التنفيذ التي تتضمّن إمكانات الكاميرا.
نوع الجهاز في Home APIs | السمات | تطبيق Swift النموذجي | حالة الاستخدام |
---|---|---|---|
الكاميرا
جهاز يلتقط صورًا ثابتة أو فيديوهات قد تتضمّن الكاميرات بثًا مباشرًا يسهل استخدامه أو ميزة "التحدّث والاستماع" أو أحداث الرصد. |
السمات المطلوبة google PushAvStreamTransportTrait google WebRtcLiveViewTrait |
الكاميرا | |
جرس الباب
جهاز يتم تشغيله بواسطة زر خارج الباب ويصدر إشارة مسموعة و/أو مرئية، ويُستخدم لطلب انتباه شخص موجود في مكان ما على الجانب الآخر من الباب. قد تتضمّن أجراس الأبواب بثًا مباشرًا يسهل الوصول إليه أو ميزة التحدّث ثنائي الاتجاه أو أحداث الرصد. |
السمات المطلوبة google PushAvStreamTransportTrait google WebRtcLiveViewTrait |
جرس الباب |
بدء بث مباشر
لبدء بث مباشر، أرسِل سلسلة Session Description Protocol (SDP) إلى طريقة startLiveView(offerSdp:)
في السمة WebRtcLiveViewTrait
، والتي تعرض ثلاث قيم:
- تمثّل هذه السمة وصف الجلسة (SDP).
- مدة الجلسة بالثواني
- رقم تعريف الجلسة الذي يمكن استخدامه لتمديد الجلسة أو إنهاءها
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
}
بدء TalkBack وإيقافه
لبدء ميزة Talkback، اتّصِل بطريقة 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)")
}
}