"""Standalone validation harness for build-order step 1: confirm python-mpv gives frame-accurate seeking before any of the rest of the UI is built. Steps frame-by-frame across the known flash event in the synthetic test clip (white flash at t=5.000s, frame 150 @ 30fps) and dumps a screenshot + reported position/frame-number per step, so the results can be inspected directly instead of trusted on faith. """ import sys import time from pathlib import Path from PyQt6.QtWidgets import QApplication sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from player_widget import PlayerWidget CLIP = str(Path(__file__).resolve().parent.parent / "test_media" / "sync_test_INSYNC.mp4") OUT_DIR = Path(__file__).resolve().parent.parent / "test_media" / "seek_validation" def main(): OUT_DIR.mkdir(exist_ok=True) app = QApplication(sys.argv) w = PlayerWidget() w.resize(640, 480) w.show() app.processEvents() w.load(CLIP) app.processEvents() print(f"fps reported by mpv: {w.fps()}") # Land a few frames before the flash (frame 150 == t=5.000s), then # single-step across it. w.seek(4.900) app.processEvents() time.sleep(0.2) app.processEvents() results = [] for i in range(8): pos = w.get_position() frame = w.get_estimated_frame() shot = OUT_DIR / f"step_{i:02d}_frame{frame}.png" w.screenshot(str(shot)) results.append((i, pos, frame, shot.name)) print(f"step {i}: time_pos={pos:.4f}s estimated_frame={frame} -> {shot.name}") w.step_frame(1) app.processEvents() w.shutdown() print("\nExpected: flash frame is frame index 150 (t=5.000-5.033s).") print("Check the dumped PNGs in test_media/seek_validation/ to confirm") print("exactly one frame is white/bright and it lines up with the") print("reported frame number close to 150.") if __name__ == "__main__": main()