mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-10 16:52:47 +03:00
don't treat unknown audio as an audio-bearing stream
A recording row with NULL has_audio (ffprobe failed and the cv2 fallback can't report audio) marked the whole stream as audio-bearing, so every confirmed video-only row on it was dropped as a glitch. A stream now counts as audio-bearing only when a row is known to carry audio.
This commit is contained in:
@@ -13,6 +13,7 @@ from frigate.models import Recordings
|
|||||||
from frigate.util.recording_coverage import (
|
from frigate.util.recording_coverage import (
|
||||||
_rows_query,
|
_rows_query,
|
||||||
coverage_spans,
|
coverage_spans,
|
||||||
|
null_audio_glitches,
|
||||||
plan_clip,
|
plan_clip,
|
||||||
realized_timeline,
|
realized_timeline,
|
||||||
resolve_coverage,
|
resolve_coverage,
|
||||||
@@ -166,6 +167,22 @@ class TestRecordingCoverage(CoverageDbTestCase):
|
|||||||
expected = int(5 * 1024 * 1024 * 8 / 10)
|
expected = int(5 * 1024 * 1024 * 8 / 10)
|
||||||
assert summary["main"]["bitrate"] == expected
|
assert summary["main"]["bitrate"] == expected
|
||||||
|
|
||||||
|
def test_unknown_audio_row_keeps_video_only_stream(self):
|
||||||
|
self._insert("s1", 1000.0, 1010.0, "sub", has_audio=False)
|
||||||
|
self._insert("s2", 1010.0, 1020.0, "sub", has_audio=None)
|
||||||
|
self._insert("s3", 1020.0, 1030.0, "sub", has_audio=False)
|
||||||
|
kept = null_audio_glitches(resolve_coverage("front_door", 1000.0, 1030.0))
|
||||||
|
self.assertEqual(
|
||||||
|
[i.sub.path for i in kept], [f"/tmp/s{n}.mp4" for n in (1, 2, 3)]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_video_only_glitch_dropped_on_audio_stream(self):
|
||||||
|
self._insert("s1", 1000.0, 1010.0, "sub", has_audio=True)
|
||||||
|
self._insert("s2", 1010.0, 1020.0, "sub", has_audio=False)
|
||||||
|
self._insert("s3", 1020.0, 1030.0, "sub", has_audio=None)
|
||||||
|
kept = null_audio_glitches(resolve_coverage("front_door", 1000.0, 1030.0))
|
||||||
|
self.assertEqual([i.sub.path for i in kept], ["/tmp/s1.mp4", "/tmp/s3.mp4"])
|
||||||
|
|
||||||
def test_other_camera_rows_excluded(self):
|
def test_other_camera_rows_excluded(self):
|
||||||
self._insert("m1", 1000.0, 1010.0, "main")
|
self._insert("m1", 1000.0, 1010.0, "main")
|
||||||
self._insert("o1", 1000.0, 1010.0, "main", camera="back_yard")
|
self._insert("o1", 1000.0, 1010.0, "main", camera="back_yard")
|
||||||
|
|||||||
@@ -204,11 +204,12 @@ def coverage_spans(intervals: list[CoverageInterval]) -> list[dict[str, Any]]:
|
|||||||
def stream_has_audio(intervals: list[CoverageInterval], main: bool) -> bool:
|
def stream_has_audio(intervals: list[CoverageInterval], main: bool) -> bool:
|
||||||
"""Whether a stream is audio-bearing over a coverage window.
|
"""Whether a stream is audio-bearing over a coverage window.
|
||||||
|
|
||||||
A stream counts as audio-bearing unless EVERY one of its rows reports
|
A stream counts as audio-bearing only when one of its rows is known
|
||||||
has_audio False; NULL (legacy or undetermined) counts as audio.
|
to carry audio. A NULL row (legacy, or a segment ffprobe could not
|
||||||
|
read) proves nothing either way.
|
||||||
"""
|
"""
|
||||||
return any(
|
return any(
|
||||||
row is not None and row.has_audio is not False
|
row is not None and row.has_audio is True
|
||||||
for row in ((interval.main if main else interval.sub) for interval in intervals)
|
for row in ((interval.main if main else interval.sub) for interval in intervals)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user