#!/usr/bin/env python3 """Test frame alignment between different FFmpeg extraction methods.""" import sys import logging from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent)) import json import numpy as np from src.video.ffmpeg_reader import FFmpegFrameReader from src.readers.flags import FlagReader logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") logger = logging.getLogger(__name__) def test_frame_at_timestamp(video_path: str, target_time: float, flag_reader: FlagReader, scorebug_x: int, scorebug_y: int): """Extract and test a specific frame.""" # Calculate absolute flag region x = scorebug_x + flag_reader.flag_x_offset y = scorebug_y + flag_reader.flag_y_offset w = flag_reader.flag_width h = flag_reader.flag_height with FFmpegFrameReader(video_path, target_time, target_time + 0.5, 0.5) as reader: for timestamp, frame in reader: result = flag_reader.read_from_fixed_location(frame, (x, y, w, h)) yellow_pct = result.yellow_ratio * 100 logger.info(f" t={timestamp:.1f}s: yellow={yellow_pct:.1f}%, hue={result.mean_hue:.1f}, detected={result.detected}") return timestamp, yellow_pct, result.mean_hue return None, 0, 0 def main(): video_path = "/Users/andytaylor/Documents/Personal/cfb40/full_videos/OSU vs Tenn 12.21.24.mkv" # Load session config with open("output/OSU_vs_Tenn_12_21_24_config.json", "r") as f: config = json.load(f) # Create flag reader flag_reader = FlagReader( flag_x_offset=config["flag_x_offset"], flag_y_offset=config["flag_y_offset"], flag_width=config["flag_width"], flag_height=config["flag_height"], ) scorebug_x = config["scorebug_x"] scorebug_y = config["scorebug_y"] logger.info("=" * 80) logger.info("FRAME ALIGNMENT TEST") logger.info(f"Flag region: offset=({flag_reader.flag_x_offset}, {flag_reader.flag_y_offset})") logger.info("=" * 80) # Test 1: Extract frame at 340.5s directly (like diagnostic) logger.info("\nTest 1: Extract frame at 340.5s directly (start_time=340.5)") test_frame_at_timestamp(video_path, 340.5, flag_reader, scorebug_x, scorebug_y) # Test 2: Extract frame 681 from start (like pipeline chunk 0) logger.info("\nTest 2: Extract from start and iterate to frame 681 (340.5s)") frame_count = 0 target_frame = 681 # 340.5 / 0.5 = 681 # Only extract 5 frames around the target to save time start_time = (target_frame - 2) * 0.5 # 339.5s end_time = (target_frame + 3) * 0.5 # 342.0s x = scorebug_x + flag_reader.flag_x_offset y = scorebug_y + flag_reader.flag_y_offset w = flag_reader.flag_width h = flag_reader.flag_height with FFmpegFrameReader(video_path, start_time, end_time, 0.5) as reader: for timestamp, frame in reader: result = flag_reader.read_from_fixed_location(frame, (x, y, w, h)) yellow_pct = result.yellow_ratio * 100 logger.info(f" t={timestamp:.1f}s: yellow={yellow_pct:.1f}%, hue={result.mean_hue:.1f}, detected={result.detected}") # Test 3: Extract from time 0 and iterate to 340.5s (exactly like pipeline) # This would take too long, so let's just test the first few frames to see if there's a pattern logger.info("\nTest 3: Extract first 10 frames from time 0 (like pipeline chunk 0)") with FFmpegFrameReader(video_path, 0.0, 5.0, 0.5) as reader: for timestamp, frame in reader: # Just print frame info, no flag detection (not expected at start of video) logger.info(f" t={timestamp:.1f}s: frame shape={frame.shape}") logger.info("\n" + "=" * 80) logger.info("CONCLUSION: If Test 1 and Test 2 show same results, frame alignment is correct") logger.info("=" * 80) if __name__ == "__main__": main()