iobroker.eusec 2.0.2 → 3.0.2

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.
@@ -36,15 +36,16 @@ __export(video_exports, {
36
36
  streamToGo2rtc: () => streamToGo2rtc
37
37
  });
38
38
  module.exports = __toCommonJS(video_exports);
39
- var import_net = __toESM(require("net"));
40
- var import_path = __toESM(require("path"));
39
+ var import_node_net = __toESM(require("node:net"));
40
+ var import_node_path = __toESM(require("node:path"));
41
41
  var import_fluent_ffmpeg = __toESM(require("@bropat/fluent-ffmpeg"));
42
42
  var import_ffmpeg_for_homebridge = __toESM(require("ffmpeg-for-homebridge"));
43
43
  var import_eufy_security_client = require("eufy-security-client");
44
- var import_os = require("os");
44
+ var import_node_os = require("node:os");
45
45
  var import_fs_extra = __toESM(require("fs-extra"));
46
46
  var import_node_stream = __toESM(require("node:stream"));
47
47
  var import_promises = require("node:stream/promises");
48
+ var import_go2rtc = require("./go2rtc");
48
49
  var import_utils = require("./utils");
49
50
  class UniversalStream {
50
51
  url;
@@ -52,43 +53,50 @@ class UniversalStream {
52
53
  server;
53
54
  sock_id;
54
55
  constructor(namespace, onSocket) {
55
- let sockpath = "";
56
+ let sockPath = "";
56
57
  const unique_sock_id = (0, import_utils.lowestUnusedNumber)([...UniversalStream.socks], 1);
57
58
  UniversalStream.socks.add(unique_sock_id);
58
59
  this.sock_id = unique_sock_id;
59
60
  if (process.platform === "win32") {
60
61
  const pipePrefix = "\\\\.\\pipe\\";
61
62
  const pipeName = `node-webrtc.${namespace}.${unique_sock_id}.sock`;
62
- sockpath = import_path.default.join(pipePrefix, pipeName);
63
- this.url = sockpath;
63
+ sockPath = import_node_path.default.join(pipePrefix, pipeName);
64
+ this.url = sockPath;
64
65
  } else {
65
66
  const pipeName = `${namespace}.${unique_sock_id}.sock`;
66
- sockpath = import_path.default.join((0, import_os.tmpdir)(), pipeName);
67
- this.url = "unix:" + sockpath;
67
+ sockPath = import_node_path.default.join((0, import_node_os.tmpdir)(), pipeName);
68
+ this.url = `unix:${sockPath}`;
68
69
  try {
69
- if (import_fs_extra.default.existsSync(sockpath))
70
- import_fs_extra.default.unlinkSync(sockpath);
71
- } catch (error) {
70
+ if (import_fs_extra.default.existsSync(sockPath)) {
71
+ import_fs_extra.default.unlinkSync(sockPath);
72
+ }
73
+ } catch {
72
74
  }
73
75
  }
74
- this.server = import_net.default.createServer(onSocket);
75
- this.server.listen(sockpath);
76
+ this.server = import_node_net.default.createServer(onSocket);
77
+ this.server.listen(sockPath);
76
78
  this.server.on("error", () => {
77
79
  });
78
80
  }
79
81
  close() {
80
- if (this.server)
81
- this.server.close();
82
+ var _a;
83
+ (_a = this.server) == null ? void 0 : _a.close();
82
84
  UniversalStream.socks.delete(this.sock_id);
83
85
  }
84
86
  }
85
87
  const StreamInput = function(namespace, stream2) {
86
- return new UniversalStream(namespace, (socket) => stream2.pipe(socket, { end: true }).on("error", (_error) => {
87
- }));
88
+ return new UniversalStream(
89
+ namespace,
90
+ (socket) => stream2.pipe(socket, { end: true }).on("error", (_error) => {
91
+ })
92
+ );
88
93
  };
89
94
  const StreamOutput = function(namespace, stream2) {
90
- return new UniversalStream(namespace, (socket) => socket.pipe(stream2, { end: true }).on("error", (_error) => {
91
- }));
95
+ return new UniversalStream(
96
+ namespace,
97
+ (socket) => socket.pipe(stream2, { end: true }).on("error", (_error) => {
98
+ })
99
+ );
92
100
  };
93
101
  const ffmpegPreviewImage = (config, input, output, log, skip_seconds = 2) => {
94
102
  return new Promise((resolve, reject) => {
@@ -97,10 +105,7 @@ const ffmpegPreviewImage = (config, input, output, log, skip_seconds = 2) => {
97
105
  import_fluent_ffmpeg.default.setFfmpegPath(import_ffmpeg_for_homebridge.default);
98
106
  (0, import_fluent_ffmpeg.default)().withProcessOptions({
99
107
  detached: true
100
- }).addOptions([
101
- `-ss ${skip_seconds}`,
102
- "-frames:v 1"
103
- ]).input(input).inputFormat("hls").outputFormat("image2").output(output).on("error", function(err, stdout, stderr) {
108
+ }).addOptions([`-ss ${skip_seconds}`, "-frames:v 1"]).input(input).inputFormat("hls").outputFormat("image2").output(output).on("error", function(err, stdout, stderr) {
104
109
  log.error(`ffmpegPreviewImage(): An error occurred: ${err.message}`);
105
110
  log.error(`ffmpegPreviewImage(): ffmpeg output:
106
111
  ${stdout}`);
@@ -116,7 +121,7 @@ ${stderr}`);
116
121
  }
117
122
  } catch (error) {
118
123
  log.error(`ffmpegPreviewImage(): Error: ${error}`);
119
- reject(error);
124
+ reject(new Error(error.toString()));
120
125
  }
121
126
  });
122
127
  };
@@ -167,7 +172,9 @@ const ffmpegStreamToHls = (config, namespace, metadata, videoStream, audioStream
167
172
  command.input(uAudioStream.url).inputFormat(audioFormat).videoCodec("copy").audioCodec("copy");
168
173
  options.push("-absf aac_adtstoasc");
169
174
  } else {
170
- log.warn(`ffmpegStreamToHls(): Not support audio codec or unknown audio codec (${import_eufy_security_client.AudioCodec[metadata.audioCodec]})`);
175
+ log.warn(
176
+ `ffmpegStreamToHls(): Not support audio codec or unknown audio codec (${import_eufy_security_client.AudioCodec[metadata.audioCodec]})`
177
+ );
171
178
  }
172
179
  command.output(output).addOptions(options).on("error", function(err, stdout, stderr) {
173
180
  log.error(`ffmpegStreamToHls(): An error occurred: ${err.message}`);
@@ -190,7 +197,7 @@ ${stderr}`);
190
197
  }
191
198
  } catch (error) {
192
199
  log.error(`ffmpegStreamToHls(): Error: ${error}`);
193
- reject(error);
200
+ reject(new Error(error.toString()));
194
201
  }
195
202
  });
196
203
  };
@@ -239,7 +246,9 @@ const ffmpegStreamToGo2rtc = (config, namespace, camera, metadata, videoStream,
239
246
  if (audioFormat !== "") {
240
247
  command.input(uAudioStream.url).inputFormat(audioFormat).audioCodec("opus");
241
248
  } else {
242
- log.warn(`ffmpegStreamToGo2rtc(): Not support audio codec or unknown audio codec (${import_eufy_security_client.AudioCodec[metadata.audioCodec]})`);
249
+ log.warn(
250
+ `ffmpegStreamToGo2rtc(): Not support audio codec or unknown audio codec (${import_eufy_security_client.AudioCodec[metadata.audioCodec]})`
251
+ );
243
252
  }
244
253
  command.output(`rtsp://localhost:${config.go2rtc_rtsp_port}/${camera}`).outputFormat("rtsp").addOptions(options).on("start", (commandline) => {
245
254
  log.debug(`ffmpegStreamToGo2rtc(): commandline: ${commandline}`);
@@ -264,11 +273,11 @@ ${stderr}`);
264
273
  }
265
274
  } catch (error) {
266
275
  log.error(`ffmpegStreamToGo2rtc(): Error: ${error}`);
267
- reject(error);
276
+ reject(new Error(error.toString()));
268
277
  }
269
278
  });
270
279
  };
271
- const streamToGo2rtc = async (camera, videoStream, audioStream, log, _config, _namespace, _metadata) => {
280
+ const streamToGo2rtc = async (camera, videoStream, audioStream, log, config, _namespace, _metadata) => {
272
281
  const { default: got } = await import("got");
273
282
  const api = got.extend({
274
283
  hooks: {
@@ -276,11 +285,14 @@ const streamToGo2rtc = async (camera, videoStream, audioStream, log, _config, _n
276
285
  (error) => {
277
286
  const { response, options } = error;
278
287
  const { method, url, prefixUrl } = options;
279
- const shortUrl = (0, import_utils.getShortUrl)(typeof url === "string" ? new URL(url) : url === void 0 ? new URL("") : url, typeof prefixUrl === "string" ? prefixUrl : prefixUrl.toString());
288
+ const shortUrl = (0, import_utils.getShortUrl)(
289
+ typeof url === "string" ? new URL(url) : url === void 0 ? new URL("") : url,
290
+ typeof prefixUrl === "string" ? prefixUrl : prefixUrl.toString()
291
+ );
280
292
  const body = (response == null ? void 0 : response.body) ? response.body : error.message;
281
293
  error.message = `${error.message} | method: ${method} url: ${shortUrl}`;
282
294
  if (response == null ? void 0 : response.body) {
283
- error.message = `${error.message} body: ${body}`;
295
+ error.message = `${error.message} body: ${typeof body === "object" ? JSON.stringify(body) : body == null ? void 0 : body.toString()}`;
284
296
  }
285
297
  return error;
286
298
  }
@@ -293,12 +305,12 @@ const streamToGo2rtc = async (camera, videoStream, audioStream, log, _config, _n
293
305
  audioStream.on("error", (error) => {
294
306
  log.error("streamToGo2rtc(): Audiostream Error", error);
295
307
  });
296
- return Promise.allSettled([
308
+ const ingestUrl = `http://localhost:${config.go2rtc_api_port}/api/stream?dst=${camera}`;
309
+ const results = await Promise.allSettled([
297
310
  (0, import_promises.pipeline)(
298
311
  videoStream,
299
- api.stream.post(`http://localhost:1984/api/stream?dst=${camera}`).on("error", (error) => {
300
- var _a, _b;
301
- if (!((_b = (_a = error.response) == null ? void 0 : _a.body) == null ? void 0 : _b.startsWith("EOF"))) {
312
+ api.stream.post(ingestUrl).on("error", (error) => {
313
+ if (!(0, import_go2rtc.isRegularStreamEnd)(error)) {
302
314
  log.error(`streamToGo2rtc(): Got Videostream Error: ${error.message}`);
303
315
  }
304
316
  }),
@@ -306,9 +318,8 @@ const streamToGo2rtc = async (camera, videoStream, audioStream, log, _config, _n
306
318
  ),
307
319
  (0, import_promises.pipeline)(
308
320
  audioStream,
309
- api.stream.post(`http://localhost:1984/api/stream?dst=${camera}`).on("error", (error) => {
310
- var _a, _b;
311
- if (!((_b = (_a = error.response) == null ? void 0 : _a.body) == null ? void 0 : _b.startsWith("EOF"))) {
321
+ api.stream.post(ingestUrl).on("error", (error) => {
322
+ if (!(0, import_go2rtc.isRegularStreamEnd)(error)) {
312
323
  log.error(`streamToGo2rtc(): Got Audiostream Error: ${error.message}`);
313
324
  }
314
325
  }),
@@ -379,6 +390,12 @@ const streamToGo2rtc = async (camera, videoStream, audioStream, log, _config, _n
379
390
  }
380
391
  })*/
381
392
  ]);
393
+ for (const result of results) {
394
+ if (result.status === "rejected" && !(0, import_go2rtc.isRegularStreamEnd)(result.reason)) {
395
+ log.error(`streamToGo2rtc(): Stream to go2rtc failed: ${result.reason}`);
396
+ }
397
+ }
398
+ return results;
382
399
  };
383
400
  // Annotate the CommonJS export names for ESM import in node:
384
401
  0 && (module.exports = {
@@ -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 // @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": "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",
4
+ "sourcesContent": ["import net from 'node:net';\nimport path from 'node:path';\nimport ffmpeg from '@bropat/fluent-ffmpeg';\nimport pathToFfmpeg from 'ffmpeg-for-homebridge';\nimport type { Readable } from 'node:stream';\nimport { type StreamMetadata, AudioCodec, VideoCodec } from 'eufy-security-client';\nimport { tmpdir } from 'node:os';\nimport fse from 'fs-extra';\n\nimport stream from 'node:stream';\nimport { pipeline as streamPipeline } from 'node:stream/promises';\n\nimport type { ioBrokerLogger } from './log';\nimport { isRegularStreamEnd } from './go2rtc';\nimport { getShortUrl, lowestUnusedNumber } from './utils';\n\nclass UniversalStream {\n public url: string;\n private static socks = new Set<number>();\n private readonly server: net.Server;\n private readonly sock_id: number;\n\n constructor(namespace: string, onSocket: ((socket: net.Socket) => void) | undefined) {\n let sockPath = '';\n\n const unique_sock_id = lowestUnusedNumber([...UniversalStream.socks], 1);\n UniversalStream.socks.add(unique_sock_id);\n this.sock_id = unique_sock_id;\n\n if (process.platform === 'win32') {\n const pipePrefix = '\\\\\\\\.\\\\pipe\\\\';\n const pipeName = `node-webrtc.${namespace}.${unique_sock_id}.sock`;\n\n sockPath = path.join(pipePrefix, pipeName);\n this.url = sockPath;\n } else {\n const pipeName = `${namespace}.${unique_sock_id}.sock`;\n sockPath = path.join(tmpdir(), pipeName);\n this.url = `unix:${sockPath}`;\n\n try {\n if (fse.existsSync(sockPath)) {\n fse.unlinkSync(sockPath);\n }\n } catch {\n // ignore\n }\n }\n\n this.server = net.createServer(onSocket);\n this.server.listen(sockPath);\n this.server.on('error', () => {});\n }\n\n public close(): void {\n this.server?.close();\n UniversalStream.socks.delete(this.sock_id);\n }\n}\n\nexport const StreamInput = function (namespace: string, stream: NodeJS.ReadableStream): UniversalStream {\n return new UniversalStream(namespace, (socket: net.Socket) =>\n stream.pipe(socket, { end: true }).on('error', _error => {\n // TODO: log error\n }),\n );\n};\n\nexport const StreamOutput = function (namespace: string, stream: NodeJS.WritableStream): UniversalStream {\n return new UniversalStream(namespace, (socket: net.Socket) =>\n socket.pipe(stream, { end: true }).on('error', _error => {\n // TODO: log error\n }),\n );\n};\n\nexport const ffmpegPreviewImage = (\n config: ioBroker.AdapterConfig,\n input: string,\n output: string,\n log: ioBrokerLogger,\n skip_seconds = 2.0,\n): Promise<void> => {\n return new Promise((resolve, reject) => {\n try {\n if (pathToFfmpeg) {\n ffmpeg.setFfmpegPath(pathToFfmpeg);\n\n ffmpeg()\n .withProcessOptions({\n detached: true,\n })\n .addOptions([`-ss ${skip_seconds}`, '-frames:v 1'])\n .input(input)\n .inputFormat('hls')\n .outputFormat('image2')\n .output(output)\n .on('error', function (err: Error, stdout, stderr) {\n log.error(`ffmpegPreviewImage(): An error occurred: ${err.message}`);\n log.error(`ffmpegPreviewImage(): ffmpeg output:\\n${stdout}`);\n log.error(`ffmpegPreviewImage(): ffmpeg stderr:\\n${stderr}`);\n reject(err);\n })\n .on('end', () => {\n log.debug('ffmpegPreviewImage(): Preview image generated!');\n resolve();\n })\n .run();\n } else {\n reject(new Error('ffmpeg binary not found'));\n }\n } catch (error) {\n log.error(`ffmpegPreviewImage(): Error: ${error as Error}`);\n reject(new Error((error as Error).toString()));\n }\n });\n};\n\nexport const ffmpegStreamToHls = (\n config: ioBroker.AdapterConfig,\n namespace: string,\n metadata: StreamMetadata,\n videoStream: Readable,\n audioStream: Readable,\n output: string,\n log: ioBrokerLogger,\n): Promise<void> => {\n return new Promise((resolve, reject) => {\n try {\n if (pathToFfmpeg) {\n ffmpeg.setFfmpegPath(pathToFfmpeg);\n\n videoStream.on('error', error => {\n log.error('ffmpegStreamToHls(): Videostream Error', error);\n });\n\n audioStream.on('error', error => {\n log.error('ffmpegStreamToHls(): Audiostream Error', error);\n });\n\n const uVideoStream = StreamInput(namespace, videoStream);\n const uAudioStream = StreamInput(namespace, audioStream);\n\n let videoFormat = 'h264';\n let audioFormat = '';\n const options: string[] = [\n '-hls_init_time 0',\n '-hls_time 2',\n '-hls_segment_type mpegts',\n //\"-start_number 1\",\n '-sc_threshold 0',\n `-g ${metadata.videoFPS}`,\n '-fflags genpts+nobuffer+flush_packets',\n //\"-flush_packets 1\",\n '-hls_playlist_type event',\n //\"-hls_flags split_by_time\"\n ];\n\n switch (metadata.videoCodec) {\n case VideoCodec.H264:\n videoFormat = 'h264';\n break;\n case VideoCodec.H265:\n videoFormat = 'hevc';\n break;\n }\n\n switch (metadata.audioCodec) {\n case AudioCodec.AAC:\n audioFormat = 'aac';\n break;\n }\n\n const command = ffmpeg()\n .withProcessOptions({\n detached: true,\n })\n .input(uVideoStream.url)\n .inputFormat(videoFormat)\n .inputFps(metadata.videoFPS);\n if (audioFormat !== '') {\n command.input(uAudioStream.url).inputFormat(audioFormat).videoCodec('copy').audioCodec('copy');\n options.push('-absf aac_adtstoasc');\n } else {\n log.warn(\n `ffmpegStreamToHls(): Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`,\n );\n }\n command\n .output(output)\n .addOptions(options)\n .on('error', function (err: Error, stdout, stderr) {\n log.error(`ffmpegStreamToHls(): An error occurred: ${err.message}`);\n log.error(`ffmpegStreamToHls(): ffmpeg output:\\n${stdout}`);\n log.error(`ffmpegStreamToHls(): ffmpeg stderr:\\n${stderr}`);\n uVideoStream.close();\n uAudioStream.close();\n reject(err);\n })\n .on('end', () => {\n log.debug('ffmpegStreamToHls(): Processing finished!');\n uVideoStream.close();\n uAudioStream.close();\n resolve();\n });\n command.run();\n } else {\n reject(new Error('ffmpeg binary not found'));\n }\n } catch (error) {\n log.error(`ffmpegStreamToHls(): Error: ${error as Error}`);\n reject(new Error((error as Error).toString()));\n }\n });\n};\n\nexport const ffmpegStreamToGo2rtc = (\n config: ioBroker.AdapterConfig,\n namespace: string,\n camera: string,\n metadata: StreamMetadata,\n videoStream: Readable,\n audioStream: Readable,\n log: ioBrokerLogger,\n): Promise<void> => {\n return new Promise((resolve, reject) => {\n try {\n if (pathToFfmpeg) {\n ffmpeg.setFfmpegPath(pathToFfmpeg);\n\n videoStream.on('error', error => {\n log.error('ffmpegStreamToGo2rtc(): Videostream Error', error);\n });\n\n audioStream.on('error', error => {\n log.error('ffmpegStreamToGo2rtc(): Audiostream Error', error);\n });\n\n //TODO: For debugging purposes\n /*const outputVFile = path.resolve(__dirname, \"../../video-stream.dump\");\n videoStream.pipe(fse.createWriteStream(outputVFile)).on(\"finish\", () => {\n log.debug(\"videoStream dump finished!\");\n log.info(\"Manually test the output by running# ffplay output/video-stream.dump\");\n });\n const outputAFile = path.resolve(__dirname, \"../../audio-stream.dump\");\n audioStream.pipe(fse.createWriteStream(outputAFile)).on(\"finish\", () => {\n log.debug(\"audioStream dump finished!\");\n log.info(\"Manually test the output by running# ffplay output/audio-stream.dump\");\n });*/\n\n const uVideoStream = StreamInput(namespace, videoStream);\n const uAudioStream = StreamInput(namespace, audioStream);\n\n let videoFormat = 'h264';\n let audioFormat = '';\n const options: string[] = [\n '-rtsp_transport tcp',\n '-sc_threshold 0',\n '-fflags genpts+nobuffer+flush_packets',\n //\"-rtpflags latm\",\n ];\n\n switch (metadata.videoCodec) {\n case VideoCodec.H264:\n videoFormat = 'h264';\n break;\n case VideoCodec.H265:\n videoFormat = 'hevc';\n break;\n }\n\n switch (metadata.audioCodec) {\n case AudioCodec.AAC:\n audioFormat = 'aac';\n break;\n }\n\n const command = ffmpeg()\n .withProcessOptions({\n detached: true,\n })\n .input(uVideoStream.url)\n .inputFormat(videoFormat);\n if (metadata.videoFPS > 0) {\n options.push(`-g ${metadata.videoFPS}`);\n command.inputFps(metadata.videoFPS);\n }\n command.videoCodec('copy');\n if (audioFormat !== '') {\n command\n .input(uAudioStream.url)\n .inputFormat(audioFormat)\n //.audioCodec(\"copy\");\n //.audioCodec(\"aac\");\n .audioCodec('opus');\n } else {\n log.warn(\n `ffmpegStreamToGo2rtc(): Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`,\n );\n }\n command\n .output(`rtsp://localhost:${config.go2rtc_rtsp_port}/${camera}`)\n .outputFormat('rtsp')\n .addOptions(options)\n .on('start', commandline => {\n log.debug(`ffmpegStreamToGo2rtc(): commandline: ${commandline}`);\n })\n .on('error', function (err: Error, stdout, stderr) {\n log.error(`ffmpegStreamToGo2rtc(): An error occurred: ${err.message}`);\n log.error(`ffmpegStreamToGo2rtc(): ffmpeg output:\\n${stdout}`);\n log.error(`ffmpegStreamToGo2rtc(): ffmpeg stderr:\\n${stderr}`);\n uVideoStream.close();\n uAudioStream.close();\n reject(err);\n })\n .on('end', () => {\n log.debug('ffmpegStreamToGo2rtc(): Processing finished!');\n uVideoStream.close();\n uAudioStream.close();\n resolve();\n });\n command.run();\n } else {\n reject(new Error('ffmpeg binary not found'));\n }\n } catch (error) {\n log.error(`ffmpegStreamToGo2rtc(): Error: ${error as Error}`);\n reject(new Error((error as Error).toString()));\n }\n });\n};\n\nexport const streamToGo2rtc = async (\n camera: string,\n videoStream: Readable,\n audioStream: Readable,\n log: ioBrokerLogger,\n config: ioBroker.AdapterConfig,\n _namespace: string,\n _metadata: StreamMetadata,\n): Promise<Array<PromiseSettledResult<void>>> => {\n const { default: got } = await import('got');\n const api = got.extend({\n hooks: {\n beforeError: [\n error => {\n const { response, options } = error;\n const { method, url, prefixUrl } = options;\n const shortUrl = getShortUrl(\n typeof url === 'string' ? new URL(url) : url === undefined ? new URL('') : url,\n typeof prefixUrl === 'string' ? prefixUrl : prefixUrl.toString(),\n );\n const body = response?.body ? response.body : error.message;\n error.message = `${error.message} | method: ${method} url: ${shortUrl}`;\n if (response?.body) {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n error.message = `${error.message} body: ${typeof body === 'object' ? JSON.stringify(body) : body?.toString()}`;\n }\n return error;\n },\n ],\n },\n });\n videoStream.on('error', error => {\n log.error('streamToGo2rtc(): Videostream Error', error);\n });\n\n audioStream.on('error', error => {\n log.error('streamToGo2rtc(): Audiostream Error', error);\n });\n const ingestUrl = `http://localhost:${config.go2rtc_api_port}/api/stream?dst=${camera}`;\n const results = await Promise.allSettled([\n streamPipeline(\n videoStream,\n api.stream.post(ingestUrl).on('error', (error: any) => {\n if (!isRegularStreamEnd(error)) {\n log.error(`streamToGo2rtc(): Got Videostream Error: ${error.message}`);\n }\n }),\n new stream.PassThrough(),\n ),\n streamPipeline(\n audioStream,\n api.stream.post(ingestUrl).on('error', (error: any) => {\n if (!isRegularStreamEnd(error)) {\n log.error(`streamToGo2rtc(): Got Audiostream Error: ${error.message}`);\n }\n }),\n new stream.PassThrough(),\n ),\n // Alternative implementation in case of go2rtc audio bitstream isn't working (<= 1.8.5)\n /*new Promise<void>((resolve, reject) => {\n try {\n if (pathToFfmpeg) {\n ffmpeg.setFfmpegPath(pathToFfmpeg);\n\n const uAudioStream = StreamInput(namespace, audioStream);\n\n let audioFormat = \"\";\n const options: string[] = [\n \"-rtsp_transport tcp\",\n \"-fflags genpts+nobuffer+flush_packets\",\n //\"-rtpflags latm\",\n //\"-compression_level 5\",\n \"-application lowdelay\",\n ];\n\n switch(metadata.audioCodec) {\n case AudioCodec.AAC:\n audioFormat = \"aac\";\n break;\n }\n\n const command = ffmpeg()\n .withProcessOptions({\n detached: true\n });\n\n if (audioFormat !== \"\") {\n command.input(uAudioStream.url)\n .inputFormat(audioFormat)\n .audioCodec(\"opus\");\n } else {\n log.warn(`streamToGo2rtc(): ffmpeg - Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`);\n }\n command.output(`rtsp://localhost:${config.go2rtc_rtsp_port}/${camera}`)\n .outputFormat(\"rtsp\")\n .addOptions(options)\n .on(\"start\", (commandline) => {\n log.debug(`streamToGo2rtc(): ffmpeg - commandline: ${commandline}`);\n })\n .on(\"error\", function(err, stdout, stderr) {\n log.error(`streamToGo2rtc(): ffmpeg - An error occurred: ${err.message}`);\n log.error(`streamToGo2rtc(): ffmpeg output:\\n${stdout}`);\n log.error(`streamToGo2rtc(): ffmpeg stderr:\\n${stderr}`);\n uAudioStream.close();\n reject(err);\n })\n .on(\"end\", (stdout, stderr) => {\n log.debug(`streamToGo2rtc(): ffmpeg output:\\n${stdout}`);\n log.debug(`streamToGo2rtc(): ffmpeg stderr:\\n${stderr}`);\n log.debug(\"streamToGo2rtc(): Processing finished!\");\n uAudioStream.close();\n resolve();\n });\n command.run();\n } else {\n reject(new Error(\"ffmpeg binary not found\"));\n }\n } catch (error) {\n log.error(`streamToGo2rtc(): Audio Error: ${error}`);\n reject(error);\n }\n })*/\n ]);\n\n // Without this the rejection is swallowed by allSettled and a dead pipeline stays invisible,\n // while the camera keeps streaming until the maximum livestream duration expires.\n for (const result of results) {\n if (result.status === 'rejected' && !isRegularStreamEnd(result.reason)) {\n log.error(`streamToGo2rtc(): Stream to go2rtc failed: ${result.reason}`);\n }\n }\n\n return results;\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["path", "fse", "net", "stream", "pathToFfmpeg", "ffmpeg", "streamPipeline"]
7
7
  }