eufy-security-client 3.8.0-dev.15 → 3.8.0-dev.17

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.
@@ -149,6 +149,15 @@ export interface StreamMetadata {
149
149
  videoHeight: number;
150
150
  audioCodec: AudioCodec;
151
151
  }
152
+ /** Configurable timeout values for P2P streaming. All values in milliseconds. */
153
+ export interface StreamTimeoutOptions {
154
+ /** Max time to wait for stream data before auto-stopping. Default: 5000ms. */
155
+ streamDataWait?: number;
156
+ /** Time to wait for first audio frame before declaring no audio. Default: 650ms. */
157
+ audioCodecAnalyze?: number;
158
+ /** Max time to wait for an expected sequence number. Default: 20000ms. */
159
+ expectedSeqNoWait?: number;
160
+ }
152
161
  export interface DeviceSerial {
153
162
  [index: number]: {
154
163
  sn: string;
@@ -2,7 +2,7 @@ import { TypedEmitter } from "tiny-typed-emitter";
2
2
  import * as NodeRSA from "node-rsa";
3
3
  import { Address, CustomData } from "./models";
4
4
  import { CommandType, P2PDataType, P2PConnectionType } from "./types";
5
- import { P2PClientProtocolEvents, P2PCommand } from "./interfaces";
5
+ import { P2PClientProtocolEvents, P2PCommand, StreamTimeoutOptions } from "./interfaces";
6
6
  import { StationListResponse } from "../http/models";
7
7
  import { HTTPApi } from "../http/api";
8
8
  export declare class P2PClientProtocol extends TypedEmitter<P2PClientProtocolEvents> {
@@ -24,6 +24,7 @@ export declare class P2PClientProtocol extends TypedEmitter<P2PClientProtocolEve
24
24
  private readonly ESD_DISCONNECT_TIMEOUT;
25
25
  private readonly MAX_STREAM_DATA_WAIT;
26
26
  private readonly RESEND_NOT_ACKNOWLEDGED_COMMAND;
27
+ private streamTimeouts;
27
28
  private readonly UDP_RECVBUFFERSIZE_BYTES;
28
29
  private readonly MAX_PAYLOAD_BYTES;
29
30
  private readonly MAX_PACKET_BYTES;
@@ -162,6 +163,7 @@ export declare class P2PClientProtocol extends TypedEmitter<P2PClientProtocolEve
162
163
  private emitStreamStopEvent;
163
164
  isStreaming(channel: number, datatype: P2PDataType): boolean;
164
165
  isLiveStreaming(channel: number): boolean;
166
+ setStreamTimeouts(options: StreamTimeoutOptions): void;
165
167
  private isCurrentlyStreaming;
166
168
  isRTSPLiveStreaming(channel: number): boolean;
167
169
  isDownloading(channel: number): boolean;
@@ -38,6 +38,11 @@ class P2PClientProtocol extends tiny_typed_emitter_1.TypedEmitter {
38
38
  ESD_DISCONNECT_TIMEOUT = 30 * 1000;
39
39
  MAX_STREAM_DATA_WAIT = 5 * 1000;
40
40
  RESEND_NOT_ACKNOWLEDGED_COMMAND = 100;
41
+ streamTimeouts = {
42
+ streamDataWait: this.MAX_STREAM_DATA_WAIT,
43
+ audioCodecAnalyze: this.AUDIO_CODEC_ANALYZE_TIMEOUT,
44
+ expectedSeqNoWait: this.MAX_EXPECTED_SEQNO_WAIT,
45
+ };
41
46
  UDP_RECVBUFFERSIZE_BYTES = 1048576;
42
47
  MAX_PAYLOAD_BYTES = 1028;
43
48
  MAX_PACKET_BYTES = 1024;
@@ -1241,7 +1246,7 @@ class P2PClientProtocol extends tiny_typed_emitter_1.TypedEmitter {
1241
1246
  this.currentMessageState[dataType].waitForSeqNoTimeout = setTimeout(() => {
1242
1247
  this.endStream(dataType, true);
1243
1248
  this.currentMessageState[dataType].waitForSeqNoTimeout = undefined;
1244
- }, this.MAX_EXPECTED_SEQNO_WAIT);
1249
+ }, this.streamTimeouts.expectedSeqNoWait);
1245
1250
  if (!this.currentMessageState[dataType].queuedData.get(message.seqNo)) {
1246
1251
  this.currentMessageState[dataType].queuedData.set(message.seqNo, message);
1247
1252
  logging_1.rootP2PLogger.trace(`Received message - DATA ${types_1.P2PDataType[message.type]} - Received not expected sequence, added to the queue for future processing`, {
@@ -1771,6 +1776,7 @@ class P2PClientProtocol extends tiny_typed_emitter_1.TypedEmitter {
1771
1776
  }
1772
1777
  isIFrame(data, isKeyFrame) {
1773
1778
  if (this.rawStation.station_sn.startsWith("T8410") ||
1779
+ this.rawStation.station_sn.startsWith("T8417") ||
1774
1780
  this.rawStation.station_sn.startsWith("T8400") ||
1775
1781
  this.rawStation.station_sn.startsWith("T8401") ||
1776
1782
  this.rawStation.station_sn.startsWith("T8411") ||
@@ -1802,9 +1808,9 @@ class P2PClientProtocol extends tiny_typed_emitter_1.TypedEmitter {
1802
1808
  clearTimeout(this.currentMessageState[dataType].p2pStreamingTimeout);
1803
1809
  }
1804
1810
  this.currentMessageState[dataType].p2pStreamingTimeout = setTimeout(() => {
1805
- logging_1.rootP2PLogger.info(`Stopping the station stream for the device ${this.deviceSNs[this.currentMessageState[dataType].p2pStreamChannel]?.sn}, because we haven't received any data for ${this.MAX_STREAM_DATA_WAIT / 1000} seconds`);
1811
+ logging_1.rootP2PLogger.info(`Stopping the station stream for the device ${this.deviceSNs[this.currentMessageState[dataType].p2pStreamChannel]?.sn}, because we haven't received any data for ${this.streamTimeouts.streamDataWait / 1000} seconds`);
1806
1812
  this.endStream(dataType, sendStopCommand);
1807
- }, this.MAX_STREAM_DATA_WAIT);
1813
+ }, this.streamTimeouts.streamDataWait);
1808
1814
  }
1809
1815
  handleDataBinaryAndVideo(message) {
1810
1816
  if (!this.currentMessageState[message.dataType].invalidStream) {
@@ -1884,6 +1890,7 @@ class P2PClientProtocol extends tiny_typed_emitter_1.TypedEmitter {
1884
1890
  this.currentMessageState[message.dataType].p2pStreamMetadata.videoWidth = videoMetaData.videoWidth;
1885
1891
  if (!this.currentMessageState[message.dataType].p2pStreamFirstVideoDataReceived) {
1886
1892
  if (this.rawStation.station_sn.startsWith("T8410") ||
1893
+ this.rawStation.station_sn.startsWith("T8417") ||
1887
1894
  this.rawStation.station_sn.startsWith("T8400") ||
1888
1895
  this.rawStation.station_sn.startsWith("T8401") ||
1889
1896
  this.rawStation.station_sn.startsWith("T8411") ||
@@ -1973,7 +1980,7 @@ class P2PClientProtocol extends tiny_typed_emitter_1.TypedEmitter {
1973
1980
  this.currentMessageState[message.dataType].p2pStreamNotStarted) {
1974
1981
  this.emitStreamStartEvent(message.dataType);
1975
1982
  }
1976
- }, this.AUDIO_CODEC_ANALYZE_TIMEOUT);
1983
+ }, this.streamTimeouts.audioCodecAnalyze);
1977
1984
  }
1978
1985
  }
1979
1986
  if (this.currentMessageState[message.dataType].p2pStreamNotStarted) {
@@ -2856,11 +2863,16 @@ class P2PClientProtocol extends tiny_typed_emitter_1.TypedEmitter {
2856
2863
  this.emit("garage door status", message.channel, payload.door_id, payload.type);
2857
2864
  }
2858
2865
  }
2859
- else if (json.cmd === types_1.CommandType.CMD_STORAGE_INFO_HB3) {
2866
+ else if (json.cmd === 6246) {
2860
2867
  const payload = json.payload;
2861
- logging_1.rootP2PLogger.debug(`Handle DATA ${types_1.P2PDataType[message.dataType]} - CMD_NOTIFY_PAYLOAD StorageInfo HB3 update`, { stationSN: this.rawStation.station_sn, body: payload?.body });
2862
- if (payload) {
2863
- this.emit("storage info hb3", message.channel, payload.body);
2868
+ logging_1.rootP2PLogger.debug(`Handle DATA ${types_1.P2PDataType[message.dataType]} - CMD_NOTIFY_PAYLOAD Livestream status`, { stationSN: this.rawStation.station_sn, payload: payload });
2869
+ if (payload?.num !== undefined) {
2870
+ if (payload.num > 0) {
2871
+ this.emit("rtsp livestream started", message.channel);
2872
+ }
2873
+ else {
2874
+ this.emit("rtsp livestream stopped", message.channel);
2875
+ }
2864
2876
  }
2865
2877
  }
2866
2878
  else if (json.cmd === types_1.CommandType.CMD_HUB_NOTIFY_UPDATE) {
@@ -3549,6 +3561,9 @@ class P2PClientProtocol extends tiny_typed_emitter_1.TypedEmitter {
3549
3561
  isLiveStreaming(channel) {
3550
3562
  return this.isStreaming(channel, types_1.P2PDataType.VIDEO);
3551
3563
  }
3564
+ setStreamTimeouts(options) {
3565
+ this.streamTimeouts = { ...this.streamTimeouts, ...options };
3566
+ }
3552
3567
  isCurrentlyStreaming() {
3553
3568
  for (const element of Object.values(this.currentMessageState)) {
3554
3569
  if (element.p2pStreaming || element.p2pTalkback)