Guide

Python quickstart for loading egocentric training data

Install, list access, pull an episode, and stream aligned frames into training.
By the Firsthand capture teamLast updated September 23, 2026

Short answer

Install firsthand-ego, list what you can access, and pull an episode in the format your loader wants. The CLI and loader are thin wrappers over signed URLs — nothing phones home, nothing is obfuscated. Frames, depth and hand pose arrive already aligned on the head-camera clock.

Install and list what you have

shell
pip install firsthand-ego

# 1. list what you have access to
fh ls
# EP_0117_KITCHEN_A   78.4 s   kitchen/knife_dice        shipped
# EP_0118_KITCHEN_A   41.2 s   kitchen/pour_decant       shipped

# 2. pull one episode in the format your loader wants
fh get EP_0117_KITCHEN_A --format rlds --out ./data

# 3. or stream a whole skill line without staging it locally
fh stream --skill kitchen/knife_dice --format webdataset | your_trainer

Stream aligned frames into PyTorch

torch_loader.py
from firsthand_ego import Episode
import torch

ep = Episode.open("data/EP_0117_KITCHEN_A")

# frames and hand pose arrive already aligned on the head-camera clock
for step in ep.steps(rate_hz=30):
    rgb    = torch.from_numpy(step.head_rgb)          # [2160, 3840, 3]
    depth  = torch.from_numpy(step.depth_mm)          # [480, 848] uint16
    hands  = torch.from_numpy(step.hand_joints)       # [2, 21, 3] metres
    valid  = torch.from_numpy(step.hand_visible)      # [2, 21] bool
    action = step.action                               # ("dice", "onion")
    assert step.sync_error_ms < 2.0

Streams are stored at native rate and resampled by the loader with rate_hz, never in the delivery.

Check it against the sample pack.

40 episodes across 4 environments, delivered in the exact schema these guides describe.