Skip to main content
🤖AI-generated documentation curatedAI Generated
This page was drafted by an AI assistant and may contain inaccuracies.
About content generation types
🤖
AI GeneratedPage drafted entirely by AI from codebase or prompt instructions.
(e.g., docs generated from codebase analysis)
← this page
✋→🤖
AI TransformattedHuman provided raw material; AI restructured it into a different format.
(e.g., livestream → blog post, meeting notes → docs)
Human GeneratedPage written entirely by a human author.
(e.g., hand-written tutorial)
More info about content generation types ↗

Recording Structure

Every recording session — whether calibration, mocap, or both — produces a structured folder on disk. The RecordingStructure Pydantic model defines the canonical layout, and RecordingStatus tracks which processing stages are complete.

Canonical Layout

~/freemocap_data/recordings/
└── {recording_name}/
├── videos/
│ ├── synchronized/ # Frame-synchronized camera videos
│ │ ├── camera_0.mp4
│ │ ├── camera_1.mp4
│ │ └── ...
│ └── annotated/ # Videos with detection overlays
│ ├── camera_0_annotated.mp4
│ └── ...
├── output/ # Per-stage processed artifacts
│ ├── *.npy # 3D keypoints, center-of-mass, etc.
│ ├── *.csv
│ └── *.parquet
├── logs/ # Per-recording log files
├── {name}_calibration.toml # Authoritative calibration data
├── {name}_recording_info.json # Camera configs + recording type tags
├── {name}_data.parquet # Primary mocap data store
└── {name}.blend # Blender export (optional)
Current runtime layout

The synchronized camera videos are recorded by SkellyCam. The recording and post-hoc pipelines currently still write the legacy layout — synchronized_videos/, annotated_videos/, output_data/, and {recording_name}_camera_calibration.toml (see system/default_paths.py and the Post-Hoc Motion Capture guide). RecordingStructure.validate_layout() accepts both layouts and reports which markers are present; the videos/… + output/ layout above is the migration target.

RecordingStructure Model

The RecordingStructure Pydantic model (system/recording_structure/recording_structure.py, ~178 lines) provides computed properties for all canonical paths:

class RecordingStructure(BaseModel):
base_directory: Path
recording_name: str

# Computed properties (all @computed_field)
@property
def full_path(self) -> Path: ...
@property
def videos_synchronized_dir(self) -> Path: ... # {full}/videos/synchronized
@property
def videos_annotated_dir(self) -> Path: ... # {full}/videos/annotated
@property
def output_dir(self) -> Path: ... # {full}/output
@property
def logs_dir(self) -> Path: ...
@property
def calibration_toml_path(self) -> Path: ...
@property
def recording_info_path(self) -> Path: ...
@property
def data_parquet_path(self) -> Path: ...
@property
def blend_path(self) -> Path: ...

validate_layout() checks both canonical (output/) and legacy (output_data/) layouts, providing backward compatibility with recordings from older versions.

Default Paths

Defined in system/default_paths.py (~83 lines):

PathDefault
Base data folder~/freemocap_data/
Recordings folder~/freemocap_data/recordings/
Test data~/freemocap_data/recordings/freemocap_test_data/
Logs~/freemocap_data/logs_info_and_settings/logs/
Latest calibration~/freemocap_data/calibrations/last_successful_camera_calibration.toml

Recording Info

Each recording saves a recording_info.json alongside its data:

{
"recording_name": "my_session",
"recording_type": "calibration", // or "mocap"
"camera_configs": { ... }, // Per-camera settings at record time
"created_at": "2026-06-17T14:00:00"
}

This provides a self-contained record of how the recording was captured, making it possible to reprocess later with different parameters.

Recording Status

The RecordingStatus model (system/recording_status/recording_status.py, ~255 lines) tracks which processing stages are complete for a given recording.

Five Stages

StageWhat it checksKey indicator
Synchronized videosOriginal camera footage existssynchronized_videos/ has video files
CalibrationCamera parameters estimated{name}_calibration.toml exists and is valid
Blender input data (.npy)Required .npy files generatedAll 6 body/face/hand/COM .npy files present
Annotated videosDetection overlay videos renderedannotated_videos/ has annotated video files
Blender scene.blend file exported{name}.blend exists and is non-empty

Blender Export Readiness

blender_export_ready is True when all required .npy files exist:

mediapipe_body_3d_xyz.npy
mediapipe_right_hand_3d_xyz.npy
mediapipe_left_hand_3d_xyz.npy
mediapipe_face_3d_xyz.npy
mediapipe_body_total_body_center_of_mass.npy
mediapipe_body_segment_center_of_mass.npy

Usage

compute_recording_status() is called by:

  • Playback router: to report which stages are complete for each recording in the browser
  • Blender router: to check if a recording is ready for Blender export
  • Frontend: displays stage-by-stage status in the ActiveRecordingPage and RecordingBrowser

RecordingStatusSummary (Frontend Type)

The frontend mirrors this with a RecordingStatusSummary type used in Redux (recordingStatus slice) and the PipelineProgressPanel component. The backend and frontend models must agree on stage names and status values.