From 5e4b9675e2b2143e6fc1aa7fb279ec0bb2397891 Mon Sep 17 00:00:00 2001 From: Koushik Dutta Date: Tue, 18 Jan 2022 12:42:47 -0800 Subject: [PATCH] ring: a/v pipeline improvements --- .gitmodules | 2 +- common/src/listen-cluster.ts | 1 + external/ring-client-api | 2 +- plugins/ring/package-lock.json | 4 +-- plugins/ring/package.json | 4 +-- plugins/ring/src/main.ts | 49 +++++++++-------------------- plugins/ring/src/ring-client-api.ts | 11 +++++++ 7 files changed, 32 insertions(+), 41 deletions(-) create mode 100644 plugins/ring/src/ring-client-api.ts diff --git a/.gitmodules b/.gitmodules index c72b2639d..cf57113ee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -27,4 +27,4 @@ url = ../../koush/scrypted-private [submodule "external/ring-client-api"] path = external/ring-client-api - url = https://github.com/dgreif/ring.git + url = ../../koush/ring diff --git a/common/src/listen-cluster.ts b/common/src/listen-cluster.ts index 4f6f316d5..82c5d6e22 100644 --- a/common/src/listen-cluster.ts +++ b/common/src/listen-cluster.ts @@ -31,6 +31,7 @@ export async function listenZeroSingleClient() { }) return { + url: `tcp://127.0.0.1:${port}`, port, clientPromise, } diff --git a/external/ring-client-api b/external/ring-client-api index 8ef25acca..b0be15d20 160000 --- a/external/ring-client-api +++ b/external/ring-client-api @@ -1 +1 @@ -Subproject commit 8ef25acca66c533873b7fd43c7c899e34b4a7617 +Subproject commit b0be15d20b095aad72f321b6e2fb46895665fa4a diff --git a/plugins/ring/package-lock.json b/plugins/ring/package-lock.json index a55ebdf3d..4007dab1f 100644 --- a/plugins/ring/package-lock.json +++ b/plugins/ring/package-lock.json @@ -1,12 +1,12 @@ { "name": "@scrypted/ring", - "version": "0.0.7", + "version": "0.0.8", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@scrypted/ring", - "version": "0.0.7", + "version": "0.0.8", "dependencies": { "@homebridge/camera-utils": "^2.0.4", "@types/node": "^16.6.1", diff --git a/plugins/ring/package.json b/plugins/ring/package.json index 053a9d46c..02d7dc19b 100644 --- a/plugins/ring/package.json +++ b/plugins/ring/package.json @@ -28,7 +28,7 @@ "@homebridge/camera-utils": "^2.0.4", "@types/node": "^16.6.1", "axios": "^0.24.0", - "ring-client-api": "^9.23.0" + "ring-client-api": "../../external/ring-client-api" }, "optionalDependencies": { "got": "11.8.2" @@ -36,5 +36,5 @@ "devDependencies": { "@scrypted/sdk": "file:../../sdk" }, - "version": "0.0.7" + "version": "0.0.8" } diff --git a/plugins/ring/src/main.ts b/plugins/ring/src/main.ts index d36b8173b..bc012c40b 100644 --- a/plugins/ring/src/main.ts +++ b/plugins/ring/src/main.ts @@ -1,17 +1,15 @@ import { BinarySensor, Camera, Device, DeviceDiscovery, DeviceProvider, FFMpegInput, Intercom, MediaObject, MediaStreamOptions, MotionSensor, PictureOptions, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, SettingValue, VideoCamera } from '@scrypted/sdk'; import sdk from '@scrypted/sdk'; -import ring, { RingApi, RingCamera } from 'ring-client-api'; +import { SipSession, RingApi, RingCamera, RtpDescription, RingRestClient } from './ring-client-api'; import { StorageSettings } from '../../../common/src/settings'; import { listenZeroSingleClient } from '../../../common/src/listen-cluster'; -import { RingRestClient } from 'ring-client-api/lib/api/rest-client'; import { encodeSrtpOptions, RtpSplitter } from '@homebridge/camera-utils' -import { RtpDescription } from 'ring-client-api/lib/api/rtp-utils'; import child_process from 'child_process'; const { log, deviceManager, mediaManager } = sdk; class RingCameraDevice extends ScryptedDeviceBase implements Intercom, Camera, VideoCamera, MotionSensor, BinarySensor { - session: ring.SipSession; + session: SipSession; rtpDescription: RtpDescription; constructor(public plugin: RingPlugin, nativeId: string) { super(nativeId); @@ -34,47 +32,28 @@ class RingCameraDevice extends ScryptedDeviceBase implements Intercom, Camera, V // to the caller. // this is from sip - const { port, clientPromise } = await listenZeroSingleClient(); + const { clientPromise, url } = await listenZeroSingleClient(); const camera = this.findCamera(); const sip = await camera.createSipSession({ skipFfmpegCheck: true, }) - this.rtpDescription = await sip.start({ - output: [ - '-bsf:a', 'aac_adtstoasc', - '-flags', '+global_header', - '-f', 'mpegts', - `tcp://127.0.0.1:${port}`, - ], - }) - - const client = await clientPromise; - - this.session?.stop(); - this.session = undefined; - this.session = sip; - - // this is from the consumer - const passthrough = await listenZeroSingleClient(); - passthrough.clientPromise.then(pt => { - client.on('close', () => sip.stop()); - client.pipe(pt); + this.rtpDescription = await sip.start(); + const videoPort = await sip.reservePort(1); + const audioPort = await sip.reservePort(1); + + const ff = sip.prepareTranscoder(true, [], this.rtpDescription, audioPort, videoPort, url); + clientPromise.then(client => { + client.write(ff.inputSdpLines.filter((x) => Boolean(x)).join('\n')); + client.end(); }); - this.console.log(`sip output port: ${port}, consumer input port ${passthrough.port}`); - - sip.onCallEnded.subscribe(async () => { - const pt = await passthrough.clientPromise; - pt.destroy(); - }); + const index = ff.ffmpegInputArguments.indexOf('-protocol_whitelist'); + ff.ffmpegInputArguments.splice(index, 2); const ffmpegInput: FFMpegInput = { url: undefined, - inputArguments: [ - '-f', 'mpegts', - '-i', `tcp://127.0.0.1:${passthrough.port}`, - ] + inputArguments: ff.ffmpegInputArguments.filter(line => !!line).map(line => line.toString()), }; return mediaManager.createMediaObject(Buffer.from(JSON.stringify(ffmpegInput)), ScryptedMimeTypes.FFmpegInput); diff --git a/plugins/ring/src/ring-client-api.ts b/plugins/ring/src/ring-client-api.ts new file mode 100644 index 000000000..2d9363733 --- /dev/null +++ b/plugins/ring/src/ring-client-api.ts @@ -0,0 +1,11 @@ +// consolidate imports for source or dist release. +// import ring from 'ring-client-api' +// export default ring; +// export * from 'ring-client-api'; +// export { RingRestClient } from 'ring-client-api/lib/api/rest-client'; +// export { RtpDescription } from 'ring-client-api/lib/api/rtp-utils'; + +export * from '../../../external/ring-client-api/api/index' +export { RingRestClient } from '../../../external/ring-client-api/api/rest-client'; +export { RtpDescription } from '../../../external/ring-client-api/api/rtp-utils'; +