@camstack/addon-provider-reolink 1.1.16 → 1.1.18
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/addon.js +98 -47
- package/dist/addon.mjs +98 -47
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -18071,7 +18071,17 @@ var AgentAddonConfigSchema = object({
|
|
|
18071
18071
|
});
|
|
18072
18072
|
var AgentPipelineSettingsSchema = object({
|
|
18073
18073
|
addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
|
|
18074
|
-
maxCameras: number().int().nonnegative().nullable().default(null)
|
|
18074
|
+
maxCameras: number().int().nonnegative().nullable().default(null),
|
|
18075
|
+
/** Per-node detection weight (relative share for the quota balancer). */
|
|
18076
|
+
detectWeight: number().positive().optional(),
|
|
18077
|
+
/** Node is eligible to run the detection pipeline (decode + inference). */
|
|
18078
|
+
detect: boolean().optional(),
|
|
18079
|
+
/** Node is eligible to host decoder sessions. */
|
|
18080
|
+
decode: boolean().optional(),
|
|
18081
|
+
/** Node is eligible to run audio-analyzer sessions. */
|
|
18082
|
+
audio: boolean().optional(),
|
|
18083
|
+
/** Node is eligible to be the ingest / source-owner (serve the restream). */
|
|
18084
|
+
ingest: boolean().optional()
|
|
18075
18085
|
});
|
|
18076
18086
|
var CameraPipelineForAgentSchema = object({
|
|
18077
18087
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -18146,7 +18156,10 @@ var AgentLoadSummarySchema = object({
|
|
|
18146
18156
|
online: boolean(),
|
|
18147
18157
|
load: RunnerLocalLoadSchema,
|
|
18148
18158
|
/** Computed score used by the L2 capacity balancer (lower = less loaded). */
|
|
18149
|
-
score: number()
|
|
18159
|
+
score: number(),
|
|
18160
|
+
/** This node's decode hwaccel backend (per-node `probedBestHwaccel`), or null
|
|
18161
|
+
* when not yet probed — for the cluster Pipeline table UI (P0.2). */
|
|
18162
|
+
decodeHwaccel: string().nullable()
|
|
18150
18163
|
});
|
|
18151
18164
|
/**
|
|
18152
18165
|
* Aggregate metrics across the whole detection cluster. Replaces the legacy
|
|
@@ -18374,6 +18387,21 @@ method(object({
|
|
|
18374
18387
|
}), object({ success: literal(true) }), {
|
|
18375
18388
|
kind: "mutation",
|
|
18376
18389
|
auth: "admin"
|
|
18390
|
+
}), method(object({
|
|
18391
|
+
agentNodeId: string(),
|
|
18392
|
+
detectWeight: number().positive().nullable()
|
|
18393
|
+
}), object({ success: literal(true) }), {
|
|
18394
|
+
kind: "mutation",
|
|
18395
|
+
auth: "admin"
|
|
18396
|
+
}), method(object({
|
|
18397
|
+
agentNodeId: string(),
|
|
18398
|
+
detect: boolean().nullable().optional(),
|
|
18399
|
+
decode: boolean().nullable().optional(),
|
|
18400
|
+
audio: boolean().nullable().optional(),
|
|
18401
|
+
ingest: boolean().nullable().optional()
|
|
18402
|
+
}), object({ success: literal(true) }), {
|
|
18403
|
+
kind: "mutation",
|
|
18404
|
+
auth: "admin"
|
|
18377
18405
|
}), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
|
|
18378
18406
|
deviceId: number(),
|
|
18379
18407
|
addonId: string(),
|
|
@@ -20776,7 +20804,7 @@ var HardwareEncoderIdSchema = _enum([
|
|
|
20776
20804
|
"libx264",
|
|
20777
20805
|
"libx265"
|
|
20778
20806
|
]);
|
|
20779
|
-
|
|
20807
|
+
object({
|
|
20780
20808
|
encoders: array(object({
|
|
20781
20809
|
encoder: HardwareEncoderIdSchema,
|
|
20782
20810
|
codec: _enum(["H264", "H265"]),
|
|
@@ -20795,15 +20823,7 @@ var HardwareEncodersSchema = object({
|
|
|
20795
20823
|
defaultH265: HardwareEncoderIdSchema,
|
|
20796
20824
|
probedAt: number()
|
|
20797
20825
|
});
|
|
20798
|
-
|
|
20799
|
-
* Decode-side companion to {@link HardwareEncodersSchema}: the `-hwaccel`
|
|
20800
|
-
* methods the configured ffmpeg binary actually supports (parsed from
|
|
20801
|
-
* `ffmpeg -hwaccels`). Used to gate decode-hwaccel attempts so the transcode
|
|
20802
|
-
* egress never spends a spawn on a backend this build cannot offer. Per-stream
|
|
20803
|
-
* decode fragility (e.g. VideoToolbox HEVC) is still handled by the egress's
|
|
20804
|
-
* software fallback — this only filters out wholly-unsupported backends.
|
|
20805
|
-
*/
|
|
20806
|
-
var HardwareDecodeAccelsSchema = object({
|
|
20826
|
+
object({
|
|
20807
20827
|
methods: array(string()).readonly(),
|
|
20808
20828
|
probedAt: number()
|
|
20809
20829
|
});
|
|
@@ -20866,13 +20886,7 @@ var ResolvedInferenceConfigSchema = object({
|
|
|
20866
20886
|
format: ModelFormatSchema,
|
|
20867
20887
|
reason: string()
|
|
20868
20888
|
});
|
|
20869
|
-
method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema), method(object({ requirements: array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema), method(object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema)
|
|
20870
|
-
kind: "mutation",
|
|
20871
|
-
auth: "admin"
|
|
20872
|
-
}), method(_void(), HardwareDecodeAccelsSchema), method(_void(), HardwareDecodeAccelsSchema, {
|
|
20873
|
-
kind: "mutation",
|
|
20874
|
-
auth: "admin"
|
|
20875
|
-
});
|
|
20889
|
+
method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema), method(object({ requirements: array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema), method(object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema);
|
|
20876
20890
|
var PtzPresetSchema = object({
|
|
20877
20891
|
id: string(),
|
|
20878
20892
|
name: string()
|
|
@@ -24619,6 +24633,18 @@ Object.freeze({
|
|
|
24619
24633
|
addonId: null,
|
|
24620
24634
|
access: "create"
|
|
24621
24635
|
},
|
|
24636
|
+
"pipelineOrchestrator.setAgentCapabilities": {
|
|
24637
|
+
capName: "pipeline-orchestrator",
|
|
24638
|
+
capScope: "system",
|
|
24639
|
+
addonId: null,
|
|
24640
|
+
access: "create"
|
|
24641
|
+
},
|
|
24642
|
+
"pipelineOrchestrator.setAgentDetectWeight": {
|
|
24643
|
+
capName: "pipeline-orchestrator",
|
|
24644
|
+
capScope: "system",
|
|
24645
|
+
addonId: null,
|
|
24646
|
+
access: "create"
|
|
24647
|
+
},
|
|
24622
24648
|
"pipelineOrchestrator.setAgentMaxCameras": {
|
|
24623
24649
|
capName: "pipeline-orchestrator",
|
|
24624
24650
|
capScope: "system",
|
|
@@ -24775,30 +24801,6 @@ Object.freeze({
|
|
|
24775
24801
|
addonId: null,
|
|
24776
24802
|
access: "view"
|
|
24777
24803
|
},
|
|
24778
|
-
"platformProbe.getHardwareDecodeAccels": {
|
|
24779
|
-
capName: "platform-probe",
|
|
24780
|
-
capScope: "system",
|
|
24781
|
-
addonId: null,
|
|
24782
|
-
access: "view"
|
|
24783
|
-
},
|
|
24784
|
-
"platformProbe.getHardwareEncoders": {
|
|
24785
|
-
capName: "platform-probe",
|
|
24786
|
-
capScope: "system",
|
|
24787
|
-
addonId: null,
|
|
24788
|
-
access: "view"
|
|
24789
|
-
},
|
|
24790
|
-
"platformProbe.refreshHardwareDecodeAccels": {
|
|
24791
|
-
capName: "platform-probe",
|
|
24792
|
-
capScope: "system",
|
|
24793
|
-
addonId: null,
|
|
24794
|
-
access: "create"
|
|
24795
|
-
},
|
|
24796
|
-
"platformProbe.refreshHardwareEncoders": {
|
|
24797
|
-
capName: "platform-probe",
|
|
24798
|
-
capScope: "system",
|
|
24799
|
-
addonId: null,
|
|
24800
|
-
access: "create"
|
|
24801
|
-
},
|
|
24802
24804
|
"platformProbe.resolveHwAccel": {
|
|
24803
24805
|
capName: "platform-probe",
|
|
24804
24806
|
capScope: "system",
|
|
@@ -214554,6 +214556,30 @@ function buildRawState(reader) {
|
|
|
214554
214556
|
};
|
|
214555
214557
|
}
|
|
214556
214558
|
//#endregion
|
|
214559
|
+
//#region src/native-sdp-overlay.ts
|
|
214560
|
+
/**
|
|
214561
|
+
* Return a new descriptor list in which every native `pull-rfc4571` entry with
|
|
214562
|
+
* a live upstream server carries that server's real `tcp://` URL + real SDP.
|
|
214563
|
+
* Pure + immutable: non-native or cold entries pass through unchanged;
|
|
214564
|
+
* upgraded entries are fresh objects and sibling metadata keys are preserved.
|
|
214565
|
+
*/
|
|
214566
|
+
function overlayLiveNativeRfc4571Sdp(descriptors, liveServerFor) {
|
|
214567
|
+
return descriptors.map((descriptor) => {
|
|
214568
|
+
if (descriptor.kind !== "pull-rfc4571") return descriptor;
|
|
214569
|
+
const live = liveServerFor(descriptor.camStreamId);
|
|
214570
|
+
if (!live) return descriptor;
|
|
214571
|
+
const auth = `${encodeURIComponent(live.username)}:${encodeURIComponent(live.password)}`;
|
|
214572
|
+
return {
|
|
214573
|
+
...descriptor,
|
|
214574
|
+
url: `tcp://${auth}@${live.host}:${live.port}`,
|
|
214575
|
+
metadata: {
|
|
214576
|
+
...descriptor.metadata,
|
|
214577
|
+
sdp: live.sdp
|
|
214578
|
+
}
|
|
214579
|
+
};
|
|
214580
|
+
});
|
|
214581
|
+
}
|
|
214582
|
+
//#endregion
|
|
214557
214583
|
//#region src/accessory-probe-flags.ts
|
|
214558
214584
|
var FLAG_KEYS = [
|
|
214559
214585
|
"hasBattery",
|
|
@@ -220564,17 +220590,39 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
220564
220590
|
* session or touches the broker.
|
|
220565
220591
|
*/
|
|
220566
220592
|
async buildStreamCatalog() {
|
|
220567
|
-
if (this.cachedStreamDescriptors?.length) return this.cachedStreamDescriptors;
|
|
220568
|
-
if (this.buildStreamCatalogInFlight) return this.buildStreamCatalogInFlight;
|
|
220593
|
+
if (this.cachedStreamDescriptors?.length) return this.withLiveNativeSdp(this.cachedStreamDescriptors);
|
|
220594
|
+
if (this.buildStreamCatalogInFlight) return this.withLiveNativeSdp(await this.buildStreamCatalogInFlight);
|
|
220569
220595
|
const build = this.buildStreamCatalogUncached();
|
|
220570
220596
|
this.buildStreamCatalogInFlight = build;
|
|
220571
220597
|
try {
|
|
220572
|
-
return await build;
|
|
220598
|
+
return this.withLiveNativeSdp(await build);
|
|
220573
220599
|
} finally {
|
|
220574
220600
|
this.buildStreamCatalogInFlight = null;
|
|
220575
220601
|
}
|
|
220576
220602
|
}
|
|
220577
220603
|
/**
|
|
220604
|
+
* Upgrade native `pull-rfc4571` descriptors to the live upstream server's
|
|
220605
|
+
* real `tcp://` URL + real (sprop-bearing) SDP whenever a server is
|
|
220606
|
+
* currently listening in `this.active`. The synthetic catalog SDP omits
|
|
220607
|
+
* `sprop-parameter-sets`, which the raw ffmpeg decode reader cannot recover
|
|
220608
|
+
* (it has no in-band SPS/PPS merge) — so a decode-path consumer that pulls
|
|
220609
|
+
* the catalog after `materializeStreamSocket` must still see the real SDP.
|
|
220610
|
+
* See `native-sdp-overlay.ts`.
|
|
220611
|
+
*/
|
|
220612
|
+
withLiveNativeSdp(descriptors) {
|
|
220613
|
+
return overlayLiveNativeRfc4571Sdp(descriptors, (camStreamId) => {
|
|
220614
|
+
const server = this.active.get(camStreamId)?.server;
|
|
220615
|
+
if (!server?.server?.listening) return null;
|
|
220616
|
+
return {
|
|
220617
|
+
host: server.host,
|
|
220618
|
+
port: server.port,
|
|
220619
|
+
username: server.username,
|
|
220620
|
+
password: server.password,
|
|
220621
|
+
sdp: server.sdp
|
|
220622
|
+
};
|
|
220623
|
+
});
|
|
220624
|
+
}
|
|
220625
|
+
/**
|
|
220578
220626
|
* Synthesize the HTTP-FLV pull URL for a (channel, profile) pair. FLV is
|
|
220579
220627
|
* served off the Reolink Baichuan media port (default 1935, app `bcs`) as
|
|
220580
220628
|
* `channel<channel>_<profile>.bcs` — the same shape Frigate/go2rtc use. The
|
|
@@ -220798,13 +220846,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
220798
220846
|
}
|
|
220799
220847
|
const url = `tcp://${`${encodeURIComponent(server.username)}:${encodeURIComponent(server.password)}`}@${server.host}:${server.port}`;
|
|
220800
220848
|
const codec = server.videoType === "H265" ? "h265" : "h264";
|
|
220849
|
+
const descriptor = this.cachedStreamDescriptors?.find((d) => d.camStreamId === camStreamId);
|
|
220801
220850
|
await this.publishOne({
|
|
220802
220851
|
camStreamId,
|
|
220803
220852
|
kind: "pull-rfc4571",
|
|
220804
|
-
label: camStreamId,
|
|
220853
|
+
label: descriptor?.label ?? camStreamId,
|
|
220805
220854
|
url,
|
|
220806
220855
|
codec,
|
|
220807
220856
|
autoEligible: true,
|
|
220857
|
+
...descriptor?.resolution ? { resolution: descriptor.resolution } : {},
|
|
220858
|
+
...descriptor?.fps !== void 0 ? { fps: descriptor.fps } : {},
|
|
220808
220859
|
metadata: { sdp: server.sdp }
|
|
220809
220860
|
});
|
|
220810
220861
|
this.ctx.logger.info("materialized rfc4571 stream socket on broker demand", {
|
package/dist/addon.mjs
CHANGED
|
@@ -18066,7 +18066,17 @@ var AgentAddonConfigSchema = object({
|
|
|
18066
18066
|
});
|
|
18067
18067
|
var AgentPipelineSettingsSchema = object({
|
|
18068
18068
|
addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
|
|
18069
|
-
maxCameras: number().int().nonnegative().nullable().default(null)
|
|
18069
|
+
maxCameras: number().int().nonnegative().nullable().default(null),
|
|
18070
|
+
/** Per-node detection weight (relative share for the quota balancer). */
|
|
18071
|
+
detectWeight: number().positive().optional(),
|
|
18072
|
+
/** Node is eligible to run the detection pipeline (decode + inference). */
|
|
18073
|
+
detect: boolean().optional(),
|
|
18074
|
+
/** Node is eligible to host decoder sessions. */
|
|
18075
|
+
decode: boolean().optional(),
|
|
18076
|
+
/** Node is eligible to run audio-analyzer sessions. */
|
|
18077
|
+
audio: boolean().optional(),
|
|
18078
|
+
/** Node is eligible to be the ingest / source-owner (serve the restream). */
|
|
18079
|
+
ingest: boolean().optional()
|
|
18070
18080
|
});
|
|
18071
18081
|
var CameraPipelineForAgentSchema = object({
|
|
18072
18082
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -18141,7 +18151,10 @@ var AgentLoadSummarySchema = object({
|
|
|
18141
18151
|
online: boolean(),
|
|
18142
18152
|
load: RunnerLocalLoadSchema,
|
|
18143
18153
|
/** Computed score used by the L2 capacity balancer (lower = less loaded). */
|
|
18144
|
-
score: number()
|
|
18154
|
+
score: number(),
|
|
18155
|
+
/** This node's decode hwaccel backend (per-node `probedBestHwaccel`), or null
|
|
18156
|
+
* when not yet probed — for the cluster Pipeline table UI (P0.2). */
|
|
18157
|
+
decodeHwaccel: string().nullable()
|
|
18145
18158
|
});
|
|
18146
18159
|
/**
|
|
18147
18160
|
* Aggregate metrics across the whole detection cluster. Replaces the legacy
|
|
@@ -18369,6 +18382,21 @@ method(object({
|
|
|
18369
18382
|
}), object({ success: literal(true) }), {
|
|
18370
18383
|
kind: "mutation",
|
|
18371
18384
|
auth: "admin"
|
|
18385
|
+
}), method(object({
|
|
18386
|
+
agentNodeId: string(),
|
|
18387
|
+
detectWeight: number().positive().nullable()
|
|
18388
|
+
}), object({ success: literal(true) }), {
|
|
18389
|
+
kind: "mutation",
|
|
18390
|
+
auth: "admin"
|
|
18391
|
+
}), method(object({
|
|
18392
|
+
agentNodeId: string(),
|
|
18393
|
+
detect: boolean().nullable().optional(),
|
|
18394
|
+
decode: boolean().nullable().optional(),
|
|
18395
|
+
audio: boolean().nullable().optional(),
|
|
18396
|
+
ingest: boolean().nullable().optional()
|
|
18397
|
+
}), object({ success: literal(true) }), {
|
|
18398
|
+
kind: "mutation",
|
|
18399
|
+
auth: "admin"
|
|
18372
18400
|
}), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
|
|
18373
18401
|
deviceId: number(),
|
|
18374
18402
|
addonId: string(),
|
|
@@ -20771,7 +20799,7 @@ var HardwareEncoderIdSchema = _enum([
|
|
|
20771
20799
|
"libx264",
|
|
20772
20800
|
"libx265"
|
|
20773
20801
|
]);
|
|
20774
|
-
|
|
20802
|
+
object({
|
|
20775
20803
|
encoders: array(object({
|
|
20776
20804
|
encoder: HardwareEncoderIdSchema,
|
|
20777
20805
|
codec: _enum(["H264", "H265"]),
|
|
@@ -20790,15 +20818,7 @@ var HardwareEncodersSchema = object({
|
|
|
20790
20818
|
defaultH265: HardwareEncoderIdSchema,
|
|
20791
20819
|
probedAt: number()
|
|
20792
20820
|
});
|
|
20793
|
-
|
|
20794
|
-
* Decode-side companion to {@link HardwareEncodersSchema}: the `-hwaccel`
|
|
20795
|
-
* methods the configured ffmpeg binary actually supports (parsed from
|
|
20796
|
-
* `ffmpeg -hwaccels`). Used to gate decode-hwaccel attempts so the transcode
|
|
20797
|
-
* egress never spends a spawn on a backend this build cannot offer. Per-stream
|
|
20798
|
-
* decode fragility (e.g. VideoToolbox HEVC) is still handled by the egress's
|
|
20799
|
-
* software fallback — this only filters out wholly-unsupported backends.
|
|
20800
|
-
*/
|
|
20801
|
-
var HardwareDecodeAccelsSchema = object({
|
|
20821
|
+
object({
|
|
20802
20822
|
methods: array(string()).readonly(),
|
|
20803
20823
|
probedAt: number()
|
|
20804
20824
|
});
|
|
@@ -20861,13 +20881,7 @@ var ResolvedInferenceConfigSchema = object({
|
|
|
20861
20881
|
format: ModelFormatSchema,
|
|
20862
20882
|
reason: string()
|
|
20863
20883
|
});
|
|
20864
|
-
method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema), method(object({ requirements: array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema), method(object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema)
|
|
20865
|
-
kind: "mutation",
|
|
20866
|
-
auth: "admin"
|
|
20867
|
-
}), method(_void(), HardwareDecodeAccelsSchema), method(_void(), HardwareDecodeAccelsSchema, {
|
|
20868
|
-
kind: "mutation",
|
|
20869
|
-
auth: "admin"
|
|
20870
|
-
});
|
|
20884
|
+
method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema), method(object({ requirements: array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema), method(object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema);
|
|
20871
20885
|
var PtzPresetSchema = object({
|
|
20872
20886
|
id: string(),
|
|
20873
20887
|
name: string()
|
|
@@ -24614,6 +24628,18 @@ Object.freeze({
|
|
|
24614
24628
|
addonId: null,
|
|
24615
24629
|
access: "create"
|
|
24616
24630
|
},
|
|
24631
|
+
"pipelineOrchestrator.setAgentCapabilities": {
|
|
24632
|
+
capName: "pipeline-orchestrator",
|
|
24633
|
+
capScope: "system",
|
|
24634
|
+
addonId: null,
|
|
24635
|
+
access: "create"
|
|
24636
|
+
},
|
|
24637
|
+
"pipelineOrchestrator.setAgentDetectWeight": {
|
|
24638
|
+
capName: "pipeline-orchestrator",
|
|
24639
|
+
capScope: "system",
|
|
24640
|
+
addonId: null,
|
|
24641
|
+
access: "create"
|
|
24642
|
+
},
|
|
24617
24643
|
"pipelineOrchestrator.setAgentMaxCameras": {
|
|
24618
24644
|
capName: "pipeline-orchestrator",
|
|
24619
24645
|
capScope: "system",
|
|
@@ -24770,30 +24796,6 @@ Object.freeze({
|
|
|
24770
24796
|
addonId: null,
|
|
24771
24797
|
access: "view"
|
|
24772
24798
|
},
|
|
24773
|
-
"platformProbe.getHardwareDecodeAccels": {
|
|
24774
|
-
capName: "platform-probe",
|
|
24775
|
-
capScope: "system",
|
|
24776
|
-
addonId: null,
|
|
24777
|
-
access: "view"
|
|
24778
|
-
},
|
|
24779
|
-
"platformProbe.getHardwareEncoders": {
|
|
24780
|
-
capName: "platform-probe",
|
|
24781
|
-
capScope: "system",
|
|
24782
|
-
addonId: null,
|
|
24783
|
-
access: "view"
|
|
24784
|
-
},
|
|
24785
|
-
"platformProbe.refreshHardwareDecodeAccels": {
|
|
24786
|
-
capName: "platform-probe",
|
|
24787
|
-
capScope: "system",
|
|
24788
|
-
addonId: null,
|
|
24789
|
-
access: "create"
|
|
24790
|
-
},
|
|
24791
|
-
"platformProbe.refreshHardwareEncoders": {
|
|
24792
|
-
capName: "platform-probe",
|
|
24793
|
-
capScope: "system",
|
|
24794
|
-
addonId: null,
|
|
24795
|
-
access: "create"
|
|
24796
|
-
},
|
|
24797
24799
|
"platformProbe.resolveHwAccel": {
|
|
24798
24800
|
capName: "platform-probe",
|
|
24799
24801
|
capScope: "system",
|
|
@@ -214534,6 +214536,30 @@ function buildRawState(reader) {
|
|
|
214534
214536
|
};
|
|
214535
214537
|
}
|
|
214536
214538
|
//#endregion
|
|
214539
|
+
//#region src/native-sdp-overlay.ts
|
|
214540
|
+
/**
|
|
214541
|
+
* Return a new descriptor list in which every native `pull-rfc4571` entry with
|
|
214542
|
+
* a live upstream server carries that server's real `tcp://` URL + real SDP.
|
|
214543
|
+
* Pure + immutable: non-native or cold entries pass through unchanged;
|
|
214544
|
+
* upgraded entries are fresh objects and sibling metadata keys are preserved.
|
|
214545
|
+
*/
|
|
214546
|
+
function overlayLiveNativeRfc4571Sdp(descriptors, liveServerFor) {
|
|
214547
|
+
return descriptors.map((descriptor) => {
|
|
214548
|
+
if (descriptor.kind !== "pull-rfc4571") return descriptor;
|
|
214549
|
+
const live = liveServerFor(descriptor.camStreamId);
|
|
214550
|
+
if (!live) return descriptor;
|
|
214551
|
+
const auth = `${encodeURIComponent(live.username)}:${encodeURIComponent(live.password)}`;
|
|
214552
|
+
return {
|
|
214553
|
+
...descriptor,
|
|
214554
|
+
url: `tcp://${auth}@${live.host}:${live.port}`,
|
|
214555
|
+
metadata: {
|
|
214556
|
+
...descriptor.metadata,
|
|
214557
|
+
sdp: live.sdp
|
|
214558
|
+
}
|
|
214559
|
+
};
|
|
214560
|
+
});
|
|
214561
|
+
}
|
|
214562
|
+
//#endregion
|
|
214537
214563
|
//#region src/accessory-probe-flags.ts
|
|
214538
214564
|
var FLAG_KEYS = [
|
|
214539
214565
|
"hasBattery",
|
|
@@ -220544,17 +220570,39 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
220544
220570
|
* session or touches the broker.
|
|
220545
220571
|
*/
|
|
220546
220572
|
async buildStreamCatalog() {
|
|
220547
|
-
if (this.cachedStreamDescriptors?.length) return this.cachedStreamDescriptors;
|
|
220548
|
-
if (this.buildStreamCatalogInFlight) return this.buildStreamCatalogInFlight;
|
|
220573
|
+
if (this.cachedStreamDescriptors?.length) return this.withLiveNativeSdp(this.cachedStreamDescriptors);
|
|
220574
|
+
if (this.buildStreamCatalogInFlight) return this.withLiveNativeSdp(await this.buildStreamCatalogInFlight);
|
|
220549
220575
|
const build = this.buildStreamCatalogUncached();
|
|
220550
220576
|
this.buildStreamCatalogInFlight = build;
|
|
220551
220577
|
try {
|
|
220552
|
-
return await build;
|
|
220578
|
+
return this.withLiveNativeSdp(await build);
|
|
220553
220579
|
} finally {
|
|
220554
220580
|
this.buildStreamCatalogInFlight = null;
|
|
220555
220581
|
}
|
|
220556
220582
|
}
|
|
220557
220583
|
/**
|
|
220584
|
+
* Upgrade native `pull-rfc4571` descriptors to the live upstream server's
|
|
220585
|
+
* real `tcp://` URL + real (sprop-bearing) SDP whenever a server is
|
|
220586
|
+
* currently listening in `this.active`. The synthetic catalog SDP omits
|
|
220587
|
+
* `sprop-parameter-sets`, which the raw ffmpeg decode reader cannot recover
|
|
220588
|
+
* (it has no in-band SPS/PPS merge) — so a decode-path consumer that pulls
|
|
220589
|
+
* the catalog after `materializeStreamSocket` must still see the real SDP.
|
|
220590
|
+
* See `native-sdp-overlay.ts`.
|
|
220591
|
+
*/
|
|
220592
|
+
withLiveNativeSdp(descriptors) {
|
|
220593
|
+
return overlayLiveNativeRfc4571Sdp(descriptors, (camStreamId) => {
|
|
220594
|
+
const server = this.active.get(camStreamId)?.server;
|
|
220595
|
+
if (!server?.server?.listening) return null;
|
|
220596
|
+
return {
|
|
220597
|
+
host: server.host,
|
|
220598
|
+
port: server.port,
|
|
220599
|
+
username: server.username,
|
|
220600
|
+
password: server.password,
|
|
220601
|
+
sdp: server.sdp
|
|
220602
|
+
};
|
|
220603
|
+
});
|
|
220604
|
+
}
|
|
220605
|
+
/**
|
|
220558
220606
|
* Synthesize the HTTP-FLV pull URL for a (channel, profile) pair. FLV is
|
|
220559
220607
|
* served off the Reolink Baichuan media port (default 1935, app `bcs`) as
|
|
220560
220608
|
* `channel<channel>_<profile>.bcs` — the same shape Frigate/go2rtc use. The
|
|
@@ -220778,13 +220826,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
220778
220826
|
}
|
|
220779
220827
|
const url = `tcp://${`${encodeURIComponent(server.username)}:${encodeURIComponent(server.password)}`}@${server.host}:${server.port}`;
|
|
220780
220828
|
const codec = server.videoType === "H265" ? "h265" : "h264";
|
|
220829
|
+
const descriptor = this.cachedStreamDescriptors?.find((d) => d.camStreamId === camStreamId);
|
|
220781
220830
|
await this.publishOne({
|
|
220782
220831
|
camStreamId,
|
|
220783
220832
|
kind: "pull-rfc4571",
|
|
220784
|
-
label: camStreamId,
|
|
220833
|
+
label: descriptor?.label ?? camStreamId,
|
|
220785
220834
|
url,
|
|
220786
220835
|
codec,
|
|
220787
220836
|
autoEligible: true,
|
|
220837
|
+
...descriptor?.resolution ? { resolution: descriptor.resolution } : {},
|
|
220838
|
+
...descriptor?.fps !== void 0 ? { fps: descriptor.fps } : {},
|
|
220788
220839
|
metadata: { sdp: server.sdp }
|
|
220789
220840
|
});
|
|
220790
220841
|
this.ctx.logger.info("materialized rfc4571 stream socket on broker demand", {
|