From 7ca6d3fdfed9afc5edf8153a10095b7004908b7c Mon Sep 17 00:00:00 2001 From: Koushik Dutta Date: Tue, 5 Apr 2022 17:00:58 -0700 Subject: [PATCH] synology-ss: update readme, remove default stream as it is in rebroadcast now --- plugins/synology-ss/package-lock.json | 4 +- plugins/synology-ss/package.json | 2 +- plugins/synology-ss/src/main.ts | 39 ++++---------------- plugins/webrtc/src/ffmpeg-to-wrtc.ts | 22 +---------- plugins/webrtc/src/webrtc-required-codecs.ts | 21 +++++++++++ plugins/webrtc/src/wrtc-to-rtsp.ts | 37 +++---------------- 6 files changed, 39 insertions(+), 86 deletions(-) create mode 100644 plugins/webrtc/src/webrtc-required-codecs.ts diff --git a/plugins/synology-ss/package-lock.json b/plugins/synology-ss/package-lock.json index 24d660787..9a589365d 100644 --- a/plugins/synology-ss/package-lock.json +++ b/plugins/synology-ss/package-lock.json @@ -1,12 +1,12 @@ { "name": "@scrypted/synology-ss", - "version": "0.0.12", + "version": "0.0.13", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@scrypted/synology-ss", - "version": "0.0.12", + "version": "0.0.13", "license": "Apache", "dependencies": { "axios": "^0.24.0" diff --git a/plugins/synology-ss/package.json b/plugins/synology-ss/package.json index 743d3cee3..943300440 100644 --- a/plugins/synology-ss/package.json +++ b/plugins/synology-ss/package.json @@ -1,6 +1,6 @@ { "name": "@scrypted/synology-ss", - "version": "0.0.12", + "version": "0.0.13", "description": "A Synology Surveillance Station plugin for Scrypted", "author": "Scrypted", "license": "Apache", diff --git a/plugins/synology-ss/src/main.ts b/plugins/synology-ss/src/main.ts index 3d5d41239..e44e0c7d8 100644 --- a/plugins/synology-ss/src/main.ts +++ b/plugins/synology-ss/src/main.ts @@ -1,4 +1,4 @@ -import sdk, { ScryptedDeviceBase, DeviceProvider, HttpRequest, HttpRequestHandler, HttpResponse, Settings, Setting, ScryptedDeviceType, VideoCamera, MediaObject, Device, MotionSensor, ScryptedInterface, Camera, MediaStreamOptions, PictureOptions } from "@scrypted/sdk"; +import sdk, { ScryptedDeviceBase, DeviceProvider, HttpRequest, HttpRequestHandler, HttpResponse, Settings, Setting, ScryptedDeviceType, VideoCamera, MediaObject, Device, MotionSensor, ScryptedInterface, Camera, MediaStreamOptions, PictureOptions, ResponseMediaStreamOptions, ScryptedMimeTypes } from "@scrypted/sdk"; import { createInstanceableProviderPlugin, enableInstanceableProviderMode, isInstanceableProviderModeEnabled } from '../../../common/src/provider-plugin'; import { SynologyApiClient, SynologyCameraStream, SynologyCamera } from "./api/synology-api-client"; @@ -19,26 +19,10 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, HttpReq this.streams = SynologyCameraDevice.identifyStreams(camera); } - private getDefaultStream(vsos: MediaStreamOptions[]) { - let defaultStreamIndex = vsos.findIndex(vso => vso.id === this.storage.getItem('defaultStream')); - if (defaultStreamIndex === -1) - defaultStreamIndex = 0; - - return vsos[defaultStreamIndex]; - } - public async getSettings(): Promise { const vsos = await this.getVideoStreamOptions(); - const defaultStream = this.getDefaultStream(vsos); return [ - { - title: 'Default Stream', - key: 'defaultStream', - value: defaultStream?.name, - choices: vsos.map(vso => vso.name), - description: 'The default stream to use when not specified', - }, { title: 'Motion Sensor Timeout', key: 'sensorTimeout', @@ -57,14 +41,7 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, HttpReq } public async putSetting(key: string, value: string | number | boolean) { - if (key === 'defaultStream') { - const vsos = await this.getVideoStreamOptions(); - const stream = vsos.find(vso => vso.name === value); - this.storage.setItem('defaultStream', stream?.id); - } - else { - this.storage.setItem(key, value?.toString()); - } + this.storage.setItem(key, value?.toString()); this.onDeviceEvent(ScryptedInterface.Settings, undefined); } @@ -87,12 +64,12 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, HttpReq public async takePicture(options?: PictureOptions): Promise { const buffer = await this.getSnapshot(options); - return mediaManager.createMediaObject(buffer, 'image/jpeg'); + return this.createMediaObject(buffer, 'image/jpeg'); } public async getVideoStream(options?: MediaStreamOptions): Promise { const vsos = await this.getVideoStreamOptions(); - const vso = vsos.find(check => check.id === options?.id) || this.getDefaultStream(vsos); + const vso = vsos.find(check => check.id === options?.id) || vsos[0]; const rtspChannel = this.streams.find(check => check.id === vso.id); @@ -113,18 +90,18 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, HttpReq rtspPath = liveViewPaths[0].rtspPath; } - return mediaManager.createFFmpegMediaObject({ + return this.createMediaObject({ url: rtspPath, inputArguments: [ "-rtsp_transport", "tcp", "-i", rtspPath, ], mediaStreamOptions: this.createMediaStreamOptions(rtspChannel), - }); + }, ScryptedMimeTypes.FFmpegInput); } private createMediaStreamOptions(stream: SynologyCameraStream) { - const ret: MediaStreamOptions = { + const ret: ResponseMediaStreamOptions = { id: stream.id, name: stream.id, container: 'rtsp', @@ -142,7 +119,7 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, HttpReq return ret; } - public async getVideoStreamOptions(): Promise { + public async getVideoStreamOptions(): Promise { const vsos = this.streams.map(channel => this.createMediaStreamOptions(channel)); return vsos; } diff --git a/plugins/webrtc/src/ffmpeg-to-wrtc.ts b/plugins/webrtc/src/ffmpeg-to-wrtc.ts index 9ec229751..de3dc6523 100644 --- a/plugins/webrtc/src/ffmpeg-to-wrtc.ts +++ b/plugins/webrtc/src/ffmpeg-to-wrtc.ts @@ -11,29 +11,11 @@ import ip from 'ip'; import { WebRTCOutputSignalingSession } from "./output-signaling-session"; import { getFFmpegRtpAudioOutputArguments, startRtpForwarderProcess } from "./rtp-forwarders"; import { ScryptedSessionControl } from "./session-control"; +import { requiredAudioCodec, requiredVideoCodec } from "./webrtc-required-codecs"; import { WebRTCStorageSettingsKeys } from "./webrtc-storage-settings"; import { isPeerConnectionAlive } from "./werift-util"; -const { mediaManager, systemManager, deviceManager } = sdk; - -const requiredVideoCodec = new RTCRtpCodecParameters({ - mimeType: "video/H264", - clockRate: 90000, - rtcpFeedback: [ - { type: "transport-cc" }, - { type: "ccm", parameter: "fir" }, - { type: "nack" }, - { type: "nack", parameter: "pli" }, - { type: "goog-remb" }, - ], - parameters: 'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f' -}); - -const requiredAudioCodec = new RTCRtpCodecParameters({ - mimeType: "audio/opus", - clockRate: 48000, - channels: 2, -}); +const { mediaManager } = sdk; function createSetup(audioDirection: RTCRtpTransceiverDirection, videoDirection: RTCRtpTransceiverDirection): Partial { return { diff --git a/plugins/webrtc/src/webrtc-required-codecs.ts b/plugins/webrtc/src/webrtc-required-codecs.ts new file mode 100644 index 000000000..a39774940 --- /dev/null +++ b/plugins/webrtc/src/webrtc-required-codecs.ts @@ -0,0 +1,21 @@ +import { RTCRtpCodecParameters } from "@koush/werift"; +import sdk, { } from "@scrypted/sdk"; + +export const requiredVideoCodec = new RTCRtpCodecParameters({ + mimeType: "video/H264", + clockRate: 90000, + rtcpFeedback: [ + { type: "transport-cc" }, + { type: "ccm", parameter: "fir" }, + { type: "nack" }, + { type: "nack", parameter: "pli" }, + { type: "goog-remb" }, + ], + parameters: 'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f' +}); + +export const requiredAudioCodec = new RTCRtpCodecParameters({ + mimeType: "audio/opus", + clockRate: 48000, + channels: 2, +}); diff --git a/plugins/webrtc/src/wrtc-to-rtsp.ts b/plugins/webrtc/src/wrtc-to-rtsp.ts index 3b1e0e1e9..b75fcaa34 100644 --- a/plugins/webrtc/src/wrtc-to-rtsp.ts +++ b/plugins/webrtc/src/wrtc-to-rtsp.ts @@ -9,6 +9,7 @@ import { ChildProcess } from "child_process"; import dgram from 'dgram'; import { Socket } from "net"; import { getFFmpegRtpAudioOutputArguments, startRtpForwarderProcess } from "./rtp-forwarders"; +import { requiredAudioCodec, requiredVideoCodec } from "./webrtc-required-codecs"; import { createRawResponse, isPeerConnectionAlive } from "./werift-util"; const { mediaManager } = sdk; @@ -60,11 +61,9 @@ export async function createRTCPeerConnectionSource(options: { const pc = new RTCPeerConnection({ codecs: { audio: [ - new RTCRtpCodecParameters({ - mimeType: "audio/opus", - clockRate: 48000, - channels: 2, - }), + requiredAudioCodec, + // these are some other option templates that may be worth considering + // for fast path. // new RTCRtpCodecParameters({ // mimeType: "audio/opus", // clockRate: 8000, @@ -82,33 +81,7 @@ export async function createRTCPeerConnectionSource(options: { // }), ], video: [ - // h264 high - // new RTCRtpCodecParameters( - // { - // clockRate: 90000, - // mimeType: "video/H264", - // rtcpFeedback: [ - // { type: "transport-cc" }, - // { type: "ccm", parameter: "fir" }, - // { type: "nack" }, - // { type: "nack", parameter: "pli" }, - // { type: "goog-remb" }, - // ], - // parameters: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640c1f" - // }, - // ), - new RTCRtpCodecParameters({ - mimeType: "video/H264", - clockRate: 90000, - rtcpFeedback: [ - { type: "transport-cc" }, - { type: "ccm", parameter: "fir" }, - { type: "nack" }, - { type: "nack", parameter: "pli" }, - { type: "goog-remb" }, - ], - parameters: 'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f' - }) + requiredVideoCodec, ], } });