mirror of
https://github.com/koush/scrypted.git
synced 2026-05-04 21:30:30 +01:00
ring: a/v pipeline improvements
This commit is contained in:
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -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
|
||||
|
||||
@@ -31,6 +31,7 @@ export async function listenZeroSingleClient() {
|
||||
})
|
||||
|
||||
return {
|
||||
url: `tcp://127.0.0.1:${port}`,
|
||||
port,
|
||||
clientPromise,
|
||||
}
|
||||
|
||||
2
external/ring-client-api
vendored
2
external/ring-client-api
vendored
Submodule external/ring-client-api updated: 8ef25acca6...b0be15d20b
4
plugins/ring/package-lock.json
generated
4
plugins/ring/package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
11
plugins/ring/src/ring-client-api.ts
Normal file
11
plugins/ring/src/ring-client-api.ts
Normal file
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user