iobroker.eusec 2.0.0-alpha.1 → 2.0.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,129 +1,92 @@
1
- ![Logo](docs/_media/ioBroker.euSec.png)
2
- # ioBroker.euSec
3
-
4
- [![NPM version](https://img.shields.io/npm/v/iobroker.eusec.svg)](https://www.npmjs.com/package/iobroker.eusec)
5
- [![Downloads](https://img.shields.io/npm/dm/iobroker.eusec.svg)](https://www.npmjs.com/package/iobroker.eusec)
6
- [![Total Downloads](https://img.shields.io/npm/dt/iobroker.eusec.svg)](https://www.npmjs.com/package/iobroker.eusec)
7
- ![Node version requirement](https://img.shields.io/node/v/iobroker.eusec)
8
- ![Number of Installations (latest)](https://iobroker.live/badges/eusec-installed.svg)
9
- ![Number of Installations (stable)](https://iobroker.live/badges/eusec-stable.svg)
10
- [![Dependency Status](https://img.shields.io/librariesio/release/npm/iobroker.eusec)](https://libraries.io/npm/iobroker.eusec)
11
-
12
- **Tests:** ![Test and Release](https://github.com/iobroker-community-adapters/ioBroker.eusec/workflows/Test%20and%20Release/badge.svg)
13
-
14
- [![NPM](https://nodei.co/npm/iobroker.eusec.png?downloads=true)](https://nodei.co/npm/iobroker.eusec/)
15
-
16
- This is an [ioBroker](https://www.iobroker.net) adapter that uses the [eufy-security-client](https://github.com/bropat/eufy-security-client) library to comunicate with Eufy devices.
17
-
18
- **This project is not affiliated with Anker and Eufy (Eufy Security). It is a personal project that is maintained in spare time.**
19
-
20
- ## Description
21
-
22
- This adapter allows to control [Eufy security devices](https://us.eufylife.com/collections/security) by connecting to the Eufy cloud servers and local/remote stations.
23
-
24
- You need to provide your Cloud login credentials. The adapter connects to your cloud account and polls for all device data via HTTPS. Now a local or remote P2P connection to the Eufy stations/devices is also supported. However, a connection to the Eufy Cloud is always a prerequisite.
25
-
26
- One Adapter instance will show all devices from one Eufy Cloud account and allows to control them.
27
-
28
- ## Documentation
29
-
30
- Checkout the documentation [here](https://iobroker-community-adapters.github.io/ioBroker.eusec/).
31
-
32
- ## Known working devices
33
-
34
- Information about supported devices can be found [here](https://github.com/bropat/eufy-security-client#known-working-devices).
35
-
36
- ## Credits
37
-
38
- This adapter would not have been possible without the great work of Patrick Broetto (brobat) <https://github.com/bropat>, who created previous releases of this adapter.
39
-
40
- ## Changelog
41
-
42
- <!--
43
- Placeholder for the next version (at the beginning of the line):
44
- ### **WORK IN PROGRESS**
1
+ ![Logo](docs/_media/ioBroker.euSec.png)
2
+ # ioBroker.euSec
3
+
4
+ [![NPM version](https://img.shields.io/npm/v/iobroker.eusec.svg)](https://www.npmjs.com/package/iobroker.eusec)
5
+ [![Downloads](https://img.shields.io/npm/dm/iobroker.eusec.svg)](https://www.npmjs.com/package/iobroker.eusec)
6
+ [![Total Downloads](https://img.shields.io/npm/dt/iobroker.eusec.svg)](https://www.npmjs.com/package/iobroker.eusec)
7
+ ![Node version requirement](https://img.shields.io/node/v/iobroker.eusec)
8
+ ![Number of Installations (latest)](https://iobroker.live/badges/eusec-installed.svg)
9
+ ![Number of Installations (stable)](https://iobroker.live/badges/eusec-stable.svg)
10
+ [![Dependency Status](https://img.shields.io/librariesio/release/npm/iobroker.eusec)](https://libraries.io/npm/iobroker.eusec)
11
+
12
+ **Tests:** ![Test and Release](https://github.com/iobroker-community-adapters/ioBroker.eusec/workflows/Test%20and%20Release/badge.svg)
13
+
14
+ [![NPM](https://nodei.co/npm/iobroker.eusec.png?downloads=true)](https://nodei.co/npm/iobroker.eusec/)
15
+
16
+ This is an [ioBroker](https://www.iobroker.net) adapter that uses the [eufy-security-client](https://github.com/bropat/eufy-security-client) library to comunicate with Eufy devices.
17
+
18
+ **This project is not affiliated with Anker and Eufy (Eufy Security). It is a personal project that is maintained in spare time.**
19
+
20
+ ## Description
21
+
22
+ This adapter allows to control [Eufy security devices](https://us.eufylife.com/collections/security) by connecting to the Eufy cloud servers and local/remote stations.
23
+
24
+ You need to provide your Cloud login credentials. The adapter connects to your cloud account and polls for all device data via HTTPS. Now a local or remote P2P connection to the Eufy stations/devices is also supported. However, a connection to the Eufy Cloud is always a prerequisite.
25
+
26
+ One Adapter instance will show all devices from one Eufy Cloud account and allows to control them.
27
+
28
+ ## Documentation
29
+
30
+ Checkout the documentation [here](https://iobroker-community-adapters.github.io/ioBroker.eusec/).
31
+
32
+ ## Known working devices
33
+
34
+ Information about supported devices can be found [here](https://github.com/bropat/eufy-security-client#known-working-devices).
35
+
36
+ ## Credits
37
+
38
+ This adapter would not have been possible without the great work of Patrick Broetto (brobat) <https://github.com/bropat>, who created previous releases of this adapter.
39
+
40
+ ## Changelog
41
+
42
+ <!--
43
+ Placeholder for the next version (at the beginning of the line):
44
+ ### **WORK IN PROGRESS**
45
45
  -->
46
- ### 2.0.0-alpha.1 (2025-10-26)
47
-
48
- - (mcm1957) Adapter has been migrated to iobroker-community-adapters organisation
49
- - (mcm1957) Adapter requires node.js >= 20, js-controller >= 6.0.11 and admin >= 7.6.17 now
46
+ ### 2.0.1-alpha.0 (2025-10-26)
47
+ - (mcm1957) Remove fix for CVE-2023-46809 for node.js 22 and newer
48
+
49
+ ### 2.0.0 (2025-10-26)
50
+
51
+ - (mcm1957) Adapter has been migrated to iobroker-community-adapters organisation
52
+ - (mcm1957) Adapter requires node.js >= 20, js-controller >= 6.0.11 and admin >= 7.6.17 now
50
53
  - (mcm1957) Dependencies have been updated
51
54
 
52
- ### 1.3.3 (2024-09-28)
53
-
54
- * (bropat) Updated version of the package eufy-security-client (3.1.1)
55
+ ### 1.3.3 (2024-09-28)
56
+
57
+ * (bropat) Updated version of the package eufy-security-client (3.1.1)
55
58
  * (bropat) Further details can be found in the changelog of eufy-security-client (3.1.1)
56
59
 
57
- ### 1.3.2 (2024-09-10)
58
-
60
+ ### 1.3.2 (2024-09-10)
61
+
59
62
  * (bropat) Fixed issue #440
60
63
 
61
- ### 1.3.1 (2024-09-08)
62
-
63
- * (bropat) Fixed issue #436
64
+ ### 1.3.1 (2024-09-08)
65
+
66
+ * (bropat) Fixed issue #436
64
67
  * (bropat) Fixed issue #439
65
68
 
66
- ### 1.3.0 (2024-08-27)
67
-
68
- * (bropat) Requires ioBroker.admin version >= 7.0.12
69
- * (bropat) Requires ioBroker.js-controller version >= 6.0.0
70
- * (bropat) Requires node version >= 20
71
- * (bropat) Added new setting to choose country indipendently of ioBroker setting
72
- * (bropat) New go2rtc streaming implementation
73
- * (bropat) Added messagebox support (sendTo) to exhibit new commands (snooze #294, chime, quickResponse, getQuickResponseVoices, pollRefresh)
74
- * (bropat) Fixed deletion of obsolete devices, channels and states
75
- * (bropat) Added support for Video Smart Lock S330 (T8530)
76
- * (bropat) Added support for Smart Lock C210 (T8502)
77
- * (bropat) Added support for Smart Lock C220 (T8506)
78
- * (bropat) Added support for Smart Lock S230 (T8510P)
79
- * (bropat) Added support for Smart Lock S231 (T8520P)
80
- * (bropat) Added support for Retrofit Smart Lock E110 (T8503)
81
- * (bropat) Added support for Retrofit Smart Lock E130 (T8504)
82
- * (bropat) Added support for Smart Drop S300 (T8790)
83
- * (bropat/martijnpoppen) Added support for Video Doorbell E340 (T8214)
84
- * (martijnpoppen) Added support for MiniBase Chime (T8023)
85
- * (bropat/martijnpoppen) Added support for eufyCam E330 (Professional; T8600; #391)
86
- * (bropat/martijnpoppen) Added support for Solar Wall Light Cam S120 (T84A0; #406)
87
- * (bropat/martijnpoppen) Added support for SoloCam S340 (T8170; #399)
88
- * (bropat) Added support for Indoor Cam S350 (T8416; #403)
89
- * (bropat) Added support for Floodlight Cam E340 (T8425, #428)
90
- * (bropat) Added support for SoloCam C210 (T8B00)
91
- * (bropat) Storage of files switched to [Meta-Storage](https://iobroker.readthedocs.io/de/latest/bestpractice/storefiles.html#meta-storage)
92
- * (bropat) Implemented workaround for livestreaming issue introduced by CVE-2023-46809 in Node.js (18.19.1=<; 20.11.1=<; 21.6.2=<)
93
- * (bropat) Changed ffmpeg static package from `ffmpeg-static` to `ffmpeg-for-homebridge`
94
- * (bropat) Fixed issue #432
95
- * (bropat) Fixed issue #422
96
- * (bropat) Fixed issue #420
97
- * (bropat) Fixed issue #387
98
- * (bropat) Fixed issue #380
99
- * (bropat) Fixed issue #379
100
- * (bropat) Fixed issue #376
101
- * (bropat) Fixed issue #371
102
- * (bropat) Updated version of the package go2rtc-static (1.8.5)
103
- * (bropat) Updated version of the package eufy-security-client (3.0.0)
104
- * (bropat) Further details can be found in the changelog of eufy-security-client (3.0.0)
105
-
106
- ## License
107
-
108
- MIT License
109
-
110
- Copyright (c) 2025 iobroker-community-adapters <iobroker-community-adapters@gmx.de>
111
- Copyright (c) 2020-2024 bropat <patrick.broetto@gmail.com>
112
-
113
- Permission is hereby granted, free of charge, to any person obtaining a copy
114
- of this software and associated documentation files (the "Software"), to deal
115
- in the Software without restriction, including without limitation the rights
116
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
117
- copies of the Software, and to permit persons to whom the Software is
118
- furnished to do so, subject to the following conditions:
119
-
120
- The above copyright notice and this permission notice shall be included in all
121
- copies or substantial portions of the Software.
122
-
123
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
124
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
125
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
126
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
127
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
128
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
69
+ ## License
70
+
71
+ MIT License
72
+
73
+ Copyright (c) 2025 iobroker-community-adapters <iobroker-community-adapters@gmx.de>
74
+ Copyright (c) 2020-2024 bropat <patrick.broetto@gmail.com>
75
+
76
+ Permission is hereby granted, free of charge, to any person obtaining a copy
77
+ of this software and associated documentation files (the "Software"), to deal
78
+ in the Software without restriction, including without limitation the rights
79
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
80
+ copies of the Software, and to permit persons to whom the Software is
81
+ furnished to do so, subject to the following conditions:
82
+
83
+ The above copyright notice and this permission notice shall be included in all
84
+ copies or substantial portions of the Software.
85
+
86
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
87
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
88
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
89
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
90
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
91
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
129
92
  SOFTWARE.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/video.ts"],
4
- "sourcesContent": ["import net from \"net\";\r\nimport path from \"path\";\r\nimport ffmpeg from \"@bropat/fluent-ffmpeg\";\r\nimport pathToFfmpeg from \"ffmpeg-for-homebridge\";\r\nimport { Readable } from \"stream\";\r\nimport { StreamMetadata, AudioCodec, VideoCodec } from \"eufy-security-client\";\r\nimport { tmpdir } from \"os\";\r\nimport fse from \"fs-extra\";\r\n\r\nimport stream from \"node:stream\";\r\nimport {pipeline as streamPipeline} from \"node:stream/promises\";\r\n\r\nimport { ioBrokerLogger } from \"./log\";\r\nimport { getShortUrl, lowestUnusedNumber } from \"./utils\";\r\n\r\nclass UniversalStream {\r\n\r\n public url: string;\r\n private static socks = new Set<number>();\r\n private server: net.Server;\r\n private sock_id: number;\r\n\r\n constructor (namespace: string, onSocket: ((socket: net.Socket) => void) | undefined) {\r\n let sockpath = \"\";\r\n\r\n const unique_sock_id = lowestUnusedNumber([...UniversalStream.socks], 1);\r\n UniversalStream.socks.add(unique_sock_id);\r\n this.sock_id = unique_sock_id;\r\n\r\n if (process.platform === \"win32\") {\r\n const pipePrefix = \"\\\\\\\\.\\\\pipe\\\\\";\r\n const pipeName = `node-webrtc.${namespace}.${unique_sock_id}.sock`;\r\n\r\n sockpath = path.join(pipePrefix, pipeName);\r\n this.url = sockpath;\r\n }\r\n else {\r\n const pipeName = `${namespace}.${unique_sock_id}.sock`;\r\n sockpath = path.join(tmpdir(), pipeName);\r\n this.url = \"unix:\" + sockpath;\r\n\r\n try {\r\n if (fse.existsSync(sockpath))\r\n fse.unlinkSync(sockpath);\r\n } catch(error) {\r\n }\r\n }\r\n\r\n this.server = net.createServer(onSocket);\r\n this.server.listen(sockpath);\r\n this.server.on(\"error\", () => {});\r\n }\r\n\r\n public close(): void {\r\n if (this.server)\r\n this.server.close();\r\n UniversalStream.socks.delete(this.sock_id);\r\n }\r\n\r\n}\r\n\r\nexport const StreamInput = function(namespace: string, stream: NodeJS.ReadableStream): UniversalStream {\r\n return new UniversalStream(namespace, (socket: net.Socket) => stream.pipe(socket, { end: true }).on(\"error\", (_error) => {\r\n //TODO: log error\r\n }));\r\n}\r\n\r\nexport const StreamOutput = function(namespace: string, stream: NodeJS.WritableStream): UniversalStream {\r\n return new UniversalStream(namespace, (socket: net.Socket) => socket.pipe(stream, { end: true }).on(\"error\", (_error) => {\r\n //TODO: log error\r\n }));\r\n}\r\n\r\nexport const ffmpegPreviewImage = (config: ioBroker.AdapterConfig, input:string, output: string, log: ioBrokerLogger, skip_seconds = 2.0): Promise<void> => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .addOptions([\r\n `-ss ${skip_seconds}`,\r\n \"-frames:v 1\"\r\n ])\r\n .input(input)\r\n .inputFormat(\"hls\")\r\n .outputFormat(\"image2\")\r\n .output(output)\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegPreviewImage(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegPreviewImage(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegPreviewImage(): ffmpeg stderr:\\n${stderr}`);\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegPreviewImage(): Preview image generated!\");\r\n resolve();\r\n })\r\n .run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegPreviewImage(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nexport const ffmpegStreamToHls = (config: ioBroker.AdapterConfig, namespace: string, metadata: StreamMetadata, videoStream: Readable, audioStream: Readable, output: string, log: ioBrokerLogger): Promise<void> => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n videoStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToHls(): Videostream Error\", error);\r\n });\r\n\r\n audioStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToHls(): Audiostream Error\", error);\r\n });\r\n\r\n const uVideoStream = StreamInput(namespace, videoStream);\r\n const uAudioStream = StreamInput(namespace, audioStream);\r\n\r\n let videoFormat = \"h264\";\r\n let audioFormat = \"\";\r\n const options: string[] = [\r\n \"-hls_init_time 0\",\r\n \"-hls_time 2\",\r\n \"-hls_segment_type mpegts\",\r\n //\"-start_number 1\",\r\n \"-sc_threshold 0\",\r\n `-g ${metadata.videoFPS}`,\r\n \"-fflags genpts+nobuffer+flush_packets\",\r\n //\"-flush_packets 1\",\r\n \"-hls_playlist_type event\"\r\n //\"-hls_flags split_by_time\"\r\n ];\r\n\r\n switch(metadata.videoCodec) {\r\n case VideoCodec.H264:\r\n videoFormat = \"h264\";\r\n break;\r\n case VideoCodec.H265:\r\n videoFormat = \"hevc\";\r\n break;\r\n }\r\n\r\n switch(metadata.audioCodec) {\r\n case AudioCodec.AAC:\r\n audioFormat = \"aac\";\r\n break;\r\n }\r\n\r\n const command = ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .input(uVideoStream.url)\r\n .inputFormat(videoFormat)\r\n .inputFps(metadata.videoFPS);\r\n if (audioFormat !== \"\") {\r\n command.input(uAudioStream.url)\r\n .inputFormat(audioFormat)\r\n .videoCodec(\"copy\")\r\n .audioCodec(\"copy\");\r\n options.push(\"-absf aac_adtstoasc\");\r\n } else {\r\n log.warn(`ffmpegStreamToHls(): Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`);\r\n }\r\n command.output(output)\r\n .addOptions(options)\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegStreamToHls(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegStreamToHls(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegStreamToHls(): ffmpeg stderr:\\n${stderr}`);\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegStreamToHls(): Processing finished!\");\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n resolve();\r\n });\r\n command.run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegStreamToHls(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nexport const ffmpegStreamToGo2rtc = (config: ioBroker.AdapterConfig, namespace: string, camera: string, metadata: StreamMetadata, videoStream: Readable, audioStream: Readable, log: ioBrokerLogger): Promise<void> => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n videoStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToGo2rtc(): Videostream Error\", error);\r\n });\r\n\r\n audioStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToGo2rtc(): Audiostream Error\", error);\r\n });\r\n\r\n //TODO: For debugging purposes\r\n /*const outputVFile = path.resolve(__dirname, \"../../video-stream.dump\");\r\n videoStream.pipe(fse.createWriteStream(outputVFile)).on(\"finish\", () => {\r\n log.debug(\"videoStream dump finished!\");\r\n log.info(\"Manually test the output by running# ffplay output/video-stream.dump\");\r\n });\r\n const outputAFile = path.resolve(__dirname, \"../../audio-stream.dump\");\r\n audioStream.pipe(fse.createWriteStream(outputAFile)).on(\"finish\", () => {\r\n log.debug(\"audioStream dump finished!\");\r\n log.info(\"Manually test the output by running# ffplay output/audio-stream.dump\");\r\n });*/\r\n\r\n const uVideoStream = StreamInput(namespace, videoStream);\r\n const uAudioStream = StreamInput(namespace, audioStream);\r\n\r\n let videoFormat = \"h264\";\r\n let audioFormat = \"\";\r\n const options: string[] = [\r\n \"-rtsp_transport tcp\",\r\n \"-sc_threshold 0\",\r\n \"-fflags genpts+nobuffer+flush_packets\",\r\n //\"-rtpflags latm\",\r\n ];\r\n\r\n switch(metadata.videoCodec) {\r\n case VideoCodec.H264:\r\n videoFormat = \"h264\";\r\n break;\r\n case VideoCodec.H265:\r\n videoFormat = \"hevc\";\r\n break;\r\n }\r\n\r\n switch(metadata.audioCodec) {\r\n case AudioCodec.AAC:\r\n audioFormat = \"aac\";\r\n break;\r\n }\r\n\r\n const command = ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .input(uVideoStream.url)\r\n .inputFormat(videoFormat);\r\n if (metadata.videoFPS > 0 ) {\r\n options.push(`-g ${metadata.videoFPS}`);\r\n command.inputFps(metadata.videoFPS);\r\n }\r\n command.videoCodec(\"copy\");\r\n if (audioFormat !== \"\") {\r\n command.input(uAudioStream.url)\r\n .inputFormat(audioFormat)\r\n //.audioCodec(\"copy\");\r\n //.audioCodec(\"aac\");\r\n .audioCodec(\"opus\");\r\n } else {\r\n log.warn(`ffmpegStreamToGo2rtc(): Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`);\r\n }\r\n command.output(`rtsp://localhost:${config.go2rtc_rtsp_port}/${camera}`)\r\n .outputFormat(\"rtsp\")\r\n .addOptions(options)\r\n .on(\"start\", (commandline) => {\r\n log.debug(`ffmpegStreamToGo2rtc(): commandline: ${commandline}`);\r\n })\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegStreamToGo2rtc(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegStreamToGo2rtc(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegStreamToGo2rtc(): ffmpeg stderr:\\n${stderr}`);\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegStreamToGo2rtc(): Processing finished!\");\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n resolve();\r\n });\r\n command.run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegStreamToGo2rtc(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nexport const streamToGo2rtc = async (camera: string, videoStream: Readable, audioStream: Readable, log: ioBrokerLogger, _config: ioBroker.AdapterConfig, _namespace: string, _metadata: StreamMetadata): Promise<Array<PromiseSettledResult<void>>> => {\r\n const { default: got } = await import(\"got\");\r\n const api = got.extend({\r\n hooks: {\r\n beforeError: [\r\n error => {\r\n const { response, options } = error;\r\n const { method, url, prefixUrl } = options;\r\n const shortUrl = getShortUrl(typeof url === \"string\" ? new URL(url) : url === undefined ? new URL(\"\") : url, typeof prefixUrl === \"string\" ? prefixUrl : prefixUrl.toString());\r\n const body = response?.body ? response.body : error.message;\r\n error.message = `${error.message} | method: ${method} url: ${shortUrl}`;\r\n if (response?.body) {\r\n error.message = `${error.message} body: ${body}`;\r\n }\r\n return error;\r\n }\r\n ],\r\n }\r\n });\r\n videoStream.on(\"error\", (error) => {\r\n log.error(\"streamToGo2rtc(): Videostream Error\", error);\r\n });\r\n\r\n audioStream.on(\"error\", (error) => {\r\n log.error(\"streamToGo2rtc(): Audiostream Error\", error);\r\n });\r\n return Promise.allSettled([\r\n streamPipeline(\r\n videoStream,\r\n api.stream.post(`http://localhost:1984/api/stream?dst=${camera}`).on(\"error\", (error: any) => {\r\n if (!(error.response?.body as string)?.startsWith(\"EOF\")) {\r\n log.error(`streamToGo2rtc(): Got Videostream Error: ${error.message}`);\r\n }\r\n }),\r\n new stream.PassThrough()\r\n ),\r\n streamPipeline(\r\n audioStream,\r\n api.stream.post(`http://localhost:1984/api/stream?dst=${camera}`).on(\"error\", (error: any) => {\r\n if (!(error.response?.body as string)?.startsWith(\"EOF\")) {\r\n log.error(`streamToGo2rtc(): Got Audiostream Error: ${error.message}`);\r\n }\r\n }),\r\n new stream.PassThrough()\r\n )\r\n // Alternative implementation in case of go2rtc audio bitstream isn't working (<= 1.8.5)\r\n /*new Promise<void>((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n const uAudioStream = StreamInput(namespace, audioStream);\r\n\r\n let audioFormat = \"\";\r\n const options: string[] = [\r\n \"-rtsp_transport tcp\",\r\n \"-fflags genpts+nobuffer+flush_packets\",\r\n //\"-rtpflags latm\",\r\n //\"-compression_level 5\",\r\n \"-application lowdelay\",\r\n ];\r\n\r\n switch(metadata.audioCodec) {\r\n case AudioCodec.AAC:\r\n audioFormat = \"aac\";\r\n break;\r\n }\r\n\r\n const command = ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n });\r\n\r\n if (audioFormat !== \"\") {\r\n command.input(uAudioStream.url)\r\n .inputFormat(audioFormat)\r\n .audioCodec(\"opus\");\r\n } else {\r\n log.warn(`streamToGo2rtc(): ffmpeg - Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`);\r\n }\r\n command.output(`rtsp://localhost:${config.go2rtc_rtsp_port}/${camera}`)\r\n .outputFormat(\"rtsp\")\r\n .addOptions(options)\r\n .on(\"start\", (commandline) => {\r\n log.debug(`streamToGo2rtc(): ffmpeg - commandline: ${commandline}`);\r\n })\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`streamToGo2rtc(): ffmpeg - An error occurred: ${err.message}`);\r\n log.error(`streamToGo2rtc(): ffmpeg output:\\n${stdout}`);\r\n log.error(`streamToGo2rtc(): ffmpeg stderr:\\n${stderr}`);\r\n uAudioStream.close();\r\n reject(err);\r\n })\r\n .on(\"end\", (stdout, stderr) => {\r\n log.debug(`streamToGo2rtc(): ffmpeg output:\\n${stdout}`);\r\n log.debug(`streamToGo2rtc(): ffmpeg stderr:\\n${stderr}`);\r\n log.debug(\"streamToGo2rtc(): Processing finished!\");\r\n uAudioStream.close();\r\n resolve();\r\n });\r\n command.run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`streamToGo2rtc(): Audio Error: ${error}`);\r\n reject(error);\r\n }\r\n })*/\r\n ]);\r\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import net from \"net\";\r\nimport path from \"path\";\r\nimport ffmpeg from \"@bropat/fluent-ffmpeg\";\r\nimport pathToFfmpeg from \"ffmpeg-for-homebridge\";\r\nimport { Readable } from \"stream\";\r\nimport { StreamMetadata, AudioCodec, VideoCodec } from \"eufy-security-client\";\r\nimport { tmpdir } from \"os\";\r\nimport fse from \"fs-extra\";\r\n\r\nimport stream from \"node:stream\";\r\nimport {pipeline as streamPipeline} from \"node:stream/promises\";\r\n\r\nimport { ioBrokerLogger } from \"./log\";\r\nimport { getShortUrl, lowestUnusedNumber } from \"./utils\";\r\n\r\nclass UniversalStream {\r\n\r\n public url: string;\r\n private static socks = new Set<number>();\r\n private server: net.Server;\r\n private sock_id: number;\r\n\r\n constructor (namespace: string, onSocket: ((socket: net.Socket) => void) | undefined) {\r\n let sockpath = \"\";\r\n\r\n const unique_sock_id = lowestUnusedNumber([...UniversalStream.socks], 1);\r\n UniversalStream.socks.add(unique_sock_id);\r\n this.sock_id = unique_sock_id;\r\n\r\n if (process.platform === \"win32\") {\r\n const pipePrefix = \"\\\\\\\\.\\\\pipe\\\\\";\r\n const pipeName = `node-webrtc.${namespace}.${unique_sock_id}.sock`;\r\n\r\n sockpath = path.join(pipePrefix, pipeName);\r\n this.url = sockpath;\r\n }\r\n else {\r\n const pipeName = `${namespace}.${unique_sock_id}.sock`;\r\n sockpath = path.join(tmpdir(), pipeName);\r\n this.url = \"unix:\" + sockpath;\r\n\r\n try {\r\n if (fse.existsSync(sockpath))\r\n fse.unlinkSync(sockpath);\r\n } catch(error) {\r\n }\r\n }\r\n\r\n this.server = net.createServer(onSocket);\r\n this.server.listen(sockpath);\r\n this.server.on(\"error\", () => {});\r\n }\r\n\r\n public close(): void {\r\n if (this.server)\r\n this.server.close();\r\n UniversalStream.socks.delete(this.sock_id);\r\n }\r\n\r\n}\r\n\r\nexport const StreamInput = function(namespace: string, stream: NodeJS.ReadableStream): UniversalStream {\r\n return new UniversalStream(namespace, (socket: net.Socket) => stream.pipe(socket, { end: true }).on(\"error\", (_error) => {\r\n //TODO: log error\r\n }));\r\n}\r\n\r\nexport const StreamOutput = function(namespace: string, stream: NodeJS.WritableStream): UniversalStream {\r\n return new UniversalStream(namespace, (socket: net.Socket) => socket.pipe(stream, { end: true }).on(\"error\", (_error) => {\r\n //TODO: log error\r\n }));\r\n}\r\n\r\nexport const ffmpegPreviewImage = (config: ioBroker.AdapterConfig, input:string, output: string, log: ioBrokerLogger, skip_seconds = 2.0): Promise<void> => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n // @ts-expect-error old code\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .addOptions([\r\n `-ss ${skip_seconds}`,\r\n \"-frames:v 1\"\r\n ])\r\n .input(input)\r\n .inputFormat(\"hls\")\r\n .outputFormat(\"image2\")\r\n .output(output)\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegPreviewImage(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegPreviewImage(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegPreviewImage(): ffmpeg stderr:\\n${stderr}`);\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegPreviewImage(): Preview image generated!\");\r\n resolve();\r\n })\r\n .run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegPreviewImage(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nexport const ffmpegStreamToHls = (config: ioBroker.AdapterConfig, namespace: string, metadata: StreamMetadata, videoStream: Readable, audioStream: Readable, output: string, log: ioBrokerLogger): Promise<void> => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n // @ts-expect-error old code\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n videoStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToHls(): Videostream Error\", error);\r\n });\r\n\r\n audioStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToHls(): Audiostream Error\", error);\r\n });\r\n\r\n const uVideoStream = StreamInput(namespace, videoStream);\r\n const uAudioStream = StreamInput(namespace, audioStream);\r\n\r\n let videoFormat = \"h264\";\r\n let audioFormat = \"\";\r\n const options: string[] = [\r\n \"-hls_init_time 0\",\r\n \"-hls_time 2\",\r\n \"-hls_segment_type mpegts\",\r\n //\"-start_number 1\",\r\n \"-sc_threshold 0\",\r\n `-g ${metadata.videoFPS}`,\r\n \"-fflags genpts+nobuffer+flush_packets\",\r\n //\"-flush_packets 1\",\r\n \"-hls_playlist_type event\"\r\n //\"-hls_flags split_by_time\"\r\n ];\r\n\r\n switch(metadata.videoCodec) {\r\n case VideoCodec.H264:\r\n videoFormat = \"h264\";\r\n break;\r\n case VideoCodec.H265:\r\n videoFormat = \"hevc\";\r\n break;\r\n }\r\n\r\n switch(metadata.audioCodec) {\r\n case AudioCodec.AAC:\r\n audioFormat = \"aac\";\r\n break;\r\n }\r\n\r\n const command = ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .input(uVideoStream.url)\r\n .inputFormat(videoFormat)\r\n .inputFps(metadata.videoFPS);\r\n if (audioFormat !== \"\") {\r\n command.input(uAudioStream.url)\r\n .inputFormat(audioFormat)\r\n .videoCodec(\"copy\")\r\n .audioCodec(\"copy\");\r\n options.push(\"-absf aac_adtstoasc\");\r\n } else {\r\n log.warn(`ffmpegStreamToHls(): Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`);\r\n }\r\n command.output(output)\r\n .addOptions(options)\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegStreamToHls(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegStreamToHls(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegStreamToHls(): ffmpeg stderr:\\n${stderr}`);\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegStreamToHls(): Processing finished!\");\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n resolve();\r\n });\r\n command.run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegStreamToHls(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nexport const ffmpegStreamToGo2rtc = (config: ioBroker.AdapterConfig, namespace: string, camera: string, metadata: StreamMetadata, videoStream: Readable, audioStream: Readable, log: ioBrokerLogger): Promise<void> => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n // @ts-expect-error old code\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n videoStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToGo2rtc(): Videostream Error\", error);\r\n });\r\n\r\n audioStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToGo2rtc(): Audiostream Error\", error);\r\n });\r\n\r\n //TODO: For debugging purposes\r\n /*const outputVFile = path.resolve(__dirname, \"../../video-stream.dump\");\r\n videoStream.pipe(fse.createWriteStream(outputVFile)).on(\"finish\", () => {\r\n log.debug(\"videoStream dump finished!\");\r\n log.info(\"Manually test the output by running# ffplay output/video-stream.dump\");\r\n });\r\n const outputAFile = path.resolve(__dirname, \"../../audio-stream.dump\");\r\n audioStream.pipe(fse.createWriteStream(outputAFile)).on(\"finish\", () => {\r\n log.debug(\"audioStream dump finished!\");\r\n log.info(\"Manually test the output by running# ffplay output/audio-stream.dump\");\r\n });*/\r\n\r\n const uVideoStream = StreamInput(namespace, videoStream);\r\n const uAudioStream = StreamInput(namespace, audioStream);\r\n\r\n let videoFormat = \"h264\";\r\n let audioFormat = \"\";\r\n const options: string[] = [\r\n \"-rtsp_transport tcp\",\r\n \"-sc_threshold 0\",\r\n \"-fflags genpts+nobuffer+flush_packets\",\r\n //\"-rtpflags latm\",\r\n ];\r\n\r\n switch(metadata.videoCodec) {\r\n case VideoCodec.H264:\r\n videoFormat = \"h264\";\r\n break;\r\n case VideoCodec.H265:\r\n videoFormat = \"hevc\";\r\n break;\r\n }\r\n\r\n switch(metadata.audioCodec) {\r\n case AudioCodec.AAC:\r\n audioFormat = \"aac\";\r\n break;\r\n }\r\n\r\n const command = ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .input(uVideoStream.url)\r\n .inputFormat(videoFormat);\r\n if (metadata.videoFPS > 0 ) {\r\n options.push(`-g ${metadata.videoFPS}`);\r\n command.inputFps(metadata.videoFPS);\r\n }\r\n command.videoCodec(\"copy\");\r\n if (audioFormat !== \"\") {\r\n command.input(uAudioStream.url)\r\n .inputFormat(audioFormat)\r\n //.audioCodec(\"copy\");\r\n //.audioCodec(\"aac\");\r\n .audioCodec(\"opus\");\r\n } else {\r\n log.warn(`ffmpegStreamToGo2rtc(): Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`);\r\n }\r\n command.output(`rtsp://localhost:${config.go2rtc_rtsp_port}/${camera}`)\r\n .outputFormat(\"rtsp\")\r\n .addOptions(options)\r\n .on(\"start\", (commandline) => {\r\n log.debug(`ffmpegStreamToGo2rtc(): commandline: ${commandline}`);\r\n })\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegStreamToGo2rtc(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegStreamToGo2rtc(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegStreamToGo2rtc(): ffmpeg stderr:\\n${stderr}`);\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegStreamToGo2rtc(): Processing finished!\");\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n resolve();\r\n });\r\n command.run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegStreamToGo2rtc(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nexport const streamToGo2rtc = async (camera: string, videoStream: Readable, audioStream: Readable, log: ioBrokerLogger, _config: ioBroker.AdapterConfig, _namespace: string, _metadata: StreamMetadata): Promise<Array<PromiseSettledResult<void>>> => {\r\n const { default: got } = await import(\"got\");\r\n const api = got.extend({\r\n hooks: {\r\n beforeError: [\r\n error => {\r\n const { response, options } = error;\r\n const { method, url, prefixUrl } = options;\r\n const shortUrl = getShortUrl(typeof url === \"string\" ? new URL(url) : url === undefined ? new URL(\"\") : url, typeof prefixUrl === \"string\" ? prefixUrl : prefixUrl.toString());\r\n const body = response?.body ? response.body : error.message;\r\n error.message = `${error.message} | method: ${method} url: ${shortUrl}`;\r\n if (response?.body) {\r\n error.message = `${error.message} body: ${body}`;\r\n }\r\n return error;\r\n }\r\n ],\r\n }\r\n });\r\n videoStream.on(\"error\", (error) => {\r\n log.error(\"streamToGo2rtc(): Videostream Error\", error);\r\n });\r\n\r\n audioStream.on(\"error\", (error) => {\r\n log.error(\"streamToGo2rtc(): Audiostream Error\", error);\r\n });\r\n return Promise.allSettled([\r\n streamPipeline(\r\n videoStream,\r\n api.stream.post(`http://localhost:1984/api/stream?dst=${camera}`).on(\"error\", (error: any) => {\r\n if (!(error.response?.body as string)?.startsWith(\"EOF\")) {\r\n log.error(`streamToGo2rtc(): Got Videostream Error: ${error.message}`);\r\n }\r\n }),\r\n new stream.PassThrough()\r\n ),\r\n streamPipeline(\r\n audioStream,\r\n api.stream.post(`http://localhost:1984/api/stream?dst=${camera}`).on(\"error\", (error: any) => {\r\n if (!(error.response?.body as string)?.startsWith(\"EOF\")) {\r\n log.error(`streamToGo2rtc(): Got Audiostream Error: ${error.message}`);\r\n }\r\n }),\r\n new stream.PassThrough()\r\n )\r\n // Alternative implementation in case of go2rtc audio bitstream isn't working (<= 1.8.5)\r\n /*new Promise<void>((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n const uAudioStream = StreamInput(namespace, audioStream);\r\n\r\n let audioFormat = \"\";\r\n const options: string[] = [\r\n \"-rtsp_transport tcp\",\r\n \"-fflags genpts+nobuffer+flush_packets\",\r\n //\"-rtpflags latm\",\r\n //\"-compression_level 5\",\r\n \"-application lowdelay\",\r\n ];\r\n\r\n switch(metadata.audioCodec) {\r\n case AudioCodec.AAC:\r\n audioFormat = \"aac\";\r\n break;\r\n }\r\n\r\n const command = ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n });\r\n\r\n if (audioFormat !== \"\") {\r\n command.input(uAudioStream.url)\r\n .inputFormat(audioFormat)\r\n .audioCodec(\"opus\");\r\n } else {\r\n log.warn(`streamToGo2rtc(): ffmpeg - Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`);\r\n }\r\n command.output(`rtsp://localhost:${config.go2rtc_rtsp_port}/${camera}`)\r\n .outputFormat(\"rtsp\")\r\n .addOptions(options)\r\n .on(\"start\", (commandline) => {\r\n log.debug(`streamToGo2rtc(): ffmpeg - commandline: ${commandline}`);\r\n })\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`streamToGo2rtc(): ffmpeg - An error occurred: ${err.message}`);\r\n log.error(`streamToGo2rtc(): ffmpeg output:\\n${stdout}`);\r\n log.error(`streamToGo2rtc(): ffmpeg stderr:\\n${stderr}`);\r\n uAudioStream.close();\r\n reject(err);\r\n })\r\n .on(\"end\", (stdout, stderr) => {\r\n log.debug(`streamToGo2rtc(): ffmpeg output:\\n${stdout}`);\r\n log.debug(`streamToGo2rtc(): ffmpeg stderr:\\n${stderr}`);\r\n log.debug(\"streamToGo2rtc(): Processing finished!\");\r\n uAudioStream.close();\r\n resolve();\r\n });\r\n command.run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`streamToGo2rtc(): Audio Error: ${error}`);\r\n reject(error);\r\n }\r\n })*/\r\n ]);\r\n}"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAgB;AAChB,kBAAiB;AACjB,2BAAmB;AACnB,mCAAyB;AAEzB,kCAAuD;AACvD,gBAAuB;AACvB,sBAAgB;AAEhB,yBAAmB;AACnB,sBAAyC;AAGzC,mBAAgD;AAEhD,MAAM,gBAAgB;AAAA,EAEX;AAAA,EACP,OAAe,QAAQ,oBAAI,IAAY;AAAA,EAC/B;AAAA,EACA;AAAA,EAER,YAAa,WAAmB,UAAsD;AAClF,QAAI,WAAW;AAEf,UAAM,qBAAiB,iCAAmB,CAAC,GAAG,gBAAgB,KAAK,GAAG,CAAC;AACvE,oBAAgB,MAAM,IAAI,cAAc;AACxC,SAAK,UAAU;AAEf,QAAI,QAAQ,aAAa,SAAS;AAC9B,YAAM,aAAa;AACnB,YAAM,WAAW,eAAe,SAAS,IAAI,cAAc;AAE3D,iBAAW,YAAAA,QAAK,KAAK,YAAY,QAAQ;AACzC,WAAK,MAAM;AAAA,IACf,OACK;AACD,YAAM,WAAW,GAAG,SAAS,IAAI,cAAc;AAC/C,iBAAW,YAAAA,QAAK,SAAK,kBAAO,GAAG,QAAQ;AACvC,WAAK,MAAM,UAAU;AAErB,UAAI;AACA,YAAI,gBAAAC,QAAI,WAAW,QAAQ;AACvB,0BAAAA,QAAI,WAAW,QAAQ;AAAA,MAC/B,SAAQ,OAAO;AAAA,MACf;AAAA,IACJ;AAEA,SAAK,SAAS,WAAAC,QAAI,aAAa,QAAQ;AACvC,SAAK,OAAO,OAAO,QAAQ;AAC3B,SAAK,OAAO,GAAG,SAAS,MAAM;AAAA,IAAC,CAAC;AAAA,EACpC;AAAA,EAEO,QAAc;AACjB,QAAI,KAAK;AACL,WAAK,OAAO,MAAM;AACtB,oBAAgB,MAAM,OAAO,KAAK,OAAO;AAAA,EAC7C;AAEJ;AAEO,MAAM,cAAc,SAAS,WAAmBC,SAAgD;AACnG,SAAO,IAAI,gBAAgB,WAAW,CAAC,WAAuBA,QAAO,KAAK,QAAQ,EAAE,KAAK,KAAK,CAAC,EAAE,GAAG,SAAS,CAAC,WAAW;AAAA,EAEzH,CAAC,CAAC;AACN;AAEO,MAAM,eAAe,SAAS,WAAmBA,SAAgD;AACpG,SAAO,IAAI,gBAAgB,WAAW,CAAC,WAAuB,OAAO,KAAKA,SAAQ,EAAE,KAAK,KAAK,CAAC,EAAE,GAAG,SAAS,CAAC,WAAW;AAAA,EAEzH,CAAC,CAAC;AACN;AAEO,MAAM,qBAAqB,CAAC,QAAgC,OAAc,QAAgB,KAAqB,eAAe,MAAuB;AACxJ,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,QAAI;AACA,UAAI,6BAAAC,SAAc;AAEd,6BAAAC,QAAO,cAAc,6BAAAD,OAAY;AAEjC,iCAAAC,SAAO,EACF,mBAAmB;AAAA,UAChB,UAAU;AAAA,QACd,CAAC,EACA,WAAW;AAAA,UACR,OAAO,YAAY;AAAA,UACnB;AAAA,QACJ,CAAC,EACA,MAAM,KAAK,EACX,YAAY,KAAK,EACjB,aAAa,QAAQ,EACrB,OAAO,MAAM,EACb,GAAG,SAAS,SAAS,KAAK,QAAQ,QAAQ;AACvC,cAAI,MAAM,4CAA4C,IAAI,OAAO,EAAE;AACnE,cAAI,MAAM;AAAA,EAAyC,MAAM,EAAE;AAC3D,cAAI,MAAM;AAAA,EAAyC,MAAM,EAAE;AAC3D,iBAAO,GAAG;AAAA,QACd,CAAC,EACA,GAAG,OAAO,MAAM;AACb,cAAI,MAAM,gDAAgD;AAC1D,kBAAQ;AAAA,QACZ,CAAC,EACA,IAAI;AAAA,MACb,OAAO;AACH,eAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC/C;AAAA,IACJ,SAAS,OAAO;AACZ,UAAI,MAAM,gCAAgC,KAAK,EAAE;AACjD,aAAO,KAAK;AAAA,IAChB;AAAA,EACJ,CAAC;AACL;AAEO,MAAM,oBAAoB,CAAC,QAAgC,WAAmB,UAA0B,aAAuB,aAAuB,QAAgB,QAAuC;AAChN,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,QAAI;AACA,UAAI,6BAAAD,SAAc;AAEd,6BAAAC,QAAO,cAAc,6BAAAD,OAAY;AAEjC,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,0CAA0C,KAAK;AAAA,QAC7D,CAAC;AAED,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,0CAA0C,KAAK;AAAA,QAC7D,CAAC;AAED,cAAM,eAAe,YAAY,WAAW,WAAW;AACvD,cAAM,eAAe,YAAY,WAAW,WAAW;AAEvD,YAAI,cAAc;AAClB,YAAI,cAAc;AAClB,cAAM,UAAoB;AAAA,UACtB;AAAA,UACA;AAAA,UACA;AAAA;AAAA,UAEA;AAAA,UACA,MAAM,SAAS,QAAQ;AAAA,UACvB;AAAA;AAAA,UAEA;AAAA;AAAA,QAEJ;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,UACJ,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,cAAM,cAAU,qBAAAC,SAAO,EAClB,mBAAmB;AAAA,UAChB,UAAU;AAAA,QACd,CAAC,EACA,MAAM,aAAa,GAAG,EACtB,YAAY,WAAW,EACvB,SAAS,SAAS,QAAQ;AAC/B,YAAI,gBAAgB,IAAI;AACpB,kBAAQ,MAAM,aAAa,GAAG,EACzB,YAAY,WAAW,EACvB,WAAW,MAAM,EACjB,WAAW,MAAM;AACtB,kBAAQ,KAAK,qBAAqB;AAAA,QACtC,OAAO;AACH,cAAI,KAAK,wEAAwE,uCAAW,SAAS,UAAU,CAAC,GAAG;AAAA,QACvH;AACA,gBAAQ,OAAO,MAAM,EAChB,WAAW,OAAO,EAClB,GAAG,SAAS,SAAS,KAAK,QAAQ,QAAQ;AACvC,cAAI,MAAM,2CAA2C,IAAI,OAAO,EAAE;AAClE,cAAI,MAAM;AAAA,EAAwC,MAAM,EAAE;AAC1D,cAAI,MAAM;AAAA,EAAwC,MAAM,EAAE;AAC1D,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,iBAAO,GAAG;AAAA,QACd,CAAC,EACA,GAAG,OAAO,MAAM;AACb,cAAI,MAAM,2CAA2C;AACrD,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,kBAAQ;AAAA,QACZ,CAAC;AACL,gBAAQ,IAAI;AAAA,MAChB,OAAO;AACH,eAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC/C;AAAA,IACJ,SAAS,OAAO;AACZ,UAAI,MAAM,+BAA+B,KAAK,EAAE;AAChD,aAAO,KAAK;AAAA,IAChB;AAAA,EACJ,CAAC;AACL;AAEO,MAAM,uBAAuB,CAAC,QAAgC,WAAmB,QAAgB,UAA0B,aAAuB,aAAuB,QAAuC;AACnN,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,QAAI;AACA,UAAI,6BAAAD,SAAc;AAEd,6BAAAC,QAAO,cAAc,6BAAAD,OAAY;AAEjC,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,6CAA6C,KAAK;AAAA,QAChE,CAAC;AAED,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,6CAA6C,KAAK;AAAA,QAChE,CAAC;AAcD,cAAM,eAAe,YAAY,WAAW,WAAW;AACvD,cAAM,eAAe,YAAY,WAAW,WAAW;AAEvD,YAAI,cAAc;AAClB,YAAI,cAAc;AAClB,cAAM,UAAoB;AAAA,UACtB;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAEJ;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,UACJ,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,cAAM,cAAU,qBAAAC,SAAO,EAClB,mBAAmB;AAAA,UAChB,UAAU;AAAA,QACd,CAAC,EACA,MAAM,aAAa,GAAG,EACtB,YAAY,WAAW;AAC5B,YAAI,SAAS,WAAW,GAAI;AACxB,kBAAQ,KAAK,MAAM,SAAS,QAAQ,EAAE;AACtC,kBAAQ,SAAS,SAAS,QAAQ;AAAA,QACtC;AACA,gBAAQ,WAAW,MAAM;AACzB,YAAI,gBAAgB,IAAI;AACpB,kBAAQ,MAAM,aAAa,GAAG,EACzB,YAAY,WAAW,EAGvB,WAAW,MAAM;AAAA,QAC1B,OAAO;AACH,cAAI,KAAK,2EAA2E,uCAAW,SAAS,UAAU,CAAC,GAAG;AAAA,QAC1H;AACA,gBAAQ,OAAO,oBAAoB,OAAO,gBAAgB,IAAI,MAAM,EAAE,EACjE,aAAa,MAAM,EACnB,WAAW,OAAO,EAClB,GAAG,SAAS,CAAC,gBAAgB;AAC1B,cAAI,MAAM,wCAAwC,WAAW,EAAE;AAAA,QACnE,CAAC,EACA,GAAG,SAAS,SAAS,KAAK,QAAQ,QAAQ;AACvC,cAAI,MAAM,8CAA8C,IAAI,OAAO,EAAE;AACrE,cAAI,MAAM;AAAA,EAA2C,MAAM,EAAE;AAC7D,cAAI,MAAM;AAAA,EAA2C,MAAM,EAAE;AAC7D,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,iBAAO,GAAG;AAAA,QACd,CAAC,EACA,GAAG,OAAO,MAAM;AACb,cAAI,MAAM,8CAA8C;AACxD,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,kBAAQ;AAAA,QACZ,CAAC;AACL,gBAAQ,IAAI;AAAA,MAChB,OAAO;AACH,eAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC/C;AAAA,IACJ,SAAS,OAAO;AACZ,UAAI,MAAM,kCAAkC,KAAK,EAAE;AACnD,aAAO,KAAK;AAAA,IAChB;AAAA,EACJ,CAAC;AACL;AAEO,MAAM,iBAAiB,OAAO,QAAgB,aAAuB,aAAuB,KAAqB,SAAiC,YAAoB,cAA0E;AACnP,QAAM,EAAE,SAAS,IAAI,IAAI,MAAM,OAAO,KAAK;AAC3C,QAAM,MAAM,IAAI,OAAO;AAAA,IACnB,OAAO;AAAA,MACH,aAAa;AAAA,QACT,WAAS;AACL,gBAAM,EAAE,UAAU,QAAQ,IAAI;AAC9B,gBAAM,EAAE,QAAQ,KAAK,UAAU,IAAI;AACnC,gBAAM,eAAW,0BAAY,OAAO,QAAQ,WAAW,IAAI,IAAI,GAAG,IAAI,QAAQ,SAAY,IAAI,IAAI,EAAE,IAAI,KAAK,OAAO,cAAc,WAAW,YAAY,UAAU,SAAS,CAAC;AAC7K,gBAAM,QAAO,qCAAU,QAAO,SAAS,OAAO,MAAM;AACpD,gBAAM,UAAU,GAAG,MAAM,OAAO,cAAc,MAAM,SAAS,QAAQ;AACrE,cAAI,qCAAU,MAAM;AAChB,kBAAM,UAAU,GAAG,MAAM,OAAO,UAAU,IAAI;AAAA,UAClD;AACA,iBAAO;AAAA,QACX;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,CAAC;AACD,cAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,QAAI,MAAM,uCAAuC,KAAK;AAAA,EAC1D,CAAC;AAED,cAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,QAAI,MAAM,uCAAuC,KAAK;AAAA,EAC1D,CAAC;AACD,SAAO,QAAQ,WAAW;AAAA,QACtB,gBAAAC;AAAA,MACI;AAAA,MACA,IAAI,OAAO,KAAK,wCAAwC,MAAM,EAAE,EAAE,GAAG,SAAS,CAAC,UAAe;AAlV1G;AAmVgB,YAAI,GAAE,iBAAM,aAAN,mBAAgB,SAAhB,mBAAiC,WAAW,SAAQ;AACtD,cAAI,MAAM,4CAA4C,MAAM,OAAO,EAAE;AAAA,QACzE;AAAA,MACJ,CAAC;AAAA,MACD,IAAI,mBAAAH,QAAO,YAAY;AAAA,IAC3B;AAAA,QACA,gBAAAG;AAAA,MACI;AAAA,MACA,IAAI,OAAO,KAAK,wCAAwC,MAAM,EAAE,EAAE,GAAG,SAAS,CAAC,UAAe;AA3V1G;AA4VgB,YAAI,GAAE,iBAAM,aAAN,mBAAgB,SAAhB,mBAAiC,WAAW,SAAQ;AACtD,cAAI,MAAM,4CAA4C,MAAM,OAAO,EAAE;AAAA,QACzE;AAAA,MACJ,CAAC;AAAA,MACD,IAAI,mBAAAH,QAAO,YAAY;AAAA,IAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiEJ,CAAC;AACL;",
6
6
  "names": ["path", "fse", "net", "stream", "pathToFfmpeg", "ffmpeg", "streamPipeline"]
7
7
  }
package/build/main.js CHANGED
@@ -210,14 +210,14 @@ class euSec extends utils.Adapter {
210
210
  const nodeMajorVersion = nodeVersion.split(".")[0];
211
211
  let fixNeeded;
212
212
  switch (parseInt(nodeMajorVersion)) {
213
- case 18:
214
- fixNeeded = nodeVersion.localeCompare("18.19.1", void 0, { numeric: true, sensitivity: "base" });
215
- break;
213
+ // node 18 is no longer supported
216
214
  case 20:
217
215
  fixNeeded = nodeVersion.localeCompare("20.11.1", void 0, { numeric: true, sensitivity: "base" });
218
216
  break;
217
+ // node 21 is and was not supported
218
+ // node 22 and newer do NOT require any fix
219
219
  default:
220
- fixNeeded = nodeVersion.localeCompare("21.6.2", void 0, { numeric: true, sensitivity: "base" });
220
+ fixNeeded = -1;
221
221
  break;
222
222
  }
223
223
  if (fixNeeded >= 0) {
@@ -317,6 +317,7 @@ class euSec extends utils.Adapter {
317
317
  "listen": `:${this.config.go2rtc_webrtc_port}`
318
318
  },
319
319
  "ffmpeg": {
320
+ // @ts-expect-error old code
320
321
  "bin": import_ffmpeg_for_homebridge.default !== "" && import_ffmpeg_for_homebridge.default !== void 0 ? import_ffmpeg_for_homebridge.default : "ffmpeg"
321
322
  },
322
323
  "streams": {}