🤖AI-generated documentation☐ curatedAI Generated
About content generation types
(e.g., docs generated from codebase analysis)
(e.g., livestream → blog post, meeting notes → docs)
(e.g., hand-written tutorial)
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)
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):
| Path | Default |
|---|---|
| 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
| Stage | What it checks | Key indicator |
|---|---|---|
| Synchronized videos | Original camera footage exists | synchronized_videos/ has video files |
| Calibration | Camera parameters estimated | {name}_calibration.toml exists and is valid |
| Blender input data (.npy) | Required .npy files generated | All 6 body/face/hand/COM .npy files present |
| Annotated videos | Detection overlay videos rendered | annotated_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
ActiveRecordingPageandRecordingBrowser
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.