mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-12 17:52:48 +03:00
Add sub stream recording with adaptive quality playback (#24009)
* add sub stream recording with adaptive quality playback Optionally record a second, lower bitrate stream alongside the main recording stream via a `record_sub` input role and `record.sub` config block, with its own retention windows. Recordings rows now carry the stream type plus the media details needed to serve both streams from one manifest: video codec, audio presence, audio codec and rate, and a record-time keyframe index. Playback resolves coverage across both streams and merges them into a single VOD sequence, falling back to a discontinuity manifest with per-clip init segments when the media signatures differ. The player exposes a quality selector, and an auto governor picks the stream from stall time, bandwidth, codec support, and the save-data hint. * fix tests and i18n
This commit is contained in:
committed by
Nicolas Mowen
parent
f7c5500ea8
commit
1498231eb9
@@ -20,6 +20,13 @@ const ffmpegArgsWidget = (
|
||||
},
|
||||
});
|
||||
|
||||
const recordSubArgsWidget = () =>
|
||||
ffmpegArgsWidget("output_args.record_sub", {
|
||||
allowInherit: true,
|
||||
forceSplitLayout: true,
|
||||
unsetLabelKey: "configForm.ffmpegArgs.sameAsRecord",
|
||||
});
|
||||
|
||||
const ffmpeg: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/ffmpeg_presets",
|
||||
@@ -75,6 +82,8 @@ const ffmpeg: SectionConfigOverrides = {
|
||||
output_args: "/configuration/ffmpeg_presets#output-args-presets",
|
||||
"inputs.output_args": "/configuration/ffmpeg_presets#output-args-presets",
|
||||
"output_args.record": "/configuration/ffmpeg_presets#output-args-presets",
|
||||
"output_args.record_sub":
|
||||
"/configuration/ffmpeg_presets#output-args-presets",
|
||||
"inputs.roles": "/configuration/cameras/#setting-up-camera-inputs",
|
||||
apple_compatibility:
|
||||
"/configuration/camera_specific#h265-cameras-via-safari",
|
||||
@@ -112,9 +121,11 @@ const ffmpeg: SectionConfigOverrides = {
|
||||
output_args: {
|
||||
detect: arrayAsTextWidget,
|
||||
record: ffmpegArgsWidget("output_args.record"),
|
||||
record_sub: recordSubArgsWidget(),
|
||||
items: {
|
||||
detect: arrayAsTextWidget,
|
||||
record: ffmpegArgsWidget("output_args.record"),
|
||||
record_sub: recordSubArgsWidget(),
|
||||
},
|
||||
},
|
||||
inputs: {
|
||||
@@ -148,6 +159,7 @@ const ffmpeg: SectionConfigOverrides = {
|
||||
items: {
|
||||
detect: arrayAsTextWidget,
|
||||
record: ffmpegArgsWidget("output_args.record"),
|
||||
record_sub: recordSubArgsWidget(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -176,6 +188,7 @@ const ffmpeg: SectionConfigOverrides = {
|
||||
output_args: {
|
||||
detect: arrayAsTextWidget,
|
||||
record: ffmpegArgsWidget("output_args.record"),
|
||||
record_sub: recordSubArgsWidget(),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -15,6 +15,19 @@ const record: SectionConfigOverrides = {
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "no-record-sub-role",
|
||||
messageKey: "configMessages.record.noRecordSubRole",
|
||||
severity: "warning",
|
||||
condition: (ctx) => {
|
||||
if (ctx.level !== "camera" || !ctx.fullCameraConfig) return false;
|
||||
const sub = ctx.formData?.sub as Record<string, unknown> | undefined;
|
||||
if (!sub?.enabled) return false;
|
||||
return !ctx.fullCameraConfig.ffmpeg?.inputs?.some((i) =>
|
||||
i.roles?.includes("record_sub"),
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
fieldDocs: {
|
||||
"alerts.pre_capture":
|
||||
@@ -34,6 +47,7 @@ const record: SectionConfigOverrides = {
|
||||
"motion",
|
||||
"alerts",
|
||||
"detections",
|
||||
"sub",
|
||||
"preview",
|
||||
"export",
|
||||
],
|
||||
@@ -67,6 +81,12 @@ const record: SectionConfigOverrides = {
|
||||
"detections.retain.mode": {
|
||||
"ui:options": { enumI18nPrefix: "retainMode" },
|
||||
},
|
||||
"sub.alerts.mode": {
|
||||
"ui:options": { enumI18nPrefix: "retainMode" },
|
||||
},
|
||||
"sub.detections.mode": {
|
||||
"ui:options": { enumI18nPrefix: "retainMode" },
|
||||
},
|
||||
preview: {
|
||||
"ui:options": { defaultOpen: true, disableCollapsible: true },
|
||||
quality: {
|
||||
|
||||
Reference in New Issue
Block a user