From cc9c4e130d40d0af3fa4d181a2a4212387d0d47c Mon Sep 17 00:00:00 2001 From: Koushik Dutta Date: Thu, 24 Mar 2022 23:08:20 -0700 Subject: [PATCH] alexa: use rtc signaling channel --- plugins/alexa/src/types/camera.ts | 50 +++++++++++++++++-------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/plugins/alexa/src/types/camera.ts b/plugins/alexa/src/types/camera.ts index a4fe011eb..fd41bb78d 100644 --- a/plugins/alexa/src/types/camera.ts +++ b/plugins/alexa/src/types/camera.ts @@ -1,4 +1,4 @@ -import sdk, { FFMpegInput, ScryptedDevice, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, VideoCamera } from "@scrypted/sdk"; +import sdk, { FFMpegInput, HttpResponse, RTCAVSignalingSetup, RTCSignalingChannel, RTCSignalingSendIceCandidate, RTCSignalingSession, ScryptedDevice, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, VideoCamera } from "@scrypted/sdk"; import { addSupportedType, AlexaCapabilityHandler, capabilityHandlers } from "./common"; import { startRTCPeerConnectionFFmpegInput } from '@scrypted/common/src/ffmpeg-to-wrtc'; import { BrowserSignalingSession, startRTCSignalingSession } from '@scrypted/common/src/rtc-signaling'; @@ -33,30 +33,24 @@ addSupportedType(ScryptedDeviceType.Camera, { export const rtcHandlers = new Map>(); -rtcHandlers.set('InitiateSessionWithOffer', async (request, response, directive: any, device: ScryptedDevice & VideoCamera) => { - const mo = await device.getVideoStream(); - const ffInput = await mediaManager.convertMediaObjectToJSON(mo, ScryptedMimeTypes.FFmpegInput); - const pc = await startRTCPeerConnectionFFmpegInput(ffInput, { - maxWidth: 960, - }); +export class AlexaSignalingSession implements RTCSignalingSession { + constructor(public response: HttpResponse, public directive: any) { - const session = new BrowserSignalingSession(pc); - session.options = undefined; - session.hasSetup = true; + } - const sdp: string = directive.payload.offer.value.replaceAll('sendrecv', 'recvonly'); + async createLocalDescription(type: "offer" | "answer", setup: RTCAVSignalingSetup, sendIceCandidate: RTCSignalingSendIceCandidate): Promise { + return { + type: 'offer', + sdp: this.directive.payload.offer.value, + } + } - setTimeout(() => { - pc.onicecandidate({ - candidate: undefined, - } as any) - },2000) + async addIceCandidate(candidate: RTCIceCandidateInit): Promise { + throw new Error("trickle ICE is not supported by Alexa"); + } - startRTCSignalingSession(session, { - sdp, - type: 'offer', - }, console, async () => undefined, async (remoteDescription: RTCSessionDescriptionInit) => { - response.send(JSON.stringify({ + async setRemoteDescription(description: RTCSessionDescriptionInit, setup: RTCAVSignalingSetup): Promise { + this.response.send(JSON.stringify({ "event": { "header": { "namespace": "Alexa.RTCSessionController", @@ -67,13 +61,23 @@ rtcHandlers.set('InitiateSessionWithOffer', async (request, response, directive: "payload": { "answer": { "format": "SDP", - "value": remoteDescription.sdp, + "value": description.sdp, } } } })); + } +} - return undefined; +rtcHandlers.set('InitiateSessionWithOffer', async (request, response, directive: any, + device: ScryptedDevice & RTCSignalingChannel) => { + const session = new AlexaSignalingSession(response, directive); + device.startRTCSignalingSession(session, { + proxy: true, + offer: { + type: 'offer', + sdp: directive.payload.offer.value, + } }); });