import cv2 import numpy as np import pytest from paperpod.capture.video import iter_frames, probe_video @pytest.fixture(scope="module") def tiny_video(tmp_path_factory): """3s, 24fps, 320x240 video with a moving square.""" path = tmp_path_factory.mktemp("video") / "tiny.mp4" writer = cv2.VideoWriter(str(path), cv2.VideoWriter_fourcc(*"mp4v"), 24, (320, 240)) for i in range(72): frame = np.full((240, 320, 3), 100, dtype=np.uint8) x = 10 + i * 3 cv2.rectangle(frame, (x, 100), (x + 40, 140), (255, 255, 255), -1) writer.write(frame) writer.release() return path def test_probe(tiny_video): meta = probe_video(tiny_video) assert meta.fps == pytest.approx(24, abs=0.5) assert meta.frame_count == 72 assert meta.width == 320 and meta.height == 240 assert meta.duration_s == pytest.approx(3.0, abs=0.1) def test_iter_frames_sample_rate(tiny_video): frames = list(iter_frames(tiny_video, sample_fps=8)) # 24fps sampled at 8fps -> every 3rd frame -> 24 frames assert len(frames) == 24 ts = [f.t for f in frames] assert ts == sorted(ts) assert ts[0] == 0.0 def test_iter_frames_resize(tiny_video): frame = next(iter_frames(tiny_video, sample_fps=8, resize_width=160)) assert frame.image.shape[1] == 160 assert frame.image.shape[0] == 120 def test_probe_missing_file(): with pytest.raises(FileNotFoundError): probe_video("does_not_exist.mp4")