diff --git a/vr180_matting/vr180_processor.py b/vr180_matting/vr180_processor.py index 3e39c95..61e5aff 100644 --- a/vr180_matting/vr180_processor.py +++ b/vr180_matting/vr180_processor.py @@ -156,80 +156,57 @@ class VR180Processor(VideoProcessor): temp_video_path = Path.cwd() / temp_video_name try: - # Write frames to temporary video + # Use ffmpeg approach since OpenCV video writer is failing height, width = eye_frames[0].shape[:2] + temp_video_path = temp_video_path.with_suffix('.mp4') - # Try different codecs if mp4v fails - codecs_to_try = [ - ('mp4v', '.mp4'), - ('XVID', '.avi'), - ('MJPG', '.avi') - ] + print(f"Creating temp video using ffmpeg: {temp_video_path}") + print(f"Video params: size=({width}, {height}), frames={len(eye_frames)}") - writer = None - for fourcc_str, ext in codecs_to_try: - fourcc = cv2.VideoWriter_fourcc(*fourcc_str) - temp_video_path_with_ext = temp_video_path.with_suffix(ext) - - print(f"Trying codec {fourcc_str} with path {temp_video_path_with_ext}") - print(f"Video params: size=({width}, {height}), fps=30.0") - - writer = cv2.VideoWriter(str(temp_video_path_with_ext), fourcc, 30.0, (width, height)) - - if writer.isOpened(): - # Test writing the first frame - test_frame = eye_frames[0].copy() - if test_frame.dtype != np.uint8: - test_frame = test_frame.astype(np.uint8) - if not test_frame.flags['C_CONTIGUOUS']: - test_frame = np.ascontiguousarray(test_frame) - - test_success = writer.write(test_frame) - print(f"Test write with {fourcc_str}: {'SUCCESS' if test_success else 'FAILED'}") - - if test_success: - temp_video_path = temp_video_path_with_ext - print(f"Using codec {fourcc_str} for temp video") - # Reset writer to start fresh - writer.release() - writer = cv2.VideoWriter(str(temp_video_path_with_ext), fourcc, 30.0, (width, height)) - break - else: - writer.release() - writer = None - else: - print(f"Failed to open writer with {fourcc_str}") - writer.release() - writer = None - - if writer is None: - raise RuntimeError("Failed to open video writer with any codec") - - # Debug frame properties - first_frame = eye_frames[0] - print(f"Frame properties: shape={first_frame.shape}, dtype={first_frame.dtype}, " - f"min={first_frame.min()}, max={first_frame.max()}") + # Create a temporary directory for frame images + temp_frames_dir = temp_video_path.parent / f"frames_{temp_video_path.stem}" + temp_frames_dir.mkdir(exist_ok=True) + # Save frames as individual images + print("Saving frames as images...") for i, frame in enumerate(eye_frames): - # Ensure frame is in the right format for OpenCV + # Ensure frame is uint8 if frame.dtype != np.uint8: frame = frame.astype(np.uint8) - # Ensure frame is contiguous - if not frame.flags['C_CONTIGUOUS']: - frame = np.ascontiguousarray(frame) - - success = writer.write(frame) + frame_path = temp_frames_dir / f"frame_{i:06d}.png" + success = cv2.imwrite(str(frame_path), frame) if not success: - print(f"Failed to write frame {i}/{len(eye_frames)}") - print(f"Frame {i} properties: shape={frame.shape}, dtype={frame.dtype}, contiguous={frame.flags['C_CONTIGUOUS']}") - raise RuntimeError(f"Failed to write frame {i} to {temp_video_path}") + raise RuntimeError(f"Failed to save frame {i} as image") if i % 50 == 0: - print(f"Written {i}/{len(eye_frames)} frames") + print(f"Saved {i}/{len(eye_frames)} frames") - writer.release() - del writer # Ensure it's fully released + # Use ffmpeg to create video from images + import subprocess + ffmpeg_cmd = [ + 'ffmpeg', '-y', # -y to overwrite output file + '-framerate', '30', + '-i', str(temp_frames_dir / 'frame_%06d.png'), + '-c:v', 'libx264', + '-pix_fmt', 'yuv420p', + '-crf', '23', + str(temp_video_path) + ] + + print(f"Running ffmpeg: {' '.join(ffmpeg_cmd)}") + result = subprocess.run(ffmpeg_cmd, capture_output=True, text=True) + + if result.returncode != 0: + print(f"FFmpeg stdout: {result.stdout}") + print(f"FFmpeg stderr: {result.stderr}") + raise RuntimeError(f"FFmpeg failed with return code {result.returncode}") + + # Clean up frame images + import shutil + shutil.rmtree(temp_frames_dir) + + print(f"Created temp video successfully") # Verify the file was created and has content if not temp_video_path.exists():