Validate audio stream timelines and add genuine Google transcript diagnostics

This commit is contained in:
karl committed 2026-10-13 10:39:31 +02:00
1 parent 8ef874c609
commit 5eeba29c0d
7 files changed
+1074 -23

No files matched your search

+40 -2
View File
@@ -6,11 +6,49 @@ import tempfile
import sys
import os
import wave
from run import segments, run_owned, recognized_window, decode_command, decoded_frames
from score import score
from run import segments, run_owned, recognized_window, decode_command, decoded_frames, primary_audio_range
from score import score, require_eligible
class ContractTests(unittest.TestCase):
def test_scoring_rejects_incomplete_or_reduced_pool(self):
for report in [{}, {"complete": False, "quality_score_eligible": True},
{"complete": True, "quality_score_eligible": False},
{"complete": True, "quality_score_eligible": True, "excluded_windows": [{}]}]:
with self.assertRaises(ValueError):
require_eligible(report)
require_eligible({"complete": True, "quality_score_eligible": True, "excluded_windows": []})
def test_primary_audio_duration_and_nonzero_start_ignore_longer_video(self):
probe = {"streams": [{"index": 0, "codec_type": "video", "duration": "90"},
{"index": 1, "codec_type": "audio", "start_time": "0.125", "duration": "31"}]}
self.assertEqual(primary_audio_range(probe), (125, 31125, 1))
@unittest.skipUnless(os.environ.get("SEARCHI_TEST_FFMPEG"), "Requires verified CPU FFmpeg")
def test_actual_video_longer_than_audio(self):
ffmpeg = Path(os.environ["SEARCHI_TEST_FFMPEG"])
ffprobe = ffmpeg.with_name("ffprobe.exe" if os.name == "nt" else "ffprobe")
with tempfile.TemporaryDirectory() as parent:
scratch = Path(parent)
source = scratch / "longer-video.mkv"
run_owned([str(ffmpeg), "-nostdin", "-hide_banner", "-v", "error", "-threads", "1",
"-f", "lavfi", "-i", "color=c=black:s=16x16:r=1:d=33",
"-itsoffset", "0.125", "-f", "lavfi", "-i", "anullsrc=r=48000:cl=mono:d=31", "-c:v", "ffv1",
"-c:a", "pcm_s16le", "-threads", "1", "-output_ts_offset", "5", "-y", str(source)],
scratch, "mux", [(source, 4 * 1024 * 1024)], 30)
run_owned([str(ffprobe), "-v", "error", "-show_entries", "stream=index,codec_type,duration,start_time:stream_tags=DURATION:format=duration", "-of", "json", str(source)], scratch, "probe", [], 30)
probe = json.loads((scratch / "probe.log").read_text())
audio = next(row for row in probe["streams"] if row["codec_type"] == "audio")
# Matroska stores duration in tags; test conversion is explicit, not a format fallback.
if "duration" not in audio:
h, m, sec = audio["tags"]["DURATION"].split(":")
audio["duration"] = int(h) * 3600 + int(m) * 60 + float(sec) - float(audio["start_time"])
start, end, _ = primary_audio_range(probe)
self.assertEqual((start, end), (5125, 36125))
self.assertGreater(float(probe["format"]["duration"]), end / 1000)
wav = scratch / "tail.wav"
run_owned(decode_command(ffmpeg, source, 35125, 1000, wav, audio["index"]), scratch, "tail", [(wav, 970000)], 30)
self.assertGreaterEqual(decoded_frames(wav, 1000), 15984)
@unittest.skipUnless(os.environ.get("SEARCHI_TEST_FFMPEG"), "Requires verified CPU FFmpeg")
def test_actual_ffmpeg_full_window_and_partial_tail_sample_coverage(self):
ffmpeg = Path(os.environ["SEARCHI_TEST_FFMPEG"])