homebridge-nest-accfactory 0.0.4-a → 0.0.6

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/dist/streamer.js CHANGED
@@ -8,12 +8,12 @@
8
8
  //
9
9
  // The following functions should be overriden in your class which extends this
10
10
  //
11
- // streamer.connect(host)
12
- // streamer.close(stopStreamFirst)
11
+ // streamer.connect()
12
+ // streamer.close()
13
13
  // streamer.talkingAudio(talkingData)
14
14
  // streamer.update(deviceData) <- call super after
15
15
  //
16
- // Code version 6/9/2024
16
+ // Code version 13/9/2024
17
17
  // Mark Hulskamp
18
18
  'use strict';
19
19
 
@@ -35,17 +35,17 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Make a define
35
35
 
36
36
  // Streamer object
37
37
  export default class Streamer {
38
- cameraOfflineFrame = undefined;
39
- cameraVideoOffFrame = undefined;
40
- videoEnabled = undefined;
41
- audioEnabled = undefined;
42
- online = undefined;
43
- host = ''; // Host to connect to or connected too
44
- socket = null; // TCP socket object
38
+ videoEnabled = undefined; // Video stream on camera enabled or not
39
+ audioEnabled = undefined; // Audio from camera enabled or not
40
+ online = undefined; // Camera online or not
41
+ uuid = undefined; // UUID of the device connecting
42
+ connected = false; // Streamer connected to endpoint
45
43
 
46
44
  // Internal data only for this class
47
45
  #outputTimer = undefined; // Timer for non-blocking loop to stream output data
48
46
  #outputs = {}; // Output streams ie: buffer, live, record
47
+ #cameraOfflineFrame = undefined; // Camera offline video frame
48
+ #cameraVideoOffFrame = undefined; // Video turned off on camera video frame
49
49
 
50
50
  constructor(deviceData, options) {
51
51
  // Setup logger object if passed as option
@@ -63,6 +63,7 @@ export default class Streamer {
63
63
  this.online = deviceData?.online === true;
64
64
  this.videoEnabled = deviceData?.streaming_enabled === true;
65
65
  this.audioEnabled = deviceData?.audio_enabled === true;
66
+ this.uuid = deviceData?.uuid;
66
67
 
67
68
  // Setup location for *.h264 frame files. This can be overriden by a passed in option
68
69
  let resourcePath = path.resolve(__dirname + '/res'); // Default location for *.h264 files
@@ -76,19 +77,19 @@ export default class Streamer {
76
77
 
77
78
  // load buffer for camera offline image in .h264 frame
78
79
  if (fs.existsSync(path.resolve(resourcePath + '/' + CAMERAOFFLINEH264FILE)) === true) {
79
- this.cameraOfflineFrame = fs.readFileSync(path.resolve(resourcePath + '/' + CAMERAOFFLINEH264FILE));
80
+ this.#cameraOfflineFrame = fs.readFileSync(path.resolve(resourcePath + '/' + CAMERAOFFLINEH264FILE));
80
81
  // remove any H264 NALU from beginning of any video data. We do this as they are added later when output by our ffmpeg router
81
- if (this.cameraOfflineFrame.indexOf(H264NALStartcode) === 0) {
82
- this.cameraOfflineFrame = this.cameraOfflineFrame.subarray(H264NALStartcode.length);
82
+ if (this.#cameraOfflineFrame.indexOf(H264NALStartcode) === 0) {
83
+ this.#cameraOfflineFrame = this.#cameraOfflineFrame.subarray(H264NALStartcode.length);
83
84
  }
84
85
  }
85
86
 
86
87
  // load buffer for camera stream off image in .h264 frame
87
88
  if (fs.existsSync(path.resolve(resourcePath + '/' + CAMERAOFFH264FILE)) === true) {
88
- this.cameraVideoOffFrame = fs.readFileSync(path.resolve(resourcePath + '/' + CAMERAOFFH264FILE));
89
+ this.#cameraVideoOffFrame = fs.readFileSync(path.resolve(resourcePath + '/' + CAMERAOFFH264FILE));
89
90
  // remove any H264 NALU from beginning of any video data. We do this as they are added later when output by our ffmpeg router
90
- if (this.cameraVideoOffFrame.indexOf(H264NALStartcode) === 0) {
91
- this.cameraVideoOffFrame = this.cameraVideoOffFrame.subarray(H264NALStartcode.length);
91
+ if (this.#cameraVideoOffFrame.indexOf(H264NALStartcode) === 0) {
92
+ this.#cameraVideoOffFrame = this.#cameraVideoOffFrame.subarray(H264NALStartcode.length);
92
93
  }
93
94
  }
94
95
 
@@ -103,15 +104,15 @@ export default class Streamer {
103
104
  Object.values(this.#outputs).forEach((output) => {
104
105
  // Monitor for camera going offline and/or video enabled/disabled
105
106
  // We'll insert the appropriate video frame into the stream
106
- if (this.online === false && this.cameraOfflineFrame !== undefined && outputVideoFrame === true) {
107
+ if (this.online === false && this.#cameraOfflineFrame !== undefined && outputVideoFrame === true) {
107
108
  // Camera is offline so feed in our custom h264 frame and AAC silence
108
- output.buffer.push({ type: 'video', time: dateNow, data: this.cameraOfflineFrame });
109
+ output.buffer.push({ type: 'video', time: dateNow, data: this.#cameraOfflineFrame });
109
110
  output.buffer.push({ type: 'audio', time: dateNow, data: AACAudioSilence });
110
111
  lastTimeVideo = dateNow;
111
112
  }
112
- if (this.online === true && this.videoEnabled === false && this.cameraVideoOffFrame !== undefined && outputVideoFrame === true) {
113
+ if (this.online === true && this.videoEnabled === false && this.#cameraVideoOffFrame !== undefined && outputVideoFrame === true) {
113
114
  // Camera video is turned off so feed in our custom h264 frame and AAC silence
114
- output.buffer.push({ type: 'video', time: dateNow, data: this.cameraVideoOffFrame });
115
+ output.buffer.push({ type: 'video', time: dateNow, data: this.#cameraVideoOffFrame });
115
116
  output.buffer.push({ type: 'audio', time: dateNow, data: AACAudioSilence });
116
117
  lastTimeVideo = dateNow;
117
118
  }
@@ -150,11 +151,9 @@ export default class Streamer {
150
151
  startBuffering() {
151
152
  if (this.#outputs?.buffer === undefined) {
152
153
  // No active buffer session, start connection to streamer
153
- if (this.socket === null && typeof this.host === 'string' && this.host !== '') {
154
- if (typeof this.connect === 'function') {
155
- this.connect(this.host);
156
- this?.log?.debug && this.log.debug('Started buffering from "%s"', this.host);
157
- }
154
+ if (this.connected === false && typeof this.connect === 'function') {
155
+ this?.log?.debug && this.log.debug('Started buffering for uuid "%s"', this.uuid);
156
+ this.connect();
158
157
  }
159
158
 
160
159
  this.#outputs.buffer = {
@@ -199,11 +198,9 @@ export default class Streamer {
199
198
  });
200
199
  }
201
200
 
202
- if (this.socket === null && typeof this.host === 'string' && this.host !== '') {
203
- // We do not have an active socket connection, so startup connection to host
204
- if (typeof this.connect === 'function') {
205
- this.connect(this.host);
206
- }
201
+ if (this.connected === false && typeof this.connect === 'function') {
202
+ // We do not have an active connection, so startup connection
203
+ this.connect();
207
204
  }
208
205
 
209
206
  // Add video/audio streams for our output loop to handle outputting to
@@ -218,9 +215,9 @@ export default class Streamer {
218
215
  // finally, we've started live stream
219
216
  this?.log?.debug &&
220
217
  this.log.debug(
221
- 'Started live stream from "%s" %s and sesssion id of "%s"',
222
- this.host,
223
- talkbackStream !== null && typeof talkbackStream === 'object' ? 'with two-way audio' : '',
218
+ 'Started live stream from uuid "%s" %s "%s"',
219
+ this.uuid,
220
+ talkbackStream !== null && typeof talkbackStream === 'object' ? 'with two-way audio and sesssion id of' : 'and sesssion id of',
224
221
  sessionID,
225
222
  );
226
223
  }
@@ -239,11 +236,9 @@ export default class Streamer {
239
236
  });
240
237
  }
241
238
 
242
- if (this.socket === null && typeof this.host === 'string' && this.host !== '') {
243
- // We do not have an active socket connection, so startup connection to host
244
- if (typeof this.connect === 'function') {
245
- this.connect(this.host);
246
- }
239
+ if (this.connected === false && typeof this.connect === 'function') {
240
+ // We do not have an active connection, so startup connection
241
+ this.connect();
247
242
  }
248
243
 
249
244
  // Add video/audio streams for our output loop to handle outputting to
@@ -256,44 +251,44 @@ export default class Streamer {
256
251
  };
257
252
 
258
253
  // Finally we've started the recording stream
259
- this?.log?.debug && this.log.debug('Started recording stream from "%s" with sesison id of "%s"', this.host, sessionID);
254
+ this?.log?.debug && this.log.debug('Started recording stream from uuid "%s" with sesison id of "%s"', this.uuid, sessionID);
260
255
  }
261
256
 
262
257
  stopRecordStream(sessionID) {
263
258
  // Request to stop a recording stream
264
- if (typeof this.#outputs[sessionID] === 'object') {
265
- this?.log?.debug && this.log.debug('Stopped recording stream from "%s"', this.host);
259
+ if (this.#outputs?.[sessionID] !== undefined) {
260
+ this?.log?.debug && this.log.debug('Stopped recording stream from uuid "%s"', this.uuid);
266
261
  delete this.#outputs[sessionID];
267
262
  }
268
263
 
269
- // If we have no more output streams active, we'll close the connection to host
264
+ // If we have no more output streams active, we'll close the connection
270
265
  if (Object.keys(this.#outputs).length === 0 && typeof this.close === 'function') {
271
- this.close(true);
266
+ this.close();
272
267
  }
273
268
  }
274
269
 
275
270
  stopLiveStream(sessionID) {
276
271
  // Request to stop an active live stream
277
- if (typeof this.#outputs[sessionID] === 'object') {
278
- this?.log?.debug && this.log.debug('Stopped live stream from "%s"', this.host);
272
+ if (this.#outputs?.[sessionID] !== undefined) {
273
+ this?.log?.debug && this.log.debug('Stopped live stream from uuid "%s"', this.uuid);
279
274
  delete this.#outputs[sessionID];
280
275
  }
281
276
 
282
- // If we have no more output streams active, we'll close the connection to host
277
+ // If we have no more output streams active, we'll close the connection
283
278
  if (Object.keys(this.#outputs).length === 0 && typeof this.close === 'function') {
284
- this.close(true);
279
+ this.close();
285
280
  }
286
281
  }
287
282
 
288
283
  stopBuffering() {
289
284
  if (this.#outputs?.buffer !== undefined) {
290
- this?.log?.debug && this.log.debug('Stopped buffering from "%s"', this.host);
285
+ this?.log?.debug && this.log.debug('Stopped buffering from uuid "%s"', this.uuid);
291
286
  delete this.#outputs.buffer;
292
287
  }
293
288
 
294
- // If we have no more output streams active, we'll close the connection to host
289
+ // If we have no more output streams active, we'll close the connection
295
290
  if (Object.keys(this.#outputs).length === 0 && typeof this.close === 'function') {
296
- this.close(true);
291
+ this.close();
297
292
  }
298
293
  }
299
294
 
@@ -302,24 +297,20 @@ export default class Streamer {
302
297
  return;
303
298
  }
304
299
 
305
- this.online = deviceData?.online === true;
306
- this.videoEnabled = deviceData?.streaming_enabled === true;
307
- this.audioEnabled = deviceData?.audio_enabled === true;
308
-
309
- if (this.host !== deviceData.streaming_host) {
310
- this.host = deviceData.streaming_host;
311
- this?.log?.debug && this.log.debug('New streaming host has requested a new host "%s" for connection', this.host);
312
- }
313
-
314
- if (this.online !== deviceData.online || this.videoEnabled !== deviceData.streaming_enabled) {
300
+ if (
301
+ this.online !== deviceData.online ||
302
+ this.videoEnabled !== deviceData.streaming_enabled ||
303
+ this.audioEnabled !== deviceData?.audio_enabled
304
+ ) {
315
305
  // Online status or streaming status has changed has changed
316
306
  this.online = deviceData?.online === true;
317
307
  this.videoEnabled = deviceData?.streaming_enabled === true;
318
- if ((this.online === false || this.videoEnabled === false) && typeof this.close === 'function') {
319
- this.close(true); // as offline or streaming not enabled, close socket
308
+ this.audioEnabled = deviceData?.audio_enabled === true;
309
+ if ((this.online === false || this.videoEnabled === false || this.audioEnabled === false) && typeof this.close === 'function') {
310
+ this.close(); // as offline or streaming not enabled, close streamer
320
311
  }
321
312
  if (this.online === true && this.videoEnabled === true && typeof this.connect === 'function') {
322
- this.connect(this.host); // Connect to host for stream
313
+ this.connect(); // Connect for stream
323
314
  }
324
315
  }
325
316
  }