from pathlib import Path import cv2 as cv source_path = Path("input/scene.png") output_path = Path("output/still-demo.mp4") fps = 24 duration_seconds = 3 frame_count = fps * duration_seconds image = cv.imread(str(source_path)) if image is None: raise SystemExit(f"Could not read source image: {source_path}") height, width = image.shape[:2] width -= width % 2 height -= height % 2 frame_size = (width, height) base = cv.resize(image, frame_size, interpolation=cv.INTER_AREA) output_path.parent.mkdir(parents=True, exist_ok=True) fourcc = cv.VideoWriter_fourcc(*"mp4v") writer = cv.VideoWriter(str(output_path), fourcc, fps, frame_size) if not writer.isOpened(): raise SystemExit(f"Could not open VideoWriter for: {output_path}") for index in range(frame_count): frame = base.copy() progress = index / max(frame_count - 1, 1) bar_width = int(progress * (width - 40)) overlay = frame.copy() cv.rectangle(overlay, (20, height - 45), (20 + bar_width, height - 25), (0, 180, 255), -1) frame = cv.addWeighted(overlay, 0.35, frame, 0.65, 0) cv.putText( frame, f"Frame {index + 1:02d}/{frame_count}", (20, 40), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv.LINE_AA, ) writer.write(frame) writer.release() capture = cv.VideoCapture(str(output_path)) if not capture.isOpened(): raise SystemExit(f"Could not reopen video: {output_path}") saved_frames = int(capture.get(cv.CAP_PROP_FRAME_COUNT)) saved_fps = capture.get(cv.CAP_PROP_FPS) saved_width = int(capture.get(cv.CAP_PROP_FRAME_WIDTH)) saved_height = int(capture.get(cv.CAP_PROP_FRAME_HEIGHT)) capture.release() duration = saved_frames / saved_fps if saved_fps else 0 size_kib = output_path.stat().st_size / 1024 print(f"wrote: {output_path}") print(f"frames: {saved_frames}") print(f"fps: {saved_fps:.1f}") print(f"size: {saved_width}x{saved_height}") print(f"duration: {duration:.2f}s") print(f"file size: {size_kib:.1f} KiB")