@homebridge-plugins/homebridge-eufy-security 5.0.0-beta.35 → 5.0.0-beta.37
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/CONTRIBUTING.md +9 -17
- package/config.schema.json +6 -0
- package/dist/account/ownership.js +16 -16
- package/dist/account/ownership.js.map +1 -1
- package/dist/account/persistence.js +24 -74
- package/dist/account/persistence.js.map +1 -1
- package/dist/account/temporary-authentication.js +2 -2
- package/dist/account/temporary-authentication.js.map +1 -1
- package/dist/configuration.js +18 -25
- package/dist/configuration.js.map +1 -1
- package/dist/device/member-evidence.js +1 -1
- package/dist/device/member-evidence.js.map +1 -1
- package/dist/device/member-trust.js +14 -32
- package/dist/device/member-trust.js.map +1 -1
- package/dist/device/snapshot.js +5 -17
- package/dist/device/snapshot.js.map +1 -1
- package/dist/diagnostics.js +268 -308
- package/dist/diagnostics.js.map +1 -1
- package/dist/homekit/adapter.js +4 -1
- package/dist/homekit/adapter.js.map +1 -1
- package/dist/homekit/adapters/battery.js +3 -3
- package/dist/homekit/adapters/battery.js.map +1 -1
- package/dist/homekit/adapters/camera-controls.js +15 -37
- package/dist/homekit/adapters/camera-controls.js.map +1 -1
- package/dist/homekit/adapters/camera-streaming.js +9 -19
- package/dist/homekit/adapters/camera-streaming.js.map +1 -1
- package/dist/homekit/adapters/contact.js +5 -5
- package/dist/homekit/adapters/contact.js.map +1 -1
- package/dist/homekit/adapters/doorbell.js +3 -15
- package/dist/homekit/adapters/doorbell.js.map +1 -1
- package/dist/homekit/adapters/lock.js +15 -214
- package/dist/homekit/adapters/lock.js.map +1 -1
- package/dist/homekit/adapters/motion.js +2 -2
- package/dist/homekit/adapters/motion.js.map +1 -1
- package/dist/homekit/adapters/package-sensor.js +2 -2
- package/dist/homekit/adapters/package-sensor.js.map +1 -1
- package/dist/homekit/adapters/security-system.js +11 -211
- package/dist/homekit/adapters/security-system.js.map +1 -1
- package/dist/homekit/adapters/siren.js +5 -33
- package/dist/homekit/adapters/siren.js.map +1 -1
- package/dist/homekit/adapters/smart-light.js +19 -217
- package/dist/homekit/adapters/smart-light.js.map +1 -1
- package/dist/homekit/coverage-matrix.js +8 -65
- package/dist/homekit/coverage-matrix.js.map +1 -1
- package/dist/homekit/device-control.js +249 -13
- package/dist/homekit/device-control.js.map +1 -1
- package/dist/homekit/reconciler.js +5 -5
- package/dist/homekit/reconciler.js.map +1 -1
- package/dist/media/last-successful-image.js +3 -20
- package/dist/media/last-successful-image.js.map +1 -1
- package/dist/media/live-preview.js +163 -42
- package/dist/media/live-preview.js.map +1 -1
- package/dist/media/live-stream.js +126 -72
- package/dist/media/live-stream.js.map +1 -1
- package/dist/media/recording.js +37 -120
- package/dist/media/recording.js.map +1 -1
- package/dist/media/snapshot.js +1 -9
- package/dist/media/snapshot.js.map +1 -1
- package/dist/media/station-live-sessions.js +0 -15
- package/dist/media/station-live-sessions.js.map +1 -1
- package/dist/platform.js +10 -10
- package/dist/platform.js.map +1 -1
- package/dist/runtime/channel.js +91 -69
- package/dist/runtime/channel.js.map +1 -1
- package/dist/runtime/owner.js +6 -6
- package/dist/runtime/owner.js.map +1 -1
- package/dist/runtime/sdk-client.js +3 -14
- package/dist/runtime/sdk-client.js.map +1 -1
- package/dist/runtime/tracker.js +8 -38
- package/dist/runtime/tracker.js.map +1 -1
- package/dist/storage.js +1 -1
- package/dist/storage.js.map +1 -1
- package/dist/ui/runtime-channel-client.js +145 -282
- package/dist/ui/runtime-channel-client.js.map +1 -1
- package/dist/ui/server.js +39 -53
- package/dist/ui/server.js.map +1 -1
- package/homebridge-ui/public/app.css +150 -78
- package/homebridge-ui/public/i18n/en.json +15 -2
- package/homebridge-ui/public/i18n/fr.json +15 -2
- package/homebridge-ui/public/index.html +59 -10
- package/homebridge-ui/public/js/app.js +206 -42
- package/homebridge-ui/public/js/dashboard.js +4 -19
- package/i18n/runtime/en.json +1 -0
- package/package.json +3 -7
- package/homebridge-ui/public/js/legacy-settings.js +0 -37
- package/homebridge-ui/public/js/profile-wizard.js +0 -31
- package/homebridge-ui/public/js/setup-wizard.js +0 -52
|
@@ -1,26 +1,72 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
-
import { commonArguments,
|
|
2
|
+
import { adaptationReporter, AdaptationStderr, commonArguments, stopProcess, } from './live-stream.js';
|
|
3
3
|
/** How long one preview runs before it ends on its own, so a page left open does not hold a camera. */
|
|
4
|
-
|
|
4
|
+
const LIVE_PREVIEW_MAX_MS = 3 * 60_000;
|
|
5
|
+
/** How long coded video may flow without decoding to a picture before the HomeKit side ends as unplayable. */
|
|
6
|
+
export const LIVE_PREVIEW_PICTURE_MS = 10_000;
|
|
5
7
|
/** The most bytes one picture may reach before FFmpeg's output is taken as no longer pictures. */
|
|
6
8
|
const MAX_PICTURE_BYTES = 1024 * 1024;
|
|
7
9
|
const JPEG_END = Buffer.from([0xff, 0xd9]);
|
|
8
|
-
/** The
|
|
9
|
-
const
|
|
10
|
+
/** The JPEG output both preview sides are decoded into: five pictures a second, 640 pixels wide, on stdout. */
|
|
11
|
+
const STILLS = ['-an', '-vf', 'fps=5,scale=640:-2', '-q:v', '8', '-f', 'image2pipe', '-c:v', 'mjpeg', 'pipe:1'];
|
|
12
|
+
/** What an iPhone asks a camera for, on Wi-Fi and on cellular: High 4.0 at 30 fps over a 1378-byte MTU. */
|
|
13
|
+
const IPHONE = { fps: 30, profile: 'high', level: '4.0', payloadType: 99, ssrc: 1, mtu: 1378, rtcpInterval: 0.5 };
|
|
14
|
+
const IPHONE_ASKS = {
|
|
15
|
+
wifi: { ...IPHONE, width: 1280, height: 720, maxBitRate: 299 },
|
|
16
|
+
cellular: { ...IPHONE, width: 640, height: 360, maxBitRate: 132 },
|
|
17
|
+
};
|
|
10
18
|
/**
|
|
11
|
-
* A camera's live video as JPEG pictures, five a second and 640 pixels wide,
|
|
19
|
+
* A camera's live video as JPEG pictures for the settings page, five a second and 640 pixels wide, on two sides:
|
|
20
|
+
* `raw` decoded straight from the camera, and `homekit` coded as a live session configured with `adaptation`
|
|
21
|
+
* codes it for that iPhone ask, and decoded again.
|
|
12
22
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
23
|
+
* Each picture carries its side, the encoder of the HomeKit side and, once that has written for a second, the
|
|
24
|
+
* kilobits a second it wrote.
|
|
25
|
+
*
|
|
26
|
+
* The SDK source is fanned out to two FFmpegs: one decodes it into the `raw` pictures, one runs the session's own
|
|
27
|
+
* encoder and argument list and writes the coded H.264 elementary stream, which a third decodes into the
|
|
28
|
+
* `homekit` pictures. The camera side starts at the first keyframe, and each HomeKit run at a keyframe too. No
|
|
29
|
+
* audio. A write either refuses holds the SDK source until it drains, so the SDK's keyframe-aware queue is the
|
|
30
|
+
* only one, and the HomeKit decoder holds the encoder the same way.
|
|
31
|
+
*
|
|
32
|
+
* `adapt` ends the HomeKit run and starts the next with other settings at the next keyframe, leaving the source
|
|
33
|
+
* and the camera side running. A HomeKit run that fails, or yields no picture within
|
|
34
|
+
* {@link LIVE_PREVIEW_PICTURE_MS}, ends alone with an empty `homekit` picture while the camera side showed, and
|
|
35
|
+
* no other starts until `adapt`. `onRun` is called once with each run's result, and with one result where none
|
|
36
|
+
* started. A codec change, a source or camera side failure, the time limit and `stop` end the whole preview, and
|
|
37
|
+
* `onEnd` is called exactly once, saying whether the last run was unplayable. `diagnostics` receives each
|
|
38
|
+
* process's `started` and `output` notices as a live session's do, under the `preview-raw`, `preview-encode` and
|
|
39
|
+
* `preview-decode` roles.
|
|
16
40
|
*/
|
|
17
|
-
export function startLivePreview(executable, source, onPicture, onEnd) {
|
|
41
|
+
export function startLivePreview(executable, media, source, adaptation, onPicture, onRun, onEnd, diagnostics) {
|
|
42
|
+
const report = adaptationReporter(diagnostics);
|
|
18
43
|
const abandonment = new AbortController();
|
|
19
44
|
let live;
|
|
20
|
-
let
|
|
45
|
+
let raw;
|
|
46
|
+
let rawPictures = 0;
|
|
21
47
|
let codec;
|
|
48
|
+
let homekit;
|
|
49
|
+
let latest;
|
|
50
|
+
let wanted = true;
|
|
51
|
+
let last;
|
|
22
52
|
let ended = false;
|
|
23
|
-
const
|
|
53
|
+
const finish = (stopped) => {
|
|
54
|
+
const run = homekit;
|
|
55
|
+
homekit = undefined;
|
|
56
|
+
clearTimeout(run?.pictureless);
|
|
57
|
+
run?.processes.forEach(stopProcess);
|
|
58
|
+
const { profile, level, width, height, fps, maxBitRate } = IPHONE_ASKS[adaptation.ask];
|
|
59
|
+
last = {
|
|
60
|
+
outcome: run?.pictures ? 'picture' : stopped ? 'stopped' : rawPictures ? 'unplayable' : 'no-video',
|
|
61
|
+
selection: { profile, level, width, height, fps, maxBitRate },
|
|
62
|
+
...adaptation,
|
|
63
|
+
...(run ? { encoder: run.coding.encoder } : {}),
|
|
64
|
+
...(codec ? { source: codec } : {}),
|
|
65
|
+
...(run?.coding.kbps === undefined ? {} : { kbps: run.coding.kbps }),
|
|
66
|
+
};
|
|
67
|
+
onRun(last);
|
|
68
|
+
};
|
|
69
|
+
const end = (stopped = false) => {
|
|
24
70
|
if (ended)
|
|
25
71
|
return;
|
|
26
72
|
ended = true;
|
|
@@ -32,34 +78,85 @@ export function startLivePreview(executable, source, onPicture, onEnd) {
|
|
|
32
78
|
catch {
|
|
33
79
|
live = undefined;
|
|
34
80
|
}
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
81
|
+
if (homekit || !last)
|
|
82
|
+
finish(stopped);
|
|
83
|
+
if (raw)
|
|
84
|
+
stopProcess(raw);
|
|
85
|
+
onEnd(last?.outcome === 'unplayable');
|
|
86
|
+
};
|
|
87
|
+
const fail = () => {
|
|
88
|
+
if (!rawPictures)
|
|
89
|
+
return end();
|
|
90
|
+
const encoder = homekit.coding.encoder;
|
|
91
|
+
finish(false);
|
|
92
|
+
onPicture(Buffer.alloc(0), { side: 'homekit', encoder });
|
|
44
93
|
};
|
|
45
|
-
const deadline = setTimeout(end, LIVE_PREVIEW_MAX_MS);
|
|
94
|
+
const deadline = setTimeout(() => end(), LIVE_PREVIEW_MAX_MS);
|
|
46
95
|
deadline.unref();
|
|
47
|
-
const
|
|
48
|
-
const process = spawn(executable,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
96
|
+
const spawnRole = (role, args) => {
|
|
97
|
+
const process = spawn(executable, args, { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
98
|
+
const stderr = new AdaptationStderr();
|
|
99
|
+
const lost = () => {
|
|
100
|
+
if (process === raw)
|
|
101
|
+
end();
|
|
102
|
+
else if (homekit?.processes.includes(process))
|
|
103
|
+
fail();
|
|
104
|
+
};
|
|
105
|
+
process.stderr.on('data', (chunk) => stderr.observe(chunk));
|
|
106
|
+
process.once('error', lost);
|
|
107
|
+
process.once('exit', (code, signal) => {
|
|
108
|
+
report(role, 'output', stderr, code, signal);
|
|
109
|
+
lost();
|
|
110
|
+
});
|
|
111
|
+
process.stdin.on('error', lost);
|
|
112
|
+
return process;
|
|
113
|
+
};
|
|
114
|
+
const stills = (output, side, run) => {
|
|
52
115
|
let pending = Buffer.alloc(0);
|
|
53
|
-
|
|
116
|
+
output.on('data', (chunk) => {
|
|
54
117
|
pending = Buffer.concat([pending, chunk]);
|
|
55
118
|
for (let at = pending.indexOf(JPEG_END); at !== -1; at = pending.indexOf(JPEG_END)) {
|
|
56
|
-
|
|
119
|
+
if (run && run !== homekit)
|
|
120
|
+
return;
|
|
121
|
+
if (run) {
|
|
122
|
+
clearTimeout(run.pictureless);
|
|
123
|
+
run.pictures += 1;
|
|
124
|
+
}
|
|
125
|
+
else
|
|
126
|
+
rawPictures += 1;
|
|
127
|
+
onPicture(pending.subarray(0, at + JPEG_END.length), { side, ...(run ?? latest).coding });
|
|
57
128
|
pending = pending.subarray(at + JPEG_END.length);
|
|
58
129
|
}
|
|
59
130
|
if (pending.length > MAX_PICTURE_BYTES)
|
|
60
131
|
end();
|
|
61
132
|
});
|
|
62
|
-
|
|
133
|
+
};
|
|
134
|
+
const startHomeKit = (input) => {
|
|
135
|
+
const ask = IPHONE_ASKS[adaptation.ask];
|
|
136
|
+
const { encoder, args } = media.videoAdaptation(input, ask, ['-f', 'h264', 'pipe:1'], adaptation);
|
|
137
|
+
const cause = last ? 'controller-selection' : 'first';
|
|
138
|
+
diagnostics?.report({ role: 'preview-encode', event: 'started', cause, encoder, source: input });
|
|
139
|
+
const encoding = spawnRole('preview-encode', args);
|
|
140
|
+
diagnostics?.report({ role: 'preview-decode', event: 'started', cause, source: 'h264' });
|
|
141
|
+
const decoding = spawnRole('preview-decode', [...commonArguments('h264'), ...STILLS]);
|
|
142
|
+
const run = { processes: [encoding, decoding], coding: { encoder }, pictures: 0 };
|
|
143
|
+
let firstCodedAt;
|
|
144
|
+
let countedBytes = 0;
|
|
145
|
+
encoding.stdout.on('data', (chunk) => {
|
|
146
|
+
const now = Date.now();
|
|
147
|
+
if (firstCodedAt === undefined) {
|
|
148
|
+
firstCodedAt = now;
|
|
149
|
+
run.pictureless = setTimeout(() => run === homekit && fail(), LIVE_PREVIEW_PICTURE_MS);
|
|
150
|
+
run.pictureless.unref();
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
countedBytes += chunk.length;
|
|
154
|
+
if (now - firstCodedAt >= 1_000)
|
|
155
|
+
run.coding.kbps = Math.round((countedBytes * 8) / (now - firstCodedAt));
|
|
156
|
+
});
|
|
157
|
+
encoding.stdout.pipe(decoding.stdin);
|
|
158
|
+
stills(decoding.stdout, 'homekit', run);
|
|
159
|
+
return (latest = run);
|
|
63
160
|
};
|
|
64
161
|
source.live({ signal: abandonment.signal }).then((consumer) => {
|
|
65
162
|
if (ended) {
|
|
@@ -67,30 +164,54 @@ export function startLivePreview(executable, source, onPicture, onEnd) {
|
|
|
67
164
|
return;
|
|
68
165
|
}
|
|
69
166
|
live = consumer;
|
|
70
|
-
consumer.on('error', end);
|
|
71
|
-
consumer.on('stop', end);
|
|
167
|
+
consumer.on('error', () => end());
|
|
168
|
+
consumer.on('stop', () => end());
|
|
72
169
|
consumer.on('budget', (notice) => notice.extend());
|
|
170
|
+
let held = 0;
|
|
171
|
+
const feed = (stdin, data) => {
|
|
172
|
+
if (stdin.write(data))
|
|
173
|
+
return;
|
|
174
|
+
held += 1;
|
|
175
|
+
consumer.pause();
|
|
176
|
+
const release = () => {
|
|
177
|
+
stdin.off('drain', release).off('close', release);
|
|
178
|
+
if (--held === 0)
|
|
179
|
+
consumer.resume();
|
|
180
|
+
};
|
|
181
|
+
stdin.on('drain', release).on('close', release);
|
|
182
|
+
};
|
|
73
183
|
consumer.on('video', (frame) => {
|
|
74
184
|
if (ended)
|
|
75
185
|
return;
|
|
76
|
-
if (!
|
|
77
|
-
const format = INPUT_FORMATS[frame.codec];
|
|
186
|
+
if (!raw) {
|
|
78
187
|
if (!frame.keyframe)
|
|
79
188
|
return;
|
|
80
|
-
if (!format)
|
|
81
|
-
return end();
|
|
82
189
|
codec = frame.codec;
|
|
83
|
-
|
|
190
|
+
diagnostics?.report({ role: 'preview-raw', event: 'started', cause: 'first', source: codec });
|
|
191
|
+
raw = spawnRole('preview-raw', [...commonArguments(codec === 'h265' ? 'hevc' : codec), ...STILLS]);
|
|
192
|
+
stills(raw.stdout, 'raw');
|
|
84
193
|
}
|
|
85
194
|
if (frame.codec !== codec)
|
|
86
195
|
return end();
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
stdin.once('drain', () => consumer.resume());
|
|
196
|
+
if (wanted && frame.keyframe) {
|
|
197
|
+
wanted = false;
|
|
198
|
+
homekit = startHomeKit(codec);
|
|
91
199
|
}
|
|
200
|
+
feed(raw.stdin, frame.data);
|
|
201
|
+
if (homekit)
|
|
202
|
+
feed(homekit.processes[0].stdin, frame.data);
|
|
92
203
|
});
|
|
93
|
-
}, end);
|
|
94
|
-
return
|
|
204
|
+
}, () => end());
|
|
205
|
+
return {
|
|
206
|
+
stop: () => end(true),
|
|
207
|
+
adapt: (next) => {
|
|
208
|
+
if (ended)
|
|
209
|
+
return;
|
|
210
|
+
if (homekit)
|
|
211
|
+
finish(true);
|
|
212
|
+
adaptation = next;
|
|
213
|
+
wanted = true;
|
|
214
|
+
},
|
|
215
|
+
};
|
|
95
216
|
}
|
|
96
217
|
//# sourceMappingURL=live-preview.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-preview.js","sourceRoot":"","sources":["../../src/media/live-preview.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"live-preview.js","sourceRoot":"","sources":["../../src/media/live-preview.ts"],"names":[],"mappings":"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"}
|