@mega-yfue/eufy-sdk 0.4.0-beta.23 → 0.4.0-beta.25

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/index.js CHANGED
@@ -18384,101 +18384,6 @@ function annexbToJpeg(annexb, spawn2) {
18384
18384
 
18385
18385
  // dist/transport/p2p/recording-download.js
18386
18386
  import { createDecipheriv as createDecipheriv7 } from "node:crypto";
18387
-
18388
- // dist/transport/p2p/adts.js
18389
- var PROFILE_AAC_LC = 1;
18390
- var FREQ_INDEX_16K = 8;
18391
- var CHANNELS_MONO = 1;
18392
- var AAC_SAMPLES_PER_FRAME = 1024;
18393
- var AAC_SAMPLE_RATE = 16e3;
18394
- var AAC_FRAME_MS = AAC_SAMPLES_PER_FRAME * 1e3 / AAC_SAMPLE_RATE;
18395
- var MAX_AUDIO_FRAME_BYTES = 640;
18396
- var HEADER_LEN_NO_CRC = 7;
18397
- function parseAdtsHeader(buf, offset = 0) {
18398
- if (offset + HEADER_LEN_NO_CRC > buf.length)
18399
- return void 0;
18400
- if (buf[offset] !== 255 || (buf[offset + 1] & 240) !== 240)
18401
- return void 0;
18402
- const headerLength = buf[offset + 1] & 1 ? 7 : 9;
18403
- const frameLength = (buf[offset + 3] & 3) << 11 | buf[offset + 4] << 3 | (buf[offset + 5] & 224) >> 5;
18404
- if (frameLength < headerLength)
18405
- return void 0;
18406
- return {
18407
- frameLength,
18408
- headerLength,
18409
- profile: (buf[offset + 2] & 192) >> 6,
18410
- frequencyIndex: (buf[offset + 2] & 60) >> 2,
18411
- channels: (buf[offset + 2] & 1) << 2 | (buf[offset + 3] & 192) >> 6
18412
- };
18413
- }
18414
- function buildAdtsHeader(payloadLength) {
18415
- const frameLength = payloadLength + HEADER_LEN_NO_CRC;
18416
- return Buffer.from([
18417
- 255,
18418
- 241,
18419
- PROFILE_AAC_LC << 6 | FREQ_INDEX_16K << 2 | CHANNELS_MONO >> 2,
18420
- (CHANNELS_MONO & 3) << 6 | frameLength >> 11 & 3,
18421
- frameLength >> 3 & 255,
18422
- (frameLength & 7) << 5 | 31,
18423
- 252
18424
- ]);
18425
- }
18426
- function isSupportedAdts(h) {
18427
- return h.profile === PROFILE_AAC_LC && h.frequencyIndex === FREQ_INDEX_16K && h.channels === CHANNELS_MONO;
18428
- }
18429
- function describeAdts(h) {
18430
- const rate = ADTS_SAMPLE_RATES[h.frequencyIndex] ?? `index ${h.frequencyIndex}`;
18431
- const profile = h.profile === PROFILE_AAC_LC ? "AAC-LC" : `profile field ${h.profile}`;
18432
- return `${profile}, ${rate} Hz, ${h.channels} channel(s)`;
18433
- }
18434
- var ADTS_SAMPLE_RATES = [
18435
- 96e3,
18436
- 88200,
18437
- 64e3,
18438
- 48e3,
18439
- 44100,
18440
- 32e3,
18441
- 24e3,
18442
- 22050,
18443
- 16e3,
18444
- 12e3,
18445
- 11025,
18446
- 8e3,
18447
- 7350
18448
- ];
18449
- var AdtsFrameReader = class {
18450
- buffered = Buffer.alloc(0);
18451
- /**
18452
- * Append `chunk` and return every complete frame now available, each a standalone buffer that still
18453
- * carries its own ADTS header (the device expects the header on the wire).
18454
- */
18455
- push(chunk) {
18456
- this.buffered = this.buffered.length ? Buffer.concat([this.buffered, chunk]) : chunk;
18457
- const frames = [];
18458
- let at = 0;
18459
- for (; ; ) {
18460
- const h = parseAdtsHeader(this.buffered, at);
18461
- if (!h) {
18462
- if (at + HEADER_LEN_NO_CRC > this.buffered.length)
18463
- break;
18464
- at++;
18465
- continue;
18466
- }
18467
- if (at + h.frameLength > this.buffered.length)
18468
- break;
18469
- frames.push(this.buffered.subarray(at, at + h.frameLength));
18470
- at += h.frameLength;
18471
- }
18472
- this.buffered = at ? this.buffered.subarray(at) : this.buffered;
18473
- return frames;
18474
- }
18475
- /** Bytes held back awaiting the rest of their frame — non-zero mid-stream, zero on a clean boundary. */
18476
- get pending() {
18477
- return this.buffered.length;
18478
- }
18479
- };
18480
-
18481
- // dist/transport/p2p/recording-download.js
18482
18387
  var RECORDING_DATA_TYPE = 3;
18483
18388
  var VIDEO_HEADER_LEN2 = 22;
18484
18389
  var AUDIO_HEADER_LEN2 = 16;
@@ -18637,7 +18542,7 @@ function decodeRecording(frames, eccPrivateKeyHex) {
18637
18542
  continue;
18638
18543
  const aac = openAudio(mediaKey, raw.subarray(AUDIO_NONCE_START, AUDIO_BODY_START), raw.subarray(AUDIO_HEADER_LEN2, AUDIO_NONCE_START), raw.subarray(AUDIO_BODY_START, AUDIO_BODY_START + len));
18639
18544
  if (aac?.length)
18640
- audio.push(buildAdtsHeader(aac.length), aac);
18545
+ audio.push(aac);
18641
18546
  }
18642
18547
  }
18643
18548
  if (!video.length)
@@ -19783,6 +19688,89 @@ function openReadableFromConsumer(consumer, opts = {}) {
19783
19688
  // dist/transport/p2p/talkback.js
19784
19689
  import { EventEmitter as EventEmitter5 } from "node:events";
19785
19690
  import { Writable } from "node:stream";
19691
+
19692
+ // dist/transport/p2p/adts.js
19693
+ var PROFILE_AAC_LC = 1;
19694
+ var FREQ_INDEX_16K = 8;
19695
+ var CHANNELS_MONO = 1;
19696
+ var AAC_SAMPLES_PER_FRAME = 1024;
19697
+ var AAC_SAMPLE_RATE = 16e3;
19698
+ var AAC_FRAME_MS = AAC_SAMPLES_PER_FRAME * 1e3 / AAC_SAMPLE_RATE;
19699
+ var MAX_AUDIO_FRAME_BYTES = 640;
19700
+ var HEADER_LEN_NO_CRC = 7;
19701
+ function parseAdtsHeader(buf, offset = 0) {
19702
+ if (offset + HEADER_LEN_NO_CRC > buf.length)
19703
+ return void 0;
19704
+ if (buf[offset] !== 255 || (buf[offset + 1] & 240) !== 240)
19705
+ return void 0;
19706
+ const headerLength = buf[offset + 1] & 1 ? 7 : 9;
19707
+ const frameLength = (buf[offset + 3] & 3) << 11 | buf[offset + 4] << 3 | (buf[offset + 5] & 224) >> 5;
19708
+ if (frameLength < headerLength)
19709
+ return void 0;
19710
+ return {
19711
+ frameLength,
19712
+ headerLength,
19713
+ profile: (buf[offset + 2] & 192) >> 6,
19714
+ frequencyIndex: (buf[offset + 2] & 60) >> 2,
19715
+ channels: (buf[offset + 2] & 1) << 2 | (buf[offset + 3] & 192) >> 6
19716
+ };
19717
+ }
19718
+ function isSupportedAdts(h) {
19719
+ return h.profile === PROFILE_AAC_LC && h.frequencyIndex === FREQ_INDEX_16K && h.channels === CHANNELS_MONO;
19720
+ }
19721
+ function describeAdts(h) {
19722
+ const rate = ADTS_SAMPLE_RATES[h.frequencyIndex] ?? `index ${h.frequencyIndex}`;
19723
+ const profile = h.profile === PROFILE_AAC_LC ? "AAC-LC" : `profile field ${h.profile}`;
19724
+ return `${profile}, ${rate} Hz, ${h.channels} channel(s)`;
19725
+ }
19726
+ var ADTS_SAMPLE_RATES = [
19727
+ 96e3,
19728
+ 88200,
19729
+ 64e3,
19730
+ 48e3,
19731
+ 44100,
19732
+ 32e3,
19733
+ 24e3,
19734
+ 22050,
19735
+ 16e3,
19736
+ 12e3,
19737
+ 11025,
19738
+ 8e3,
19739
+ 7350
19740
+ ];
19741
+ var AdtsFrameReader = class {
19742
+ buffered = Buffer.alloc(0);
19743
+ /**
19744
+ * Append `chunk` and return every complete frame now available, each a standalone buffer that still
19745
+ * carries its own ADTS header (the device expects the header on the wire).
19746
+ */
19747
+ push(chunk) {
19748
+ this.buffered = this.buffered.length ? Buffer.concat([this.buffered, chunk]) : chunk;
19749
+ const frames = [];
19750
+ let at = 0;
19751
+ for (; ; ) {
19752
+ const h = parseAdtsHeader(this.buffered, at);
19753
+ if (!h) {
19754
+ if (at + HEADER_LEN_NO_CRC > this.buffered.length)
19755
+ break;
19756
+ at++;
19757
+ continue;
19758
+ }
19759
+ if (at + h.frameLength > this.buffered.length)
19760
+ break;
19761
+ frames.push(this.buffered.subarray(at, at + h.frameLength));
19762
+ at += h.frameLength;
19763
+ }
19764
+ this.buffered = at ? this.buffered.subarray(at) : this.buffered;
19765
+ return frames;
19766
+ }
19767
+ /** Bytes held back awaiting the rest of their frame — non-zero mid-stream, zero on a clean boundary. */
19768
+ get pending() {
19769
+ return this.buffered.length;
19770
+ }
19771
+ };
19772
+
19773
+ // dist/transport/p2p/talkback.js
19786
19774
  var DEFAULT_HIGH_WATER_FRAMES = Math.ceil(2e3 / AAC_FRAME_MS);
19787
19775
  var DEFAULT_IDLE_TIMEOUT_MS = 3e4;
19788
19776
  var Talkback = class extends EventEmitter5 {
@@ -21596,9 +21584,9 @@ var P2PCommandRouter = class _P2PCommandRouter {
21596
21584
  *
21597
21585
  * Reached two ways, both idempotent: the session's own `close` event, when it died while still the
21598
21586
  * station's registered session, and {@link SessionManagerOpts.onAutoClose}, when the manager closed it
21599
- * unasked. A close a CALLER made is deliberately not routed here — {@link closeAll} disposes its own
21600
- * sources first, and {@link replaceUnreachableSession} keeps its source alive on purpose to rewarm it
21601
- * on the replacement session.
21587
+ * unasked. A close a CALLER made is deliberately not routed here — {@link closeAll} and
21588
+ * {@link resolveSession} dispose their own sources first, while {@link replaceUnreachableSession} keeps
21589
+ * its source alive on purpose to rewarm it on the replacement session.
21602
21590
  */
21603
21591
  tearDownStation(stationSn) {
21604
21592
  this.manager.remove(stationSn);
@@ -21917,9 +21905,10 @@ var P2PCommandRouter = class _P2PCommandRouter {
21917
21905
  *
21918
21906
  * A session whose {@link P2PSession.pathAnswering} is false is closed and re-resolved before it is handed
21919
21907
  * over: the station answers every heartbeat, so a path silent past several of them is gone. A session
21920
- * reporting nothing about its path is not reporting that evidence and is handed over as it is. Replaced at
21921
- * most once per resolution, so a station whose replacement is silent too is returned rather than closed
21922
- * again.
21908
+ * reporting nothing about its path is not reporting that evidence and is handed over as it is. Cached live
21909
+ * sources on the replaced session are discarded before closing it (see {@link tearDownStation}).
21910
+ * Replaced at most once per resolution, so a station whose replacement is silent too is returned rather
21911
+ * than closed again.
21923
21912
  */
21924
21913
  async resolveSession(sn, opts = {}, rebuilt = false) {
21925
21914
  const dev = await this.deviceFor(sn);
@@ -21933,6 +21922,10 @@ var P2PCommandRouter = class _P2PCommandRouter {
21933
21922
  }
21934
21923
  if (session.pathAnswering === false && !rebuilt) {
21935
21924
  (this.deps.logger ?? noopLogger).debug(`[p2p] ${parentSn} path stopped answering \u2014 rebuilding before use`);
21925
+ for (const [key, sessionKey] of [...this.liveSessionKeys]) {
21926
+ if (sessionKey === parentSn)
21927
+ this.dropLiveSource(key);
21928
+ }
21936
21929
  await this.manager.close(parentSn).catch((error) => this.reportError(error instanceof Error ? error : new Error(String(error))));
21937
21930
  return await this.resolveSession(sn, opts, true);
21938
21931
  }