@mega-yfue/eufy-sdk 0.5.0-beta.18 → 0.5.0-beta.19

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.
@@ -311,6 +311,11 @@ export declare class P2PCommandRouter {
311
311
  * stream costs nothing extra and a talkback on an otherwise idle camera opens the session it needs
312
312
  * instead of playing into silence.
313
313
  *
314
+ * **On a model in {@link ELD_TALKBACK_MODELS}, the speaker plays the codec the camera sends.** So the first
315
+ * audio frame of the media session this talkback holds decides its codec ({@link speakerCodec}), within
316
+ * {@link TALKBACK_CODEC_WAIT_MS} of the session's first frame, and the claim is re-checked after that wait as
317
+ * after the warm-up. Every other model opens `aac-lc` at once.
318
+ *
314
319
  * The level-2 key is waited for softly: only the HomeBase-attached path requires it, and
315
320
  * {@link Talkback.start} reports that failure precisely, so a hard wait here would reject an
316
321
  * own-session camera that legitimately never negotiates one.
@@ -1,10 +1,12 @@
1
1
  /**
2
- * Managed talkback session over P2P — the send-side twin of `live-stream.ts`. Takes AAC-LC audio from
3
- * a host, recovers frame boundaries, and paces the frames onto the wire at their own playback rate,
4
- * bracketed by the device's start/stop control frames.
2
+ * Managed talkback session over P2P — the send-side twin of `live-stream.ts`. Takes audio from a host in
3
+ * the codec the camera's speaker plays (AAC-LC ADTS, or raw AAC-ELD access units), recovers frame
4
+ * boundaries, and paces the frames onto the wire at their own playback rate, bracketed by the device's
5
+ * start/stop control frames.
5
6
  *
6
7
  * Pacing is the reason this exists rather than a bare `sendAudioFrame` loop. Each AAC-LC frame at
7
- * 16 kHz is 1024 samples — exactly 64 ms of audio — and the device plays what arrives when it arrives.
8
+ * 16 kHz is 1024 samples — exactly 64 ms of audio — and each AAC-ELD access unit is 512 samples, 32 ms.
9
+ * The device plays what arrives when it arrives.
8
10
  * A host piping a file would otherwise deliver a minute of audio in a few hundred milliseconds and
9
11
  * lose all but the tail. A live source paces itself and simply keeps the queue near-empty.
10
12
  *
@@ -17,7 +19,7 @@
17
19
  */
18
20
  import { EventEmitter } from "node:events";
19
21
  import { Writable } from "node:stream";
20
- import type { AacEncoder, StreamBudgetNotice, TalkbackHandle } from "../../core/contracts.js";
22
+ import type { AacEncoder, StreamBudgetNotice, TalkbackCodec, TalkbackHandle } from "../../core/contracts.js";
21
23
  import { type Logger } from "../../core/logger.js";
22
24
  /**
23
25
  * The subset of the session this needs — start/stop the path, push one frame, and report a frame the
@@ -66,7 +68,7 @@ export interface TalkbackOptions {
66
68
  export declare const DEFAULT_IDLE_TIMEOUT_MS = 30000;
67
69
  /**
68
70
  * A talkback session bound to one camera channel. Opens the device's path on construction via
69
- * {@link start}, then drains queued frames on a fixed 64 ms tick until {@link stop}.
71
+ * {@link start}, then drains queued frames on a tick of one frame's duration until {@link stop}.
70
72
  */
71
73
  export declare class Talkback extends EventEmitter implements TalkbackHandle {
72
74
  private readonly sink;
@@ -74,7 +76,8 @@ export declare class Talkback extends EventEmitter implements TalkbackHandle {
74
76
  private readonly reader;
75
77
  private readonly queue;
76
78
  private readonly logger;
77
- private readonly highWater;
79
+ /** Playback duration of one queued frame, the pacer's step: 64 ms for `aac-lc`, 32 ms for `aac-eld`. */
80
+ private frameMs;
78
81
  private readonly idleTimeoutMs;
79
82
  private timer?;
80
83
  private started;
@@ -94,17 +97,24 @@ export declare class Talkback extends EventEmitter implements TalkbackHandle {
94
97
  private chain;
95
98
  private readonly onAudioGap;
96
99
  constructor(sink: TalkbackSink, opts: TalkbackOptions);
100
+ /** Frames the pacing queue holds before a writable applies backpressure: {@link HIGH_WATER_MS} of this codec. */
101
+ private get highWater();
102
+ /** The codec this talkback sends, set by {@link start}. */
103
+ codec: TalkbackCodec;
97
104
  /** Frames still queued for the wire. */
98
105
  get pending(): number;
99
106
  /**
100
107
  * Open the device's talkback path and begin the pacing tick. Throws when the topology's control
101
108
  * frame could not be sent — for a HomeBase-attached camera that means the level-2 key was never
102
109
  * negotiated, which would otherwise leave a silent session that accepts audio nobody hears.
110
+ *
111
+ * `codec` is the codec the camera's speaker plays; it fixes the input this talkback accepts and the pacing step.
103
112
  */
104
- start(): this;
113
+ start(codec: TalkbackCodec): this;
105
114
  /**
106
- * Queue audio. Bytes are ADTS AAC, or PCM when an encoder was supplied; either way the input is
107
- * treated as a stream, so a chunk carrying part of a frame is held until the rest arrives.
115
+ * Queue audio in the codec this talkback sends. For `aac-lc` the bytes are ADTS, or PCM when an encoder was
116
+ * supplied, read as a stream, so a chunk carrying part of a frame is held until the rest arrives. For `aac-eld`
117
+ * each call is one whole access unit; a unit over the device's length limit is dropped with an `error`.
108
118
  *
109
119
  * Audio written after {@link end} is dropped with an `error` rather than queued: `finished` has
110
120
  * either already fired or is owed on the frames written before it, so a late chunk would either play
@@ -160,6 +170,7 @@ export declare class Talkback extends EventEmitter implements TalkbackHandle {
160
170
  /**
161
171
  * A Writable over {@link write} that withholds its callback while the queue is at the high-water
162
172
  * mark — which is what turns `pipe()` from a file into playback at speed rather than a memory spike.
173
+ * For `aac-eld` it is object-mode: each write is one access unit.
163
174
  */
164
175
  writable(): Writable;
165
176
  /** Drain an encoder's partial trailing block, so the last syllable is not lost. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mega-yfue/eufy-sdk",
3
- "version": "0.5.0-beta.18",
3
+ "version": "0.5.0-beta.19",
4
4
  "description": "One typed TypeScript client for the Anker eufy v6 cloud — capability-driven devices, realtime events over P2P/MQTT/push, and live media",
5
5
  "license": "Apache-2.0",
6
6
  "author": "mega-yfue",