diff --git a/src/lerobot/datasets/aggregate.py b/src/lerobot/datasets/aggregate.py index 90fc8f583..c9bb88da4 100644 --- a/src/lerobot/datasets/aggregate.py +++ b/src/lerobot/datasets/aggregate.py @@ -332,7 +332,6 @@ def aggregate_videos(src_meta, dst_meta, videos_idx, video_files_size_in_mb, chu videos_idx: Dictionary tracking video chunk and file indices. video_files_size_in_mb: Maximum size for video files in MB (defaults to DEFAULT_VIDEO_FILE_SIZE_IN_MB) chunk_size: Maximum number of files per chunk (defaults to DEFAULT_CHUNK_SIZE) - Returns: dict: Updated videos_idx with current chunk and file indices. """ @@ -417,6 +416,7 @@ def aggregate_videos(src_meta, dst_meta, videos_idx, video_files_size_in_mb, chu concatenate_video_files( [dst_path, src_path], dst_path, + compatibilty_check=True, ) # Update duration of this destination file dst_file_durations[dst_key] = current_dst_duration + src_duration diff --git a/src/lerobot/datasets/video_utils.py b/src/lerobot/datasets/video_utils.py index 2badab394..fe64d166e 100644 --- a/src/lerobot/datasets/video_utils.py +++ b/src/lerobot/datasets/video_utils.py @@ -555,7 +555,7 @@ def encode_video_frames( def concatenate_video_files( - input_video_paths: list[Path | str], output_video_path: Path, overwrite: bool = True + input_video_paths: list[Path | str], output_video_path: Path, overwrite: bool = True, compatibilty_check: bool = False ): """ Concatenate multiple video files into a single video file using pyav. @@ -568,6 +568,7 @@ def concatenate_video_files( input_video_paths: Ordered list of input video file paths to concatenate. output_video_path: Path to the output video file. overwrite: Whether to overwrite the output video file if it already exists. Default is True. + compatibilty_check: Whether to check if the input videos are compatible. Default is False. Note: - Creates a temporary directory for intermediate files that is cleaned up after use. @@ -586,6 +587,14 @@ def concatenate_video_files( if len(input_video_paths) == 0: raise FileNotFoundError("No input video paths provided.") + # This check may be skipped at recording time as videos are encoded with the same encoder config. + if compatibilty_check: + reference_video_info = get_video_info(input_video_paths[0]) + for input_path in input_video_paths[1:]: + video_info = get_video_info(input_path) + if video_info["video.height"] != reference_video_info["video.height"] or video_info["video.width"] != reference_video_info["video.width"] or video_info["video.fps"] != reference_video_info["video.fps"] or video_info["video.codec"] != reference_video_info["video.codec"] or video_info["video.pix_fmt"] != reference_video_info["video.pix_fmt"]: + raise ValueError(f"Input video {input_path} is not compatible with the reference video {input_video_paths[0]}.") + # Create a temporary .ffconcat file to list the input video paths with tempfile.NamedTemporaryFile(mode="w", suffix=".ffconcat", delete=False) as tmp_concatenate_file: tmp_concatenate_file.write("ffconcat version 1.0\n")