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:
Josh Hawkins
2026-08-27 20:30:35 -05:00
parent 31bbf910c7
commit 5d807587ab
68 changed files with 6813 additions and 602 deletions
+7 -1
View File
@@ -398,6 +398,7 @@
"title": "Stream Roles",
"detect": "Main feed for object detection.",
"record": "Saves segments of the video feed based on configuration settings.",
"record_sub": "Lower quality recordings for adaptive playback and extended retention (typically the camera sub stream).",
"audio": "Feed for audio based detection."
},
"featuresPopover": {
@@ -1528,6 +1529,7 @@
"manual": "Manual arguments",
"inherit": "Inherit from camera setting",
"none": "None",
"sameAsRecord": "Same as record output arguments",
"useGlobalSetting": "Inherit from global setting",
"selectPreset": "Select preset",
"manualPlaceholder": "Enter FFmpeg arguments",
@@ -1648,9 +1650,12 @@
"inputRoles": {
"summary": "{{count}} roles selected",
"empty": "No roles available",
"roleInUse": "Already assigned to another stream",
"recordSubConflict": "A stream cannot have both record and record_sub roles",
"options": {
"detect": "Detect",
"record": "Record",
"record_sub": "Record (Sub Stream)",
"audio": "Audio"
}
},
@@ -1952,7 +1957,8 @@
"modelSizeLarge": "The 'large' model is optimized for multi-line license plates. The 'small' model provides better performance over 'large' and should be used unless your region uses multi-line plate formats."
},
"record": {
"noRecordRole": "No streams have the record role defined. Recording will not function."
"noRecordRole": "No streams have the record role defined. Recording will not function.",
"noRecordSubRole": "No streams have the record_sub role defined. Sub stream recording will not function."
},
"birdseye": {
"objectTrackingDetectDisabled": "Birdseye includes tracked objects, but object detection is disabled for this camera. The camera will not appear in Birdseye."