| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | import glob |
| | from dataclasses import dataclass |
| |
|
| | import imageio |
| | import numpy as np |
| |
|
| | from .log import log |
| |
|
| |
|
| | @dataclass |
| | class VideoData: |
| | frames: np.ndarray |
| | fps: int |
| | duration: int |
| |
|
| |
|
| | def get_video_filepaths(input_dir: str) -> list[str]: |
| | """Get a list of filepaths for all videos in the input directory.""" |
| | paths = glob.glob(f"{input_dir}/**/*.mp4", recursive=True) |
| | paths += glob.glob(f"{input_dir}/**/*.avi", recursive=True) |
| | paths += glob.glob(f"{input_dir}/**/*.mov", recursive=True) |
| | paths = sorted(paths) |
| | log.debug(f"Found {len(paths)} videos") |
| | return paths |
| |
|
| |
|
| | def read_video(filepath: str) -> VideoData: |
| | """Read a video file and extract its frames and metadata.""" |
| | try: |
| | reader = imageio.get_reader(filepath, "ffmpeg") |
| | except Exception as e: |
| | raise ValueError(f"Failed to read video file: {filepath}") from e |
| |
|
| | |
| | try: |
| | metadata = reader.get_meta_data() |
| | fps = metadata.get("fps") |
| | duration = metadata.get("duration") |
| | except Exception as e: |
| | reader.close() |
| | raise ValueError(f"Failed to extract metadata from video file: {filepath}") from e |
| |
|
| | |
| | try: |
| | frames = np.array([frame for frame in reader]) |
| | except Exception as e: |
| | raise ValueError(f"Failed to extract frames from video file: {filepath}") from e |
| | finally: |
| | reader.close() |
| |
|
| | return VideoData(frames=frames, fps=fps, duration=duration) |
| |
|
| |
|
| | def save_video(filepath: str, frames: np.ndarray, fps: int) -> None: |
| | """Save a video file from a sequence of frames.""" |
| | try: |
| | writer = imageio.get_writer(filepath, fps=fps, macro_block_size=1) |
| | for frame in frames: |
| | writer.append_data(frame) |
| | except Exception as e: |
| | raise ValueError(f"Failed to save video file to {filepath}") from e |
| | finally: |
| | writer.close() |
| |
|