homebridge-nest-accfactory 0.2.11 → 0.3.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/CHANGELOG.md +24 -0
- package/README.md +14 -7
- package/config.schema.json +118 -0
- package/dist/HomeKitDevice.js +194 -77
- package/dist/HomeKitHistory.js +1 -1
- package/dist/config.js +207 -0
- package/dist/devices.js +113 -0
- package/dist/index.js +2 -1
- package/dist/nexustalk.js +19 -21
- package/dist/{camera.js → plugins/camera.js} +212 -239
- package/dist/{doorbell.js → plugins/doorbell.js} +32 -30
- package/dist/plugins/floodlight.js +91 -0
- package/dist/plugins/heatlink.js +17 -0
- package/dist/{protect.js → plugins/protect.js} +24 -41
- package/dist/{tempsensor.js → plugins/tempsensor.js} +13 -17
- package/dist/{thermostat.js → plugins/thermostat.js} +424 -381
- package/dist/{weather.js → plugins/weather.js} +26 -60
- package/dist/protobuf/nest/services/apigateway.proto +31 -1
- package/dist/protobuf/nest/trait/firmware.proto +207 -89
- package/dist/protobuf/nest/trait/hvac.proto +1052 -312
- package/dist/protobuf/nest/trait/located.proto +51 -8
- package/dist/protobuf/nest/trait/network.proto +366 -36
- package/dist/protobuf/nest/trait/occupancy.proto +145 -17
- package/dist/protobuf/nest/trait/product/protect.proto +57 -43
- package/dist/protobuf/nest/trait/resourcedirectory.proto +8 -0
- package/dist/protobuf/nest/trait/sensor.proto +7 -1
- package/dist/protobuf/nest/trait/service.proto +3 -1
- package/dist/protobuf/nest/trait/structure.proto +60 -14
- package/dist/protobuf/nest/trait/ui.proto +41 -1
- package/dist/protobuf/nest/trait/user.proto +6 -1
- package/dist/protobuf/nest/trait/voiceassistant.proto +2 -1
- package/dist/protobuf/nestlabs/eventingapi/v1.proto +20 -1
- package/dist/protobuf/root.proto +1 -0
- package/dist/protobuf/wdl.proto +18 -2
- package/dist/protobuf/weave/common.proto +2 -1
- package/dist/protobuf/weave/trait/heartbeat.proto +41 -1
- package/dist/protobuf/weave/trait/power.proto +1 -0
- package/dist/protobuf/weave/trait/security.proto +10 -1
- package/dist/streamer.js +68 -72
- package/dist/system.js +1208 -1245
- package/dist/webrtc.js +28 -23
- package/package.json +12 -12
- package/dist/floodlight.js +0 -97
package/dist/protobuf/wdl.proto
CHANGED
|
@@ -171,8 +171,9 @@ message WdlCommandOptions {
|
|
|
171
171
|
bool extendable = 5;
|
|
172
172
|
uint32 reservedTagMin = 6;
|
|
173
173
|
uint32 reservedTagMax = 7;
|
|
174
|
-
string
|
|
174
|
+
string extends = 8;
|
|
175
175
|
string completionEvent = 11;
|
|
176
|
+
WdlPermission permission = 20;
|
|
176
177
|
}
|
|
177
178
|
|
|
178
179
|
message WdlEventOptions {
|
|
@@ -181,7 +182,7 @@ message WdlEventOptions {
|
|
|
181
182
|
bool extendable = 5;
|
|
182
183
|
uint32 reservedTagMin = 6;
|
|
183
184
|
uint32 reservedTagMax = 7;
|
|
184
|
-
string
|
|
185
|
+
string extends = 8;
|
|
185
186
|
EventImportance eventImportance = 9;
|
|
186
187
|
}
|
|
187
188
|
|
|
@@ -373,6 +374,8 @@ message WdlTraitOptions {
|
|
|
373
374
|
uint32 reservedCommandTagMax = 11;
|
|
374
375
|
uint32 reservedEventTagMin = 12;
|
|
375
376
|
uint32 reservedEventTagMax = 13;
|
|
377
|
+
WdlPermission permissionRead = 20;
|
|
378
|
+
WdlPermission permissionUpdate = 21;
|
|
376
379
|
}
|
|
377
380
|
|
|
378
381
|
message WdlTypespaceOptions {
|
|
@@ -440,6 +443,19 @@ message WdlServiceOptions {
|
|
|
440
443
|
WdlResourceOptions resource = 3;
|
|
441
444
|
}
|
|
442
445
|
|
|
446
|
+
message WdlFileOptions {
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
message WdlPermission {
|
|
450
|
+
string permission = 1;
|
|
451
|
+
repeated Override permissionOverrides = 2;
|
|
452
|
+
|
|
453
|
+
message Override {
|
|
454
|
+
string resourceType = 1;
|
|
455
|
+
string permission = 2;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
443
459
|
message CaspianOptions {
|
|
444
460
|
bool ignore = 1;
|
|
445
461
|
}
|
|
@@ -17,6 +17,15 @@ message LivenessTrait {
|
|
|
17
17
|
google.protobuf.BoolValue commandRequestUnresponsiveness = 8;
|
|
18
18
|
google.protobuf.Timestamp commandRequestUnresponsivenessTimeStatusChanged = 9;
|
|
19
19
|
google.protobuf.StringValue publisherName = 10;
|
|
20
|
+
google.protobuf.BoolValue tunnelDisconnected = 11;
|
|
21
|
+
google.protobuf.Timestamp tunnelDisconnectedTimeStatusChanged = 12;
|
|
22
|
+
google.protobuf.Timestamp lastContactedTime = 13;
|
|
23
|
+
google.protobuf.Timestamp lastWdmHeartbeatTime = 14;
|
|
24
|
+
google.protobuf.Timestamp tunnelClosedTime = 15;
|
|
25
|
+
repeated DeviceFrontendType frontend = 16;
|
|
26
|
+
google.protobuf.BoolValue disconnected = 17;
|
|
27
|
+
google.protobuf.Timestamp disconnectedTimeStatusChanged = 18;
|
|
28
|
+
google.protobuf.Timestamp connectionClosedTime = 19;
|
|
20
29
|
|
|
21
30
|
enum LivenessDeviceStatus {
|
|
22
31
|
LIVENESS_DEVICE_STATUS_UNSPECIFIED = 0;
|
|
@@ -28,11 +37,42 @@ message LivenessTrait {
|
|
|
28
37
|
LIVENESS_DEVICE_STATUS_SCHEDULED_DOWN = 6;
|
|
29
38
|
}
|
|
30
39
|
|
|
40
|
+
enum DeviceFrontendType {
|
|
41
|
+
DEVICE_FRONTEND_TYPE_UNSPECIFIED = 0;
|
|
42
|
+
DEVICE_FRONTEND_TYPE_LYCRA = 1;
|
|
43
|
+
DEVICE_FRONTEND_TYPE_WEAVE_FE_1 = 2;
|
|
44
|
+
}
|
|
45
|
+
|
|
31
46
|
message LivenessChangeEvent {
|
|
32
47
|
LivenessDeviceStatus status = 1;
|
|
33
48
|
LivenessDeviceStatus heartbeatStatus = 2;
|
|
34
49
|
google.protobuf.BoolValue notifyRequestUnresponsiveness = 3;
|
|
35
50
|
google.protobuf.BoolValue commandRequestUnresponsiveness = 4;
|
|
36
51
|
LivenessDeviceStatus prevStatus = 5;
|
|
52
|
+
google.protobuf.BoolValue tunnelDisconnected = 6;
|
|
53
|
+
google.protobuf.Timestamp lastContactedTime = 7;
|
|
54
|
+
google.protobuf.Timestamp lastWdmHeartbeatTime = 8;
|
|
55
|
+
google.protobuf.Timestamp tunnelClosedTime = 9;
|
|
56
|
+
google.protobuf.Timestamp timeStatusChanged = 10;
|
|
57
|
+
google.protobuf.Timestamp timePrevStatusChanged = 11;
|
|
58
|
+
repeated DeviceFrontendType frontend = 12;
|
|
59
|
+
google.protobuf.BoolValue disconnected = 13;
|
|
60
|
+
google.protobuf.Timestamp disconnectedTimeStatusChanged = 14;
|
|
61
|
+
google.protobuf.Timestamp connectionClosedTime = 15;
|
|
62
|
+
google.protobuf.StringValue traitLabel = 16;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
message LivenessConnectedSignalEvent {
|
|
66
|
+
string connectionId = 1;
|
|
67
|
+
DeviceFrontendType frontend = 2;
|
|
68
|
+
google.protobuf.Timestamp occurrenceTime = 3;
|
|
69
|
+
google.protobuf.StringValue connectionTag = 4;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
message LivenessDisconnectedSignalEvent {
|
|
73
|
+
string connectionId = 1;
|
|
74
|
+
DeviceFrontendType frontend = 2;
|
|
75
|
+
google.protobuf.Timestamp occurrenceTime = 3;
|
|
76
|
+
google.protobuf.StringValue connectionTag = 4;
|
|
37
77
|
}
|
|
38
|
-
}
|
|
78
|
+
}
|
|
@@ -249,12 +249,21 @@ message TamperTrait {
|
|
|
249
249
|
TAMPER_STATE_UNKNOWN = 3;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
+
enum TamperStateChangeReason {
|
|
253
|
+
TAMPER_STATE_CHANGE_REASON_UNSPECIFIED = 0;
|
|
254
|
+
TAMPER_STATE_CHANGE_REASON_CLEAR_SECURE = 1;
|
|
255
|
+
TAMPER_STATE_CHANGE_REASON_CLEAR_DISARM = 2;
|
|
256
|
+
TAMPER_STATE_CHANGE_REASON_CLEAR_SNOOZE = 3;
|
|
257
|
+
}
|
|
258
|
+
|
|
252
259
|
message ResetTamperRequest {
|
|
253
260
|
}
|
|
254
261
|
|
|
255
262
|
message TamperStateChangeEvent {
|
|
256
263
|
TamperState tamperState = 1;
|
|
257
264
|
TamperState priorTamperState = 2;
|
|
265
|
+
TamperStateChangeReason reason = 3;
|
|
266
|
+
google.protobuf.Timestamp tamperStateChangeTime = 4;
|
|
258
267
|
}
|
|
259
268
|
}
|
|
260
269
|
|
|
@@ -340,4 +349,4 @@ message UserPincodesCapabilitiesTrait {
|
|
|
340
349
|
uint32 minPincodeLength = 1;
|
|
341
350
|
uint32 maxPincodeLength = 2;
|
|
342
351
|
uint32 maxPincodesSupported = 3;
|
|
343
|
-
}
|
|
352
|
+
}
|
package/dist/streamer.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
//
|
|
18
18
|
// blankAudio - Buffer containing a blank audio segment for the type of audio being used
|
|
19
19
|
//
|
|
20
|
-
// Code version 2025
|
|
20
|
+
// Code version 2025.06.12
|
|
21
21
|
// Mark Hulskamp
|
|
22
22
|
'use strict';
|
|
23
23
|
|
|
@@ -29,16 +29,28 @@ import path from 'node:path';
|
|
|
29
29
|
import { fileURLToPath } from 'node:url';
|
|
30
30
|
|
|
31
31
|
// Define constants
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
const CAMERARESOURCE = {
|
|
33
|
+
offline: 'Nest_camera_offline.h264',
|
|
34
|
+
off: 'Nest_camera_off.h264',
|
|
35
|
+
transfer: 'Nest_camera_transfer.h264',
|
|
36
|
+
};
|
|
35
37
|
const TALKBACKAUDIOTIMEOUT = 1000;
|
|
36
38
|
const H264NALSTARTCODE = Buffer.from([0x00, 0x00, 0x00, 0x01]);
|
|
37
|
-
|
|
39
|
+
const MAXBUFFERAGE = 5000; // Keep last 5s of media in buffer
|
|
40
|
+
const STREAMFRAMEINTERVAL = 1000 / 30; // 30fps approx
|
|
41
|
+
const RESOURCEPATH = './res';
|
|
38
42
|
const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Make a defined for JS __dirname
|
|
43
|
+
const LOGLEVELS = {
|
|
44
|
+
info: 'info',
|
|
45
|
+
success: 'success',
|
|
46
|
+
warn: 'warn',
|
|
47
|
+
error: 'error',
|
|
48
|
+
debug: 'debug',
|
|
49
|
+
};
|
|
39
50
|
|
|
40
51
|
// Streamer object
|
|
41
52
|
export default class Streamer {
|
|
53
|
+
log = undefined; // Logging function object
|
|
42
54
|
videoEnabled = undefined; // Video stream on camera enabled or not
|
|
43
55
|
audioEnabled = undefined; // Audio from camera enabled or not
|
|
44
56
|
online = undefined; // Camera online or not
|
|
@@ -60,13 +72,7 @@ export default class Streamer {
|
|
|
60
72
|
|
|
61
73
|
constructor(deviceData, options) {
|
|
62
74
|
// Setup logger object if passed as option
|
|
63
|
-
if (
|
|
64
|
-
typeof options?.log?.info === 'function' &&
|
|
65
|
-
typeof options?.log?.success === 'function' &&
|
|
66
|
-
typeof options?.log?.warn === 'function' &&
|
|
67
|
-
typeof options?.log?.error === 'function' &&
|
|
68
|
-
typeof options?.log?.debug === 'function'
|
|
69
|
-
) {
|
|
75
|
+
if (Object.keys(LOGLEVELS).every((fn) => typeof options?.log?.[fn] === 'function')) {
|
|
70
76
|
this.log = options.log;
|
|
71
77
|
}
|
|
72
78
|
|
|
@@ -77,39 +83,30 @@ export default class Streamer {
|
|
|
77
83
|
this.audioEnabled = deviceData?.audio_enabled === true;
|
|
78
84
|
this.uuid = deviceData?.nest_google_uuid;
|
|
79
85
|
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (fs.existsSync(path.resolve(resourcePath + '/' + CAMERAOFFLINEH264FILE)) === true) {
|
|
92
|
-
this.#cameraOfflineFrame = fs.readFileSync(path.resolve(resourcePath + '/' + CAMERAOFFLINEH264FILE));
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// load buffer for camera stream off in .h264 frame
|
|
96
|
-
if (fs.existsSync(path.resolve(resourcePath + '/' + CAMERAOFFH264FILE)) === true) {
|
|
97
|
-
this.#cameraVideoOffFrame = fs.readFileSync(path.resolve(resourcePath + '/' + CAMERAOFFH264FILE));
|
|
98
|
-
}
|
|
86
|
+
// Load support video frame files as required
|
|
87
|
+
const loadFrameIfExists = (filename, label) => {
|
|
88
|
+
let buffer = undefined;
|
|
89
|
+
let file = path.resolve(__dirname, RESOURCEPATH, filename);
|
|
90
|
+
if (fs.existsSync(file) === true) {
|
|
91
|
+
buffer = fs.readFileSync(file);
|
|
92
|
+
} else {
|
|
93
|
+
this.log?.warn?.('Failed to load %s video resource for "%s"', label, deviceData.description);
|
|
94
|
+
}
|
|
95
|
+
return buffer;
|
|
96
|
+
};
|
|
99
97
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
98
|
+
this.#cameraOfflineFrame = loadFrameIfExists(CAMERARESOURCE.offline, 'offline');
|
|
99
|
+
this.#cameraVideoOffFrame = loadFrameIfExists(CAMERARESOURCE.off, 'video off');
|
|
100
|
+
this.#cameraTransferringFrame = loadFrameIfExists(CAMERARESOURCE.transfer, 'transferring');
|
|
104
101
|
|
|
105
102
|
// Start a non-blocking loop for output to the various streams which connect to our streamer object
|
|
106
103
|
// This process will also handle the rolling-buffer size we require
|
|
107
104
|
// Record streams will always start from the beginning of the buffer (tail)
|
|
108
105
|
// Live streams will always start from the end of the buffer (head)
|
|
109
|
-
let
|
|
106
|
+
let lastVideoFrameTime = Date.now();
|
|
110
107
|
this.#outputTimer = setInterval(() => {
|
|
111
108
|
let dateNow = Date.now();
|
|
112
|
-
let outputVideoFrame = dateNow
|
|
109
|
+
let outputVideoFrame = dateNow - lastVideoFrameTime >= STREAMFRAMEINTERVAL;
|
|
113
110
|
Object.values(this.#outputs).forEach((output) => {
|
|
114
111
|
// Monitor for camera going offline, video enabled/disabled or being transferred between Nest/Google Home
|
|
115
112
|
// We'll insert the appropriate video frame into the stream
|
|
@@ -117,26 +114,28 @@ export default class Streamer {
|
|
|
117
114
|
// Camera is offline so feed in our custom h264 frame and AAC silence
|
|
118
115
|
output.buffer.push({ time: dateNow, type: 'video', data: this.#cameraOfflineFrame });
|
|
119
116
|
output.buffer.push({ time: dateNow, type: 'audio', data: this.blankAudio });
|
|
120
|
-
|
|
117
|
+
lastVideoFrameTime = dateNow;
|
|
121
118
|
}
|
|
122
119
|
if (this.online === true && this.videoEnabled === false && this.#cameraVideoOffFrame !== undefined && outputVideoFrame === true) {
|
|
123
120
|
// Camera video is turned off so feed in our custom h264 frame and AAC silence
|
|
124
121
|
output.buffer.push({ time: dateNow, type: 'video', data: this.#cameraVideoOffFrame });
|
|
125
122
|
output.buffer.push({ time: dateNow, type: 'audio', data: this.blankAudio });
|
|
126
|
-
|
|
123
|
+
lastVideoFrameTime = dateNow;
|
|
127
124
|
}
|
|
128
125
|
if (this.migrating === true && this.#cameraTransferringFrame !== undefined && outputVideoFrame === true) {
|
|
129
126
|
// Camera video is turned off so feed in our custom h264 frame and AAC silence
|
|
130
127
|
output.buffer.push({ time: dateNow, type: 'video', data: this.#cameraTransferringFrame });
|
|
131
128
|
output.buffer.push({ time: dateNow, type: 'audio', data: this.blankAudio });
|
|
132
|
-
|
|
129
|
+
lastVideoFrameTime = dateNow;
|
|
133
130
|
}
|
|
134
131
|
|
|
135
132
|
// Keep our 'main' rolling buffer under a certain size
|
|
136
133
|
// Live/record buffers will always reduce in length in the next section
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
output.buffer.
|
|
134
|
+
if (output.type === 'buffer') {
|
|
135
|
+
let cutoffTime = dateNow - MAXBUFFERAGE;
|
|
136
|
+
while (output.buffer.length > 0 && output.buffer[0].time < cutoffTime) {
|
|
137
|
+
output.buffer.shift();
|
|
138
|
+
}
|
|
140
139
|
}
|
|
141
140
|
|
|
142
141
|
// Output the packet data to any 'live' or 'recording' streams
|
|
@@ -151,7 +150,7 @@ export default class Streamer {
|
|
|
151
150
|
}
|
|
152
151
|
}
|
|
153
152
|
});
|
|
154
|
-
},
|
|
153
|
+
}, 10); // Every 10ms, rather than "next tick"
|
|
155
154
|
}
|
|
156
155
|
|
|
157
156
|
// Class functions
|
|
@@ -163,7 +162,7 @@ export default class Streamer {
|
|
|
163
162
|
if (this.#outputs?.buffer === undefined) {
|
|
164
163
|
// No active buffer session, start connection to streamer
|
|
165
164
|
if (this.online === true && this.videoEnabled === true && this.connected === undefined && typeof this.connect === 'function') {
|
|
166
|
-
this?.log?.debug
|
|
165
|
+
this?.log?.debug?.('Started buffering for uuid "%s"', this.uuid);
|
|
167
166
|
this.connect();
|
|
168
167
|
}
|
|
169
168
|
|
|
@@ -209,10 +208,8 @@ export default class Streamer {
|
|
|
209
208
|
});
|
|
210
209
|
}
|
|
211
210
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
this.connect();
|
|
215
|
-
}
|
|
211
|
+
// We do not have an active connection, so startup connection
|
|
212
|
+
this.#doConnect();
|
|
216
213
|
|
|
217
214
|
// Add video/audio streams for our output loop to handle outputting
|
|
218
215
|
this.#outputs[sessionID] = {
|
|
@@ -224,13 +221,12 @@ export default class Streamer {
|
|
|
224
221
|
};
|
|
225
222
|
|
|
226
223
|
// finally, we've started live stream
|
|
227
|
-
this?.log?.debug
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
);
|
|
224
|
+
this?.log?.debug?.(
|
|
225
|
+
'Started live stream from uuid "%s" %s "%s"',
|
|
226
|
+
this.uuid,
|
|
227
|
+
talkbackStream !== null && typeof talkbackStream === 'object' ? 'with two-way audio and session id of' : 'and session id of',
|
|
228
|
+
sessionID,
|
|
229
|
+
);
|
|
234
230
|
}
|
|
235
231
|
|
|
236
232
|
startRecordStream(sessionID, videoStream, audioStream) {
|
|
@@ -247,10 +243,8 @@ export default class Streamer {
|
|
|
247
243
|
});
|
|
248
244
|
}
|
|
249
245
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
this.connect();
|
|
253
|
-
}
|
|
246
|
+
// We do not have an active connection, so startup connection
|
|
247
|
+
this.#doConnect();
|
|
254
248
|
|
|
255
249
|
// Add video/audio streams for our output loop to handle outputting
|
|
256
250
|
this.#outputs[sessionID] = {
|
|
@@ -262,13 +256,13 @@ export default class Streamer {
|
|
|
262
256
|
};
|
|
263
257
|
|
|
264
258
|
// Finally we've started the recording stream
|
|
265
|
-
this?.log?.debug
|
|
259
|
+
this?.log?.debug?.('Started recording stream from uuid "%s" with session id of "%s"', this.uuid, sessionID);
|
|
266
260
|
}
|
|
267
261
|
|
|
268
262
|
stopRecordStream(sessionID) {
|
|
269
263
|
// Request to stop a recording stream
|
|
270
264
|
if (this.#outputs?.[sessionID] !== undefined) {
|
|
271
|
-
this?.log?.debug
|
|
265
|
+
this?.log?.debug?.('Stopped recording stream from uuid "%s"', this.uuid);
|
|
272
266
|
delete this.#outputs[sessionID];
|
|
273
267
|
}
|
|
274
268
|
|
|
@@ -281,7 +275,7 @@ export default class Streamer {
|
|
|
281
275
|
stopLiveStream(sessionID) {
|
|
282
276
|
// Request to stop an active live stream
|
|
283
277
|
if (this.#outputs?.[sessionID] !== undefined) {
|
|
284
|
-
this?.log?.debug
|
|
278
|
+
this?.log?.debug?.('Stopped live stream from uuid "%s"', this.uuid);
|
|
285
279
|
delete this.#outputs[sessionID];
|
|
286
280
|
}
|
|
287
281
|
|
|
@@ -293,7 +287,7 @@ export default class Streamer {
|
|
|
293
287
|
|
|
294
288
|
stopBuffering() {
|
|
295
289
|
if (this.#outputs?.buffer !== undefined) {
|
|
296
|
-
this?.log?.debug
|
|
290
|
+
this?.log?.debug?.('Stopped buffering from uuid "%s"', this.uuid);
|
|
297
291
|
delete this.#outputs.buffer;
|
|
298
292
|
}
|
|
299
293
|
|
|
@@ -305,7 +299,7 @@ export default class Streamer {
|
|
|
305
299
|
|
|
306
300
|
stopEverything() {
|
|
307
301
|
if (this.haveOutputs() === true) {
|
|
308
|
-
this?.log?.debug
|
|
302
|
+
this?.log?.debug?.('Stopped buffering, live and recording from uuid "%s"', this.uuid);
|
|
309
303
|
this.#outputs = {}; // No more outputs
|
|
310
304
|
if (typeof this.close === 'function') {
|
|
311
305
|
this.close();
|
|
@@ -328,9 +322,7 @@ export default class Streamer {
|
|
|
328
322
|
if (typeof this.close === 'function') {
|
|
329
323
|
this.close();
|
|
330
324
|
}
|
|
331
|
-
|
|
332
|
-
this.connect();
|
|
333
|
-
}
|
|
325
|
+
this.#doConnect();
|
|
334
326
|
}
|
|
335
327
|
}
|
|
336
328
|
|
|
@@ -339,7 +331,7 @@ export default class Streamer {
|
|
|
339
331
|
this.videoEnabled !== deviceData.streaming_enabled ||
|
|
340
332
|
this.audioEnabled !== deviceData?.audio_enabled
|
|
341
333
|
) {
|
|
342
|
-
// Online status or streaming status has changed
|
|
334
|
+
// Online status or streaming status has changed
|
|
343
335
|
this.online = deviceData?.online === true;
|
|
344
336
|
this.videoEnabled = deviceData?.streaming_enabled === true;
|
|
345
337
|
this.audioEnabled = deviceData?.audio_enabled === true;
|
|
@@ -349,9 +341,7 @@ export default class Streamer {
|
|
|
349
341
|
if ((this.online === false || this.videoEnabled === false || this.audioEnabled === false) && typeof this.close === 'function') {
|
|
350
342
|
this.close(); // as offline or streaming not enabled, close streamer
|
|
351
343
|
}
|
|
352
|
-
|
|
353
|
-
this.connect(); // Connect for stream
|
|
354
|
-
}
|
|
344
|
+
this.#doConnect();
|
|
355
345
|
}
|
|
356
346
|
}
|
|
357
347
|
}
|
|
@@ -378,4 +368,10 @@ export default class Streamer {
|
|
|
378
368
|
haveOutputs() {
|
|
379
369
|
return Object.keys(this.#outputs).length > 0;
|
|
380
370
|
}
|
|
371
|
+
|
|
372
|
+
#doConnect() {
|
|
373
|
+
if (this.online === true && this.videoEnabled === true && this.connected === undefined && typeof this.connect === 'function') {
|
|
374
|
+
this.connect();
|
|
375
|
+
}
|
|
376
|
+
}
|
|
381
377
|
}
|