From ab238ab12625f73c40f4fe6e685191e49ae03798 Mon Sep 17 00:00:00 2001 From: hrstv <5302419+hrstv@users.noreply.github.com> Date: Tue, 22 Mar 2022 20:18:45 -0700 Subject: [PATCH] synology-ss: support for sub streams --- .../src/api/synology-api-client.ts | 33 +++++++++++++++++++ plugins/synology-ss/src/main.ts | 25 ++++++++++---- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/plugins/synology-ss/src/api/synology-api-client.ts b/plugins/synology-ss/src/api/synology-api-client.ts index 899b5de34..5a7b0bee7 100644 --- a/plugins/synology-ss/src/api/synology-api-client.ts +++ b/plugins/synology-ss/src/api/synology-api-client.ts @@ -82,6 +82,21 @@ export class SynologyApiClient { return response.cameras; } + public async getCameraInfo(cameraId: number | string): Promise { + const params = { + api: 'SYNO.SurveillanceStation.Camera', + version: 8, + method: 'GetInfo', + privCamType: 1, + streamInfo: true, + cameraIds: cameraId + }; + + const response = await this.sendRequest(params); + + return response.cameras[0]; + } + public async login(account: string, password: string, otpCode?: number, enableDeviceToken: boolean = false, deviceName?: string, deviceId?: string): Promise { const params = { @@ -225,3 +240,21 @@ export interface SynologyCameraStream { quality?: string; constantBitrate?: string; } + +export interface SynologyCameraInfoResponse { + cameras: SynologyCameraInfo[]; +} + +export interface SynologyCameraInfo { + id: string; + stm_info: SynologyCameraInfoStream[]; +} + +export interface SynologyCameraInfoStream { + camPath?: string; + fps?: number; + quality?: string; + resolution?: string; + stmNo?: number; + type?: number; +} diff --git a/plugins/synology-ss/src/main.ts b/plugins/synology-ss/src/main.ts index 0a6d18c5d..3d5d41239 100644 --- a/plugins/synology-ss/src/main.ts +++ b/plugins/synology-ss/src/main.ts @@ -1,6 +1,6 @@ import sdk, { ScryptedDeviceBase, DeviceProvider, HttpRequest, HttpRequestHandler, HttpResponse, Settings, Setting, ScryptedDeviceType, VideoCamera, MediaObject, Device, MotionSensor, ScryptedInterface, Camera, MediaStreamOptions, PictureOptions } from "@scrypted/sdk"; import { createInstanceableProviderPlugin, enableInstanceableProviderMode, isInstanceableProviderModeEnabled } from '../../../common/src/provider-plugin'; -import {SynologyApiClient, SynologyCameraStream, SynologyCamera} from "./api/synology-api-client"; +import { SynologyApiClient, SynologyCameraStream, SynologyCamera } from "./api/synology-api-client"; const { deviceManager, mediaManager } = sdk; @@ -96,15 +96,28 @@ class SynologyCameraDevice extends ScryptedDeviceBase implements Camera, HttpReq const rtspChannel = this.streams.find(check => check.id === vso.id); - const liveViewPaths = await this.provider.api.getCameraLiveViewPath([this.nativeId]); - if (!liveViewPaths?.length) - throw new Error(`Unable to locate RTSP stream for camera ${this.nativeId}`); + let rtspPath = null; + + if (vso.id !== '1') { + const cameraInfo = await this.provider.api.getCameraInfo(this.nativeId); + const camStream = cameraInfo?.stm_info?.find(el => el.stmNo.toString() == vso.id); + if (camStream) + rtspPath = Buffer.from(camStream.camPath, 'base64').toString('binary') + } + + if (!rtspPath) { + const liveViewPaths = await this.provider.api.getCameraLiveViewPath([this.nativeId]); + if (!liveViewPaths?.length) + throw new Error(`Unable to locate RTSP stream for camera ${this.nativeId}`); + + rtspPath = liveViewPaths[0].rtspPath; + } return mediaManager.createFFmpegMediaObject({ - url: liveViewPaths[0].rtspPath, + url: rtspPath, inputArguments: [ "-rtsp_transport", "tcp", - "-i", liveViewPaths[0].rtspPath, + "-i", rtspPath, ], mediaStreamOptions: this.createMediaStreamOptions(rtspChannel), });