From 423a6d08315a32597dce7b667006503ece2794d6 Mon Sep 17 00:00:00 2001 From: GLDuval Date: Sat, 6 May 2023 15:33:04 -0400 Subject: [PATCH] Improve quality and add flipped and rotated configs --- package-lock.json | 57 --------------- script/rtspServer.js | 2 +- src/main/preload/api.ts | 2 +- src/main/rtspServer.ts | 10 +-- .../components/Feed/Feeds/CameraFeed.tsx | 8 +- .../components/Feed/Feeds/RTSPFeed.tsx | 73 +++++++++++++------ src/renderer/types/jsmpeg.d.ts | 6 +- 7 files changed, 69 insertions(+), 89 deletions(-) diff --git a/package-lock.json b/package-lock.json index a26ceafa..b755e1a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,6 @@ "lodash": "^4.17.21", "nanoid": "^3.3.1", "node-rtsp-stream": "^0.0.9", - "node-rtsp-stream-es6": "^1.0.7", "polished": "^4.1.4", "qr-scanner": "^1.4.1", "react": "^17.0.2", @@ -4616,11 +4615,6 @@ "node": ">=0.12.0" } }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -10839,11 +10833,6 @@ "node": ">=4" } }, - "node_modules/jsmpeg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jsmpeg/-/jsmpeg-1.0.0.tgz", - "integrity": "sha512-wlBKWVJ93NRJaCfrJ1KAgpMvZBLzpZxH3wnC1Yj7DudMDa/5hHeL1HfvW48ndR8GlI4irrqCXuOGhgayP9EbHw==" - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -11685,23 +11674,6 @@ "ws": "^7.0.0" } }, - "node_modules/node-rtsp-stream-es6": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/node-rtsp-stream-es6/-/node-rtsp-stream-es6-1.0.7.tgz", - "integrity": "sha512-UsOt0Ouj6ZY6AG4QMsDBtttUq2+0JfwdptW/bCjOKh3a1FmGmBLLgmMYZIi1V3uu++MBkZT7NWarJ0tKw+YdYw==", - "dependencies": { - "jsmpeg": "^1.0.0", - "ws": "7.1.2" - } - }, - "node_modules/node-rtsp-stream-es6/node_modules/ws": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.1.2.tgz", - "integrity": "sha512-gftXq3XI81cJCgkUiAVixA0raD9IVmXqsylCrjRygw4+UOOGzPoxnQ6r/CnVL9i+mDncJo94tSkyrtuuQVBmrg==", - "dependencies": { - "async-limiter": "^1.0.0" - } - }, "node_modules/nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", @@ -19339,11 +19311,6 @@ "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", "dev": true }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -24056,11 +24023,6 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, - "jsmpeg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jsmpeg/-/jsmpeg-1.0.0.tgz", - "integrity": "sha512-wlBKWVJ93NRJaCfrJ1KAgpMvZBLzpZxH3wnC1Yj7DudMDa/5hHeL1HfvW48ndR8GlI4irrqCXuOGhgayP9EbHw==" - }, "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -24722,25 +24684,6 @@ "ws": "^7.0.0" } }, - "node-rtsp-stream-es6": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/node-rtsp-stream-es6/-/node-rtsp-stream-es6-1.0.7.tgz", - "integrity": "sha512-UsOt0Ouj6ZY6AG4QMsDBtttUq2+0JfwdptW/bCjOKh3a1FmGmBLLgmMYZIi1V3uu++MBkZT7NWarJ0tKw+YdYw==", - "requires": { - "jsmpeg": "^1.0.0", - "ws": "7.1.2" - }, - "dependencies": { - "ws": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.1.2.tgz", - "integrity": "sha512-gftXq3XI81cJCgkUiAVixA0raD9IVmXqsylCrjRygw4+UOOGzPoxnQ6r/CnVL9i+mDncJo94tSkyrtuuQVBmrg==", - "requires": { - "async-limiter": "^1.0.0" - } - } - } - }, "nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", diff --git a/script/rtspServer.js b/script/rtspServer.js index 8eed879d..6f8383e6 100644 --- a/script/rtspServer.js +++ b/script/rtspServer.js @@ -9,7 +9,7 @@ new Stream({ wsPort: parseInt(args[1]), ffmpegOptions: { // options ffmpeg flags - '-stats': '', // an option with no neccessary value uses a blank string '-r': 30, // options with required values specify the value after the key + '-q': 0, // quality video in scale [0, 32] }, }); diff --git a/src/main/preload/api.ts b/src/main/preload/api.ts index 4283cbec..652ba973 100644 --- a/src/main/preload/api.ts +++ b/src/main/preload/api.ts @@ -33,6 +33,6 @@ export const preload = { }, rtsp: { start: (url: string) => ipcRenderer.invoke(RTSP_START, url), - stop: (url: string) => ipcRenderer.send(RTSP_STOP, url), + stop: (port: number) => ipcRenderer.send(RTSP_STOP, port), }, }; diff --git a/src/main/rtspServer.ts b/src/main/rtspServer.ts index 933e2a3b..ab65fa2b 100644 --- a/src/main/rtspServer.ts +++ b/src/main/rtspServer.ts @@ -9,7 +9,7 @@ interface RtspProcess { wsPort: number; } -const rtspServers: Map = new Map(); +const rtspServers: Map = new Map(); // Stack array of ports from (9000 to 9060) to use for rtsp servers const ports = Array.from({ length: 61 }, (_, i) => i + 9000); @@ -24,7 +24,7 @@ ipcMain.handle('rtsp_start', (event, url: string) => { nextPort.toString(), ]); - rtspServers.set(url, { + rtspServers.set(nextPort, { process, wsPort: nextPort, }); @@ -32,8 +32,8 @@ ipcMain.handle('rtsp_start', (event, url: string) => { return nextPort; }); -ipcMain.on('rtsp_stop', (event, url: string) => { - const rtspProcess = rtspServers.get(url); +ipcMain.on('rtsp_stop', (event, port: number) => { + const rtspProcess = rtspServers.get(port); if (!rtspProcess) { return; @@ -41,5 +41,5 @@ ipcMain.on('rtsp_stop', (event, url: string) => { log.info('stopping rtsp process'); ports.push(rtspProcess.wsPort); rtspProcess.process.kill(); - rtspServers.delete(url); + rtspServers.delete(port); }); diff --git a/src/renderer/components/Feed/Feeds/CameraFeed.tsx b/src/renderer/components/Feed/Feeds/CameraFeed.tsx index 2051209e..e7df6b83 100644 --- a/src/renderer/components/Feed/Feeds/CameraFeed.tsx +++ b/src/renderer/components/Feed/Feeds/CameraFeed.tsx @@ -147,7 +147,13 @@ const View: FC = ({ feed }) => { ); case CameraType.RTSP: - return ; + return ( + + ); default: return ; } diff --git a/src/renderer/components/Feed/Feeds/RTSPFeed.tsx b/src/renderer/components/Feed/Feeds/RTSPFeed.tsx index eb4d668f..111cccac 100644 --- a/src/renderer/components/Feed/Feeds/RTSPFeed.tsx +++ b/src/renderer/components/Feed/Feeds/RTSPFeed.tsx @@ -1,51 +1,78 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import JSMpeg from '@cycjimmy/jsmpeg-player'; import { log } from '@/renderer/logger'; interface Props { url: string; + flipped: boolean; + rotated: boolean; } -export const RTSPFeed = ({ url }: Props) => { +export const RTSPFeed = ({ url, flipped, rotated }: Props) => { const videoRef = useRef(null); const canvasRef = useRef(null); + const [port, setPort] = useState(null); + const [videoElement, setVideoElement] = + useState(); useEffect(() => { - log.info(`Starting RTSP server for ${url}`); const videoWrapper = videoRef.current; const canvas = canvasRef.current; - let videoElement: JSMpeg.VideoElement | null = null; const startServer = async () => { const port = (await window.preloadApi.rtsp.start(url)) as number; log.info(`RTSP server started on port ${port}`); if (videoWrapper && canvas) { - videoElement = new JSMpeg.VideoElement( - videoWrapper, - `ws://localhost:${port}`, - { - canvas, - autoplay: true, - audio: false, - } + setVideoElement( + new JSMpeg.VideoElement( + videoWrapper, + `ws://localhost:${port}`, + { + canvas, + autoplay: true, + audio: false, + }, + { videoBufferSize: 2048 * 2048 } + ) ); + setPort(port); } }; - startServer().catch((e) => log.error(e)); + if (!port && !videoElement) { + startServer().catch((e) => log.error(e)); + } return () => { - log.info('Stopping RTSP server'); - window.preloadApi.rtsp.stop(url); - if (videoElement) { - videoElement.destroy(); + if (port) { + log.info(`Stopping RTSP server for ${url}`); + window.preloadApi.rtsp.stop(port); + setPort(null); + if (videoElement) { + videoElement.destroy(); + } } }; - }, [url]); + }, [port, url, videoElement]); return ( - <> -
- -
- +
+ +
); }; diff --git a/src/renderer/types/jsmpeg.d.ts b/src/renderer/types/jsmpeg.d.ts index ad338839..7e181db1 100644 --- a/src/renderer/types/jsmpeg.d.ts +++ b/src/renderer/types/jsmpeg.d.ts @@ -7,9 +7,13 @@ declare module '@cycjimmy/jsmpeg-player' { canvas?: HTMLCanvasElement; autoplay?: boolean; audio?: boolean; + autoSetWrapperSize?: boolean; + }, + overlayOptions?: { + videoBufferSize?: number; } ); - + paused: boolean; destroy(): void; } }