@apocaliss92/nodelink-js 0.4.7 → 0.4.10

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
@@ -8,6 +8,7 @@ import {
8
8
  DUAL_LENS_MODELS,
9
9
  DUAL_LENS_SINGLE_MOTION_MODELS,
10
10
  Intercom,
11
+ MpegTsMuxer,
11
12
  NVR_HUB_EXACT_TYPES,
12
13
  NVR_HUB_MODEL_PATTERNS,
13
14
  ReolinkBaichuanApi,
@@ -20,6 +21,7 @@ import {
20
21
  createNativeStream,
21
22
  createNullLogger,
22
23
  createTaggedLogger,
24
+ decideSleepInferenceTransition,
23
25
  decodeHeader,
24
26
  discoverReolinkDevices,
25
27
  discoverViaArpTable,
@@ -43,7 +45,7 @@ import {
43
45
  parseSupportXml,
44
46
  setGlobalLogger,
45
47
  xmlIndicatesFloodlight
46
- } from "./chunk-GKLOJJ34.js";
48
+ } from "./chunk-HGQ53FB3.js";
47
49
  import {
48
50
  AesStreamDecryptor,
49
51
  BC_AES_IV,
@@ -88,6 +90,7 @@ import {
88
90
  BC_CMD_ID_GET_AUDIO_ALARM,
89
91
  BC_CMD_ID_GET_AUDIO_CFG,
90
92
  BC_CMD_ID_GET_AUDIO_TASK,
93
+ BC_CMD_ID_GET_AUTO_FOCUS,
91
94
  BC_CMD_ID_GET_BATTERY_INFO,
92
95
  BC_CMD_ID_GET_BATTERY_INFO_LIST,
93
96
  BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD,
@@ -96,6 +99,7 @@ import {
96
99
  BC_CMD_ID_GET_DING_DONG_LIST,
97
100
  BC_CMD_ID_GET_DING_DONG_SILENT,
98
101
  BC_CMD_ID_GET_EMAIL_TASK,
102
+ BC_CMD_ID_GET_ENC,
99
103
  BC_CMD_ID_GET_FTP_TASK,
100
104
  BC_CMD_ID_GET_HDD_INFO_LIST,
101
105
  BC_CMD_ID_GET_KIT_AP_CFG,
@@ -104,8 +108,10 @@ import {
104
108
  BC_CMD_ID_GET_ONLINE_USER_LIST,
105
109
  BC_CMD_ID_GET_OSD_DATETIME,
106
110
  BC_CMD_ID_GET_PIR_INFO,
111
+ BC_CMD_ID_GET_PRIVACY_MASK,
107
112
  BC_CMD_ID_GET_PTZ_POSITION,
108
113
  BC_CMD_ID_GET_PTZ_PRESET,
114
+ BC_CMD_ID_GET_PUSH_TASK,
109
115
  BC_CMD_ID_GET_RECORD,
110
116
  BC_CMD_ID_GET_RECORD_CFG,
111
117
  BC_CMD_ID_GET_REC_ENC_CFG,
@@ -134,11 +140,23 @@ import {
134
140
  BC_CMD_ID_QUICK_REPLY_PLAY,
135
141
  BC_CMD_ID_SET_AI_ALARM,
136
142
  BC_CMD_ID_SET_AI_CFG,
143
+ BC_CMD_ID_SET_AI_DENOISE,
144
+ BC_CMD_ID_SET_AUDIO_CFG,
137
145
  BC_CMD_ID_SET_AUDIO_TASK,
146
+ BC_CMD_ID_SET_AUTO_FOCUS,
147
+ BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD,
138
148
  BC_CMD_ID_SET_DING_DONG_CFG,
139
149
  BC_CMD_ID_SET_DING_DONG_SILENT,
150
+ BC_CMD_ID_SET_EMAIL_TASK,
151
+ BC_CMD_ID_SET_ENC,
152
+ BC_CMD_ID_SET_LED_STATE,
140
153
  BC_CMD_ID_SET_MOTION_ALARM,
141
154
  BC_CMD_ID_SET_PIR_INFO,
155
+ BC_CMD_ID_SET_PRIVACY_MASK,
156
+ BC_CMD_ID_SET_PUSH_TASK,
157
+ BC_CMD_ID_SET_RECORD,
158
+ BC_CMD_ID_SET_RECORD_CFG,
159
+ BC_CMD_ID_SET_VIDEO_INPUT,
142
160
  BC_CMD_ID_SET_WHITE_LED_STATE,
143
161
  BC_CMD_ID_SET_WHITE_LED_TASK,
144
162
  BC_CMD_ID_SET_ZOOM_FOCUS,
@@ -163,6 +181,8 @@ import {
163
181
  ReolinkHttpClient,
164
182
  aesDecrypt,
165
183
  aesEncrypt,
184
+ applyStreamPatch,
185
+ applyXmlTagPatch,
166
186
  bcDecrypt,
167
187
  bcEncrypt,
168
188
  bcHeaderHasPayloadOffset,
@@ -197,6 +217,7 @@ import {
197
217
  createDiagnosticsBundle,
198
218
  deriveAesKey,
199
219
  detectVideoCodecFromNal,
220
+ ensureXmlHeader,
200
221
  extractPpsFromAnnexB,
201
222
  extractSpsFromAnnexB,
202
223
  extractVpsFromAnnexB,
@@ -211,8 +232,11 @@ import {
211
232
  isValidH265AnnexBAccessUnit,
212
233
  md5HexUpper,
213
234
  md5StrModern,
235
+ normalizeDayNightMode,
236
+ normalizeOpenClose,
214
237
  parseBcMedia,
215
238
  parseRecordingFileName,
239
+ patchNestedTag,
216
240
  printNvrDiagnostics,
217
241
  runAllDiagnosticsConsecutively,
218
242
  runMultifocalDiagnosticsConsecutively,
@@ -223,7 +247,7 @@ import {
223
247
  testChannelStreams,
224
248
  xmlEscape,
225
249
  zipDirectory
226
- } from "./chunk-TR3V5FTO.js";
250
+ } from "./chunk-EDLMKBG2.js";
227
251
 
228
252
  // src/reolink/baichuan/HlsSessionManager.ts
229
253
  var withTimeout = async (p, ms, label) => {
@@ -4746,6 +4770,9 @@ var Go2rtcTcpServer = class _Go2rtcTcpServer extends EventEmitter2 {
4746
4770
  totalVideoFramesWritten = 0;
4747
4771
  // Prebuffer
4748
4772
  prebuffer = [];
4773
+ // Audio metadata — populated on first valid ADTS AAC frame.
4774
+ // Exposed via getAudioInfo() for the stream-diagnostics feature.
4775
+ audioInfo = null;
4749
4776
  constructor(options) {
4750
4777
  super();
4751
4778
  this.api = options.api;
@@ -4829,6 +4856,45 @@ var Go2rtcTcpServer = class _Go2rtcTcpServer extends EventEmitter2 {
4829
4856
  return this.connectedClients.size;
4830
4857
  }
4831
4858
  // -----------------------------------------------------------------------
4859
+ // Diagnostic subscription API (implements DiagnosticStreamServer)
4860
+ //
4861
+ // Matches the shape of BaichuanRtspServer's diagnostic API so the
4862
+ // stream-diagnostic feature in the Manager app can drive either backend
4863
+ // with identical code.
4864
+ // -----------------------------------------------------------------------
4865
+ /**
4866
+ * Subscribe to the raw native stream for diagnostic purposes.
4867
+ * The subscriber receives the same frames the MPEG-TS muxer consumes
4868
+ * (pre-muxing). Counts as a "consumer" so the native stream is kept alive
4869
+ * for the lifetime of the subscription. If the stream is not already
4870
+ * running (battery camera, prestart=false), this starts it.
4871
+ */
4872
+ async subscribeDiagnostic(id) {
4873
+ this.connectedClients.add(`diag:${id}`);
4874
+ if (!this.nativeStreamActive) {
4875
+ await this.startNativeStream();
4876
+ }
4877
+ if (!this.nativeFanout) {
4878
+ this.connectedClients.delete(`diag:${id}`);
4879
+ throw new Error(
4880
+ "Go2rtcTcpServer: native stream failed to start \u2014 cannot subscribe diagnostic"
4881
+ );
4882
+ }
4883
+ return this.nativeFanout.subscribe(`diag:${id}`);
4884
+ }
4885
+ /** Unsubscribe a diagnostic session and release its consumer slot. */
4886
+ unsubscribeDiagnostic(id) {
4887
+ this.removeClient(`diag:${id}`, "diagnostic unsubscribe");
4888
+ }
4889
+ /**
4890
+ * Returns ADTS AAC audio metadata detected from the native stream, or
4891
+ * null if no audio frame has been observed yet (e.g. video-only cameras
4892
+ * or before the first audio packet arrives).
4893
+ */
4894
+ getAudioInfo() {
4895
+ return this.audioInfo;
4896
+ }
4897
+ // -----------------------------------------------------------------------
4832
4898
  // Client handling
4833
4899
  // -----------------------------------------------------------------------
4834
4900
  handleClient(socket) {
@@ -4873,6 +4939,7 @@ var Go2rtcTcpServer = class _Go2rtcTcpServer extends EventEmitter2 {
4873
4939
  }
4874
4940
  if (!this.active || !this.nativeFanout) return;
4875
4941
  const subscription = this.nativeFanout.subscribe(clientId);
4942
+ let muxer = null;
4876
4943
  const prebufferSnap = this.prebuffer.slice();
4877
4944
  let lastIdrIdx = -1;
4878
4945
  for (let i = prebufferSnap.length - 1; i >= 0; i--) {
@@ -4886,9 +4953,21 @@ var Go2rtcTcpServer = class _Go2rtcTcpServer extends EventEmitter2 {
4886
4953
  this.logger.info?.(
4887
4954
  `[Go2rtcTcpServer] prebuffer replay client=${clientId} frames=${replay.length}`
4888
4955
  );
4956
+ if (!muxer) {
4957
+ muxer = new MpegTsMuxer({
4958
+ videoType: this.detectedVideoType ?? "H264",
4959
+ includeAudio: true
4960
+ });
4961
+ }
4889
4962
  for (const entry of replay) {
4890
4963
  if (socket.destroyed) return;
4891
- socket.write(entry.data);
4964
+ let ts;
4965
+ if (!entry.audio) {
4966
+ ts = muxer.muxVideo(entry.data, entry.pts, entry.isKeyframe);
4967
+ } else {
4968
+ ts = muxer.muxAudio(entry.data, entry.pts);
4969
+ }
4970
+ if (ts.length > 0) socket.write(ts);
4892
4971
  }
4893
4972
  }
4894
4973
  let seenKeyframe = lastIdrIdx >= 0;
@@ -4907,16 +4986,33 @@ var Go2rtcTcpServer = class _Go2rtcTcpServer extends EventEmitter2 {
4907
4986
  break;
4908
4987
  }
4909
4988
  liveFrameCount++;
4910
- const annexB = this.convertFrame(frame);
4989
+ if (frame.audio) {
4990
+ if (muxer) {
4991
+ const pts2 = frame.microseconds ?? Date.now() * 1e3;
4992
+ const ts2 = muxer.muxAudio(frame.data, pts2);
4993
+ if (ts2.length > 0) socket.write(ts2);
4994
+ }
4995
+ continue;
4996
+ }
4997
+ const annexB = this.convertVideoFrame(frame);
4911
4998
  if (!annexB) continue;
4999
+ const isKf = this.isAnnexBKeyframe(annexB, frame.videoType);
4912
5000
  if (!seenKeyframe) {
4913
- if (!this.isAnnexBKeyframe(annexB, frame.videoType)) continue;
5001
+ if (!isKf) continue;
4914
5002
  seenKeyframe = true;
4915
5003
  this.logger.info?.(
4916
5004
  `[Go2rtcTcpServer] first live keyframe client=${clientId} after ${liveFrameCount} frames`
4917
5005
  );
5006
+ if (!muxer) {
5007
+ muxer = new MpegTsMuxer({
5008
+ videoType: frame.videoType ?? this.detectedVideoType ?? "H264",
5009
+ includeAudio: true
5010
+ });
5011
+ }
4918
5012
  }
4919
- socket.write(annexB);
5013
+ const pts = frame.microseconds ?? Date.now() * 1e3;
5014
+ const ts = muxer.muxVideo(annexB, pts, isKf);
5015
+ socket.write(ts);
4920
5016
  liveVideoWritten++;
4921
5017
  this.totalVideoFramesWritten++;
4922
5018
  if (Date.now() - lastLogAt > 1e4) {
@@ -4945,14 +5041,11 @@ var Go2rtcTcpServer = class _Go2rtcTcpServer extends EventEmitter2 {
4945
5041
  // Frame conversion
4946
5042
  // -----------------------------------------------------------------------
4947
5043
  /**
4948
- * Convert a native frame to wire-ready Annex-B.
4949
- * Audio frames are skipped raw TCP carries only video (Annex-B).
4950
- * go2rtc auto-detects the codec from SPS/PPS/VPS NALUs.
5044
+ * Convert a native video frame to Annex-B.
5045
+ * Returns null for audio frames (handled separately by muxAudio).
4951
5046
  */
4952
- convertFrame(frame) {
4953
- if (frame.audio) {
4954
- return null;
4955
- }
5047
+ convertVideoFrame(frame) {
5048
+ if (frame.audio) return null;
4956
5049
  if (frame.data.length === 0) return null;
4957
5050
  try {
4958
5051
  if (frame.videoType === "H264") {
@@ -5016,10 +5109,71 @@ var Go2rtcTcpServer = class _Go2rtcTcpServer extends EventEmitter2 {
5016
5109
  return nals;
5017
5110
  }
5018
5111
  // -----------------------------------------------------------------------
5112
+ // ADTS AAC parsing (used for audio metadata exposed via getAudioInfo)
5113
+ // -----------------------------------------------------------------------
5114
+ /** True if `b` starts with an ADTS AAC syncword (0xFFF). */
5115
+ static isAdtsAacFrame(b) {
5116
+ return b.length >= 2 && b[0] === 255 && (b[1] & 240) === 240;
5117
+ }
5118
+ /**
5119
+ * Parse an ADTS header into {sampleRate, channels, AudioSpecificConfig hex}.
5120
+ * Returns null when the buffer is not a valid ADTS frame.
5121
+ */
5122
+ static parseAdtsSamplingInfo(b) {
5123
+ if (b.length < 7) return null;
5124
+ if (!_Go2rtcTcpServer.isAdtsAacFrame(b)) return null;
5125
+ const samplingIndex = b[2] >> 2 & 15;
5126
+ const sampleRates = [
5127
+ 96e3,
5128
+ 88200,
5129
+ 64e3,
5130
+ 48e3,
5131
+ 44100,
5132
+ 32e3,
5133
+ 24e3,
5134
+ 22050,
5135
+ 16e3,
5136
+ 12e3,
5137
+ 11025,
5138
+ 8e3,
5139
+ 7350
5140
+ ];
5141
+ const sampleRate = sampleRates[samplingIndex] ?? null;
5142
+ if (!sampleRate) return null;
5143
+ const channelConfig = (b[2] & 1) << 2 | b[3] >> 6 & 3;
5144
+ const channels = channelConfig === 0 ? 1 : channelConfig;
5145
+ const profile = b[2] >> 6 & 3;
5146
+ const audioObjectType = profile + 1;
5147
+ const asc = audioObjectType << 11 | samplingIndex << 7 | channelConfig << 3;
5148
+ const configHex = Buffer.from([asc >> 8 & 255, asc & 255]).toString(
5149
+ "hex"
5150
+ );
5151
+ return { sampleRate, channels, configHex };
5152
+ }
5153
+ // -----------------------------------------------------------------------
5019
5154
  // Native stream management
5020
5155
  // -----------------------------------------------------------------------
5021
5156
  async startNativeStream() {
5022
5157
  if (this.nativeStreamActive) return;
5158
+ if (!this.api.isReady) {
5159
+ if (this.api.isClosed) {
5160
+ this.logger.warn?.(
5161
+ `[Go2rtcTcpServer] API has been explicitly closed \u2014 stream cannot start`
5162
+ );
5163
+ return;
5164
+ }
5165
+ try {
5166
+ this.logger.info?.(
5167
+ `[Go2rtcTcpServer] API not ready (idle disconnect?), calling ensureConnected`
5168
+ );
5169
+ await this.api.ensureConnected();
5170
+ } catch (e) {
5171
+ this.logger.warn?.(
5172
+ `[Go2rtcTcpServer] ensureConnected failed, aborting stream start: ${e}`
5173
+ );
5174
+ return;
5175
+ }
5176
+ }
5023
5177
  this.nativeStreamActive = true;
5024
5178
  let dedicatedClient;
5025
5179
  if (this.deviceId) {
@@ -5038,6 +5192,7 @@ var Go2rtcTcpServer = class _Go2rtcTcpServer extends EventEmitter2 {
5038
5192
  this.logger.info?.(
5039
5193
  `[Go2rtcTcpServer] native stream starting channel=${this.channel} profile=${this.profile} dedicated=${!!dedicatedClient}`
5040
5194
  );
5195
+ let hadFrames = false;
5041
5196
  this.nativeFanout = new NativeStreamFanout({
5042
5197
  maxQueueItems: 200,
5043
5198
  createSource: () => createNativeStream(this.api, this.channel, this.profile, {
@@ -5045,19 +5200,37 @@ var Go2rtcTcpServer = class _Go2rtcTcpServer extends EventEmitter2 {
5045
5200
  ...dedicatedClient ? { client: dedicatedClient } : {}
5046
5201
  }),
5047
5202
  onFrame: (frame) => {
5203
+ hadFrames = true;
5048
5204
  this.lastFrameAt = Date.now();
5049
5205
  this.totalFramesReceived++;
5050
5206
  if (!frame.audio && (frame.videoType === "H264" || frame.videoType === "H265")) {
5051
5207
  this.detectedVideoType = frame.videoType;
5052
5208
  }
5053
- const wireData = this.convertFrame(frame);
5054
- if (!wireData || wireData.length === 0) return;
5055
- const isKeyframe = !frame.audio && this.isAnnexBKeyframe(wireData, frame.videoType);
5209
+ let prebufData;
5210
+ let isKeyframe;
5211
+ if (frame.audio) {
5212
+ if (frame.data.length === 0) return;
5213
+ if (!this.audioInfo) {
5214
+ const parsed = _Go2rtcTcpServer.parseAdtsSamplingInfo(frame.data);
5215
+ if (parsed) {
5216
+ this.audioInfo = { codec: "aac-adts", ...parsed };
5217
+ }
5218
+ }
5219
+ prebufData = frame.data;
5220
+ isKeyframe = false;
5221
+ } else {
5222
+ const annexB = this.convertVideoFrame(frame);
5223
+ if (!annexB || annexB.length === 0) return;
5224
+ prebufData = annexB;
5225
+ isKeyframe = this.isAnnexBKeyframe(annexB, frame.videoType);
5226
+ }
5227
+ const pts = frame.microseconds ?? Date.now() * 1e3;
5056
5228
  this.prebuffer.push({
5057
- data: Buffer.from(wireData),
5229
+ data: Buffer.from(prebufData),
5058
5230
  time: Date.now(),
5059
5231
  isKeyframe,
5060
- audio: frame.audio
5232
+ audio: frame.audio,
5233
+ pts
5061
5234
  });
5062
5235
  const cutoff = Date.now() - this.prebufferMaxMs;
5063
5236
  let trimIdx = 0;
@@ -5084,7 +5257,23 @@ var Go2rtcTcpServer = class _Go2rtcTcpServer extends EventEmitter2 {
5084
5257
  });
5085
5258
  this.dedicatedSessionRelease = void 0;
5086
5259
  }
5087
- if (this.active && (this.connectedClients.size > 0 || this.prestartStream)) {
5260
+ if (!this.prestartStream) {
5261
+ this.logger.info?.(
5262
+ `[Go2rtcTcpServer] battery native stream ended hadFrames=${hadFrames} channel=${this.channel} profile=${this.profile} \u2014 dropping ${this.connectedClients.size} client(s) to prevent wake loop`
5263
+ );
5264
+ for (const [, sock] of this.clientSockets) {
5265
+ sock.destroy();
5266
+ }
5267
+ } else if (this.active) {
5268
+ if (typeof this.api.isStreamProfileRejected === "function" && this.api.isStreamProfileRejected(this.channel, this.profile)) {
5269
+ this.logger.warn?.(
5270
+ `[Go2rtcTcpServer] profile rejected by device channel=${this.channel} profile=${this.profile} \u2014 not restarting`
5271
+ );
5272
+ for (const [, sock] of this.clientSockets) {
5273
+ sock.destroy();
5274
+ }
5275
+ return;
5276
+ }
5088
5277
  this.logger.info?.(
5089
5278
  `[Go2rtcTcpServer] restarting native stream (clients=${this.connectedClients.size}, prestart=${this.prestartStream})`
5090
5279
  );
@@ -7670,6 +7859,7 @@ export {
7670
7859
  BC_CMD_ID_GET_AUDIO_ALARM,
7671
7860
  BC_CMD_ID_GET_AUDIO_CFG,
7672
7861
  BC_CMD_ID_GET_AUDIO_TASK,
7862
+ BC_CMD_ID_GET_AUTO_FOCUS,
7673
7863
  BC_CMD_ID_GET_BATTERY_INFO,
7674
7864
  BC_CMD_ID_GET_BATTERY_INFO_LIST,
7675
7865
  BC_CMD_ID_GET_DAY_NIGHT_THRESHOLD,
@@ -7678,6 +7868,7 @@ export {
7678
7868
  BC_CMD_ID_GET_DING_DONG_LIST,
7679
7869
  BC_CMD_ID_GET_DING_DONG_SILENT,
7680
7870
  BC_CMD_ID_GET_EMAIL_TASK,
7871
+ BC_CMD_ID_GET_ENC,
7681
7872
  BC_CMD_ID_GET_FTP_TASK,
7682
7873
  BC_CMD_ID_GET_HDD_INFO_LIST,
7683
7874
  BC_CMD_ID_GET_KIT_AP_CFG,
@@ -7686,8 +7877,10 @@ export {
7686
7877
  BC_CMD_ID_GET_ONLINE_USER_LIST,
7687
7878
  BC_CMD_ID_GET_OSD_DATETIME,
7688
7879
  BC_CMD_ID_GET_PIR_INFO,
7880
+ BC_CMD_ID_GET_PRIVACY_MASK,
7689
7881
  BC_CMD_ID_GET_PTZ_POSITION,
7690
7882
  BC_CMD_ID_GET_PTZ_PRESET,
7883
+ BC_CMD_ID_GET_PUSH_TASK,
7691
7884
  BC_CMD_ID_GET_RECORD,
7692
7885
  BC_CMD_ID_GET_RECORD_CFG,
7693
7886
  BC_CMD_ID_GET_REC_ENC_CFG,
@@ -7716,11 +7909,23 @@ export {
7716
7909
  BC_CMD_ID_QUICK_REPLY_PLAY,
7717
7910
  BC_CMD_ID_SET_AI_ALARM,
7718
7911
  BC_CMD_ID_SET_AI_CFG,
7912
+ BC_CMD_ID_SET_AI_DENOISE,
7913
+ BC_CMD_ID_SET_AUDIO_CFG,
7719
7914
  BC_CMD_ID_SET_AUDIO_TASK,
7915
+ BC_CMD_ID_SET_AUTO_FOCUS,
7916
+ BC_CMD_ID_SET_DAY_NIGHT_THRESHOLD,
7720
7917
  BC_CMD_ID_SET_DING_DONG_CFG,
7721
7918
  BC_CMD_ID_SET_DING_DONG_SILENT,
7919
+ BC_CMD_ID_SET_EMAIL_TASK,
7920
+ BC_CMD_ID_SET_ENC,
7921
+ BC_CMD_ID_SET_LED_STATE,
7722
7922
  BC_CMD_ID_SET_MOTION_ALARM,
7723
7923
  BC_CMD_ID_SET_PIR_INFO,
7924
+ BC_CMD_ID_SET_PRIVACY_MASK,
7925
+ BC_CMD_ID_SET_PUSH_TASK,
7926
+ BC_CMD_ID_SET_RECORD,
7927
+ BC_CMD_ID_SET_RECORD_CFG,
7928
+ BC_CMD_ID_SET_VIDEO_INPUT,
7724
7929
  BC_CMD_ID_SET_WHITE_LED_STATE,
7725
7930
  BC_CMD_ID_SET_WHITE_LED_TASK,
7726
7931
  BC_CMD_ID_SET_ZOOM_FOCUS,
@@ -7759,6 +7964,7 @@ export {
7759
7964
  HlsSessionManager,
7760
7965
  Intercom,
7761
7966
  MjpegTransformer,
7967
+ MpegTsMuxer,
7762
7968
  NVR_HUB_EXACT_TYPES,
7763
7969
  NVR_HUB_MODEL_PATTERNS,
7764
7970
  ReolinkBaichuanApi,
@@ -7768,6 +7974,8 @@ export {
7768
7974
  abilitiesHasAny,
7769
7975
  aesDecrypt,
7770
7976
  aesEncrypt,
7977
+ applyStreamPatch,
7978
+ applyXmlTagPatch,
7771
7979
  asLogger,
7772
7980
  autoDetectDeviceType,
7773
7981
  bcDecrypt,
@@ -7817,6 +8025,7 @@ export {
7817
8025
  createRfc4571TcpServerForReplay,
7818
8026
  createRtspProxyServer,
7819
8027
  createTaggedLogger,
8028
+ decideSleepInferenceTransition,
7820
8029
  decideVideoclipTranscodeMode,
7821
8030
  decodeHeader,
7822
8031
  deriveAesKey,
@@ -7831,6 +8040,7 @@ export {
7831
8040
  discoverViaUdpBroadcast,
7832
8041
  discoverViaUdpDirect,
7833
8042
  encodeHeader,
8043
+ ensureXmlHeader,
7834
8044
  extractH264ParamSetsFromAccessUnit,
7835
8045
  extractH265ParamSetsFromAccessUnit,
7836
8046
  extractPpsFromAnnexB,
@@ -7859,6 +8069,8 @@ export {
7859
8069
  maskUid,
7860
8070
  md5HexUpper,
7861
8071
  md5StrModern,
8072
+ normalizeDayNightMode,
8073
+ normalizeOpenClose,
7862
8074
  normalizeUid,
7863
8075
  packetizeAacAdtsFrame,
7864
8076
  packetizeAacRawFrame,
@@ -7868,6 +8080,7 @@ export {
7868
8080
  parseBcMedia,
7869
8081
  parseRecordingFileName,
7870
8082
  parseSupportXml,
8083
+ patchNestedTag,
7871
8084
  printNvrDiagnostics,
7872
8085
  runAllDiagnosticsConsecutively,
7873
8086
  runMultifocalDiagnosticsConsecutively,