CONTINUUM CONTINUUM
Video Annotator · GuideHow to mark test segments on videos

Video Annotator guide

The Video Annotator is used to mark when each movement in a test video starts and ends (for example stand, pour water or drink) and saves those times in a YAML file. Each time is saved as real clock time, so it can be matched to the sensor recordings.

Overview

The annotator is a web page: open continuum-tools.pages.dev/annotator in Chrome or Edge. It is part of the same website as the Clinical Log, and there is nothing to install.

Videos are not uploaded. The browser opens them directly from your computer, so large files work, and nothing leaves the computer.
Nothing is saved automatically. Click Export YAML before closing or reloading the tab, or your segments are lost. To continue later, use Load YAML.

The screen

1Video · Load folder… Single video…, camera tabs, fps
2Timeline and controls · click or drag to move, play, step frames, speed
3Segments · the list of marked segments, Export YAML Load YAML
4Recording metadata · subject, run, condition, Rec. start…
5Mark a segment · label, start, end, notes, Add

On a narrow window the right-hand panels (4 and 5) move below the video.

Opening a video

One video (for example an iPhone clip)

  1. Click Single video… and choose the file (.mov, .mp4…).
  2. The file name appears in the grey pill above the video, Recording is filled with the file name, and Rec. start is read from the video itself when the file has it (see Rec. start).
  3. Check the fps box (top right of the video). It is 30 by default; change it if the video was recorded at another frame rate.

A folder of synchronized cameras

  1. Click Load folder… and choose the synchronized_videos folder of the recording. Chrome asks to confirm uploading the folder: this only lets the page read it, nothing is sent anywhere.
  2. Every Camera_XXX_synchronized.mp4 becomes a camera. If the folder also has the …_timestamps_human_readable.csv files, the cameras are kept frame-synced and the fps is set from them (shown on the right, under the controls: synced · 3 cam · … fps).
  3. Session and Recording are filled from the folder path.
  4. Switch camera with the Cam 1 Cam 2… tabs or the keys 1–9. ▦ all cameras shows them all side by side; click one to make it the main camera.
Segments are marked once and apply to all cameras: switching camera keeps the same frame.

Recording details

Fill in the Recording metadata panel before exporting. Subject, Condition and Run give the file its name, shown under the panel (Files export as subject_96_cond_09_run_01_events.yaml + _Info.yaml).

FieldWhat to enter
Subject (XX)Subject number, e.g. 96. Numbers are padded to two digits (7 → 07).
Run (ZZ)Which repetition of the test this video is, 01 for the first.
Condition (COND)The test shown in the video. Pick it first: it decides which labels you can choose under Mark a segment (see Labels) and the colour of the segments.
Session / visit, RecordingFilled automatically when possible; edit if needed.
RaterYour initials.
Rec. start, Offset (s)The clock time of the first frame. See the next section.

Rec. start and Offset

The annotator turns every marked frame into a real date and time, so that the movements can be found in the sensor data:

event time = Rec. start + time in the video − Offset
Without a Rec. start you cannot export. The YAML holds clock times, not video times, and these are what the analysis uses to match the movements to the sensors.

Moving through the video

Click or drag on the timeline (the bar under the video) to jump; hovering shows the time under the mouse. The large clock shows the current time in the video and the frame number.

KeyButtonDoes
space▶Play / pause
,   .◀| |▶One frame back / forward
⏪ ⏩10 frames back / forward
←   →1 second back / forward
1–9Cam 1…Switch camera (folder mode)
iMark start (i)Set the segment start at the current frame
oMark end (o)Set the segment end at the current frame
EnterAdd segment ⏎Save the segment

Use the speed buttons (0.25× 0.5× 1× 2×) to slow the video down around a movement. Keyboard shortcuts do nothing while the cursor is in a text box: click on the video area first.

Marking a segment

A segment is one movement: a label with a start and an end. There are two ways to mark one.

Frame by frame (most precise)

  1. Choose the Label (or type a custom label, which overrides the list).
  2. Go to the first frame of the movement and press i (Mark start (i)).
  3. Go to the last frame and press o (Mark end (o)).
  4. Check the box under the buttons: label, start, end and duration. Use the small ‹ › buttons to move the start or end by one frame. The marked part is also highlighted on the timeline.
  5. Optionally fill Trial / rep (e.g. 2 for the second repetition) and Notes.
  6. Press Enter or Add segment ⏎.

Live, while the video plays

  1. Choose the label and play the video (slow it down if it helps).
  2. Click ● Live mark: start when the movement starts. The button turns red.
  3. Click ■ Live mark: end when it ends. The segment is added straight away.

Live marking is quick but less precise; you can adjust the segment afterwards (see Checking and fixing).

If the new segment overlaps one that is already marked, that box shows ⚠ overlaps existing. You can still add it (some movements do overlap, e.g. walk and hold tray); the warning is there to catch mistakes.

Labels for each test

The labels offered depend on the Condition. If you need a label that is not in the list, type it in …or custom label.

ConditionLabels
01 TUG
02 Cognitive TUG
start tug, start stand, end stand, start turn, end turn, start sit, end sit
03 SPPB — Gaitstart walk, end walk
04 SPPB — Parallel
05 SPPB — Semi-Tandem
06 SPPB — Tandem
start hold, end hold
07 SPPB — STSstart stand, end stand, start sit, end sit
08 2MWTstart walk, end walk
09 Upper-Body Circuitstand, walk, sit, put items on tray, pour water, hold tray, add sugar, stir, drink
10 Lower-Body Circuitlie down, sit, walk, stand, hold phone, put socks on, put on jacket

Checking and fixing segments

Every segment appears in the Segments table (sorted by start time) and as a coloured bar on the timeline.

Saving: Export and Load YAML

YAML is the only file format the annotator uses. Each video is saved as two files that belong together:

FileContains
subject_XX_cond_YY_run_ZZ_events.yamlThe movements: start and end time of every segment, with trial and notes
subject_XX_cond_YY_run_ZZ_Info.yamlThe recording information: rec_start and rec_fps

Export YAML

  1. Check Subject, Run, Condition and Rec. start.
  2. Click Export YAML. The browser downloads both files. The first time, Chrome or Edge may ask whether the site can download multiple files: click Allow.
  3. Move both files to Data/VIDEOS/SUBJECT_XX/annotations/, where the analysis notebook (video_annotations_to_runs.ipynb) looks for them.
Tip: in Chrome or Edge, turn on Ask where to save each file before downloading (Settings → Downloads) to save straight into the right folder.

Load YAML (continue or check later)

  1. Open the same video (or folder) as before.
  2. Click Load YAML and select both files of the video together (Ctrl+click). Subject, Condition and Run come back from the file name, Rec. start and fps from the _Info.yaml, and all segments, with their trial and notes, from the _events.yaml. If segments are already marked, it asks before replacing them.
  3. Make your changes and Export YAML again (it overwrites the old files if you save them with the same names).

If you select only the _events.yaml, the annotator uses the Rec. start already in the panel (for example, read from the video). You can also load the files before the video; the segments are placed using the fps, and appear on the timeline once the video is open.

Old JSON files

Earlier versions of the annotator saved .json files. To turn one into YAML, click Convert it to YAML under the Segments table and choose the JSON. The annotator loads it and immediately downloads the _events.yaml and _Info.yaml files.

The YAML files

You do not need to edit them, but this is what they contain.

_events.yaml

Under movements each label has its start and end times (in order, so the first start goes with the first end), plus the trial and notes of each occurrence. All times are clock times on the sensor clock.

movements:
  'pour water':
    movement_start:
    - '2026-10-01 10:15:35.000'
    movement_end:
    - '2026-10-01 10:15:39.000'
    trial:
    - '1'
    notes:
    - ''

The analysis notebook reads movement_start and movement_end; trial and notes are kept so that Load YAML restores everything.

_Info.yaml

rec_start: '2026-10-01 10:15:30.000'
rec_fps: 30

Subject, condition and run are not repeated inside the files: they are in the file names.

Checklist

Troubleshooting

ProblemWhat to do
The video is black, or shows browser can't decode this file / codec not supported The video is in a format the browser cannot play (usually HEVC / H.265). For a synchronized_videos folder, run Code/video_annotator/transcode_for_annotator.py on it; it makes a browser-playable synchronized_videos_h264 copy with exactly the same frames. Load that folder instead.
Load folder… does nothing or the folder can't be chosen Use Chrome or Edge. Choose the synchronized_videos folder itself.
No "Camera_XXX_synchronized.*" videos found You picked the wrong folder: it must contain the Camera_…_synchronized.mp4 files.
The label list says — pick a condition first — Choose the Condition in Recording metadata.
Export YAML says Event datetimes need a Rec. start Type Rec. start as YYYY-MM-DD HH:MM:SS.
Keys like i or space don't work The cursor is in a text box. Click on the video or an empty area of the page first.
The times look shifted compared with the sensors Check Rec. start, then adjust Offset and export again.
Only one of the two files was downloaded The browser blocked the second download. Allow multiple downloads for the site (icon at the right of the address bar) and click Export YAML again.
Load YAML: No Rec. start Select the _events.yaml and its _Info.yaml together (Ctrl+click), or open the video first.

Clinical Log users: see the Clinical Log guide.