Skip to main content

๐ŸŽฌ Annotation Tool Overview

Professional Video Annotation for Tennis AI Training

AceSense Annotate is a cross-platform desktop application for creating high-quality training data for tennis AI models. Built with Tauri + React for native performance.


๐ŸŽฏ Purposeโ€‹

:::info Why This Exists

  • Training Data: Create labeled datasets for shot detection and event classification (point, box, and temporal-event annotations)
  • Speed: Professional annotators need keyboard-first workflows :::

๐Ÿ› ๏ธ Tech Stackโ€‹

TechnologyVersionPurpose
๐Ÿฆ€ Tauri2.0+Desktop shell (frameless window, fs/dialog/opener plugins). No decoding/persistence logic lives in Rust.
โš›๏ธ React18.3UI framework โ€” owns video, canvas overlay, annotation state, persistence
โšก Vite6.4Build tool
๐Ÿ“˜ TypeScript5.6Type safety
๐ŸŽฌ @ffmpeg/ffmpeg0.12Client-side WASM format conversion (MP4 fallback when a video won't play) โ€” not Rust decoding
๐Ÿ“ˆ PostHogโ€”Product analytics

๐Ÿ—๏ธ Architectureโ€‹

The Rust backend (src-tauri/src/lib.rs) only wires the shell: frameless window setup plus fs/dialog/opener plugins. Video playback, the Canvas2D annotation overlay, WASM format conversion, and project persistence (via @tauri-apps/plugin-fs) all run in the React frontend. The app also runs in a plain browser (web mode) with a file-picker fallback.


๐Ÿ“‚ Project Structureโ€‹

acesense-annotate/
โ”œโ”€โ”€ src/ # React frontend
โ”‚ โ”œโ”€โ”€ App.tsx # Main workspace
โ”‚ โ”œโ”€โ”€ components/
โ”‚ โ”‚ โ”œโ”€โ”€ VideoViewport.tsx # <video> + Canvas2D annotation overlay
โ”‚ โ”‚ โ”œโ”€โ”€ Timeline.tsx # Frame scrubber
โ”‚ โ”‚ โ”œโ”€โ”€ PropertiesPanel.tsx # Property editor
โ”‚ โ”‚ โ”œโ”€โ”€ ItemsPanel.tsx # Annotation list
โ”‚ โ”‚ โ”œโ”€โ”€ ContextModal.tsx # Tennis context picker
โ”‚ โ”‚ โ”œโ”€โ”€ ShortcutModal.tsx # In-app shortcut cheat sheet (`?`)
โ”‚ โ”‚ โ”œโ”€โ”€ ErrorBoundary.tsx # Crash guard
โ”‚ โ”‚ โ””โ”€โ”€ VideoConverter.tsx # @ffmpeg/ffmpeg WASM converter
โ”‚ โ”œโ”€โ”€ types.ts # TypeScript types (Tool, Annotation, TemporalEvent, ProjectData)
โ”‚ โ””โ”€โ”€ utils.ts # Helpers (allowed-events, fps detection)
โ”œโ”€โ”€ src-tauri/ # Tauri shell
โ”‚ โ”œโ”€โ”€ src/lib.rs # Plugin registration + frameless window setup
โ”‚ โ”œโ”€โ”€ Cargo.toml # Dependencies
โ”‚ โ””โ”€โ”€ tauri.conf.json # App config
โ”œโ”€โ”€ public/ # Static assets
โ””โ”€โ”€ package.json

๐ŸŽฎ Keyboard Shortcutsโ€‹

Playback Controlsโ€‹

KeyAction
SpacePlay / Pause
โ† / โ†’Frame step
Shift + โ† / โ†’Jump 10 frames
J / K / LReverse / Pause / Forward (J/L ramp 2ร—โ†’4ร— on repeat)

Annotation Toolsโ€‹

KeyToolBehavior
PPointClick to place a point (x, y, time)
BBoxClick-drag to draw (x1, y1, x2, y2, time)
TTemporal EventActivate event tool, or close the open event
1โ€“6Set event typeserve / shot / bounce / point_end / net_hit / out (selected event)
EscSelect / deselectBack to select tool
?HelpToggle the shortcut cheat sheet

See the full Keyboard Reference. There is no skeleton tool or ML-suggestion review.


๐ŸŽพ Tennis Context Systemโ€‹

Before annotating, select the tennis context to unlock appropriate tools:

ContextAllowed Annotations
Matchserve, shot, bounce, net_hit, out, point_end
Practiceshot, bounce
Training (off-court)shot only
Highlight clipshot, point_end

๐Ÿ“‹ Annotation Schemaโ€‹

The persisted shapes come from src/types.ts. There is no pose/skeleton schema.

Temporal Eventโ€‹

{
"id": "evt_014",
"type": "event",
"eventType": "shot",
"startTime": 12.21,
"endTime": 12.94,
"shotType": "forehand",
"confidence": 0.88
}

eventType โˆˆ serve | shot | bounce | net_hit | out | point_end. shotType (forehand | backhand | unknown) and confidence are optional. endTime is null while an event is open.

Point / Box annotationsโ€‹

{ "id": "pt_001", "type": "point", "time": 3.417, "x": 0.51, "y": 0.18 }
{ "id": "box_002", "type": "box", "time": 4.000, "x1": 0.40, "y1": 0.30, "x2": 0.62, "y2": 0.70 }

The full saved file is a ProjectData object (video, fps, video_meta, events, annotations).


๐Ÿš€ Developmentโ€‹

# Install dependencies
pnpm install

# Start dev server (web preview, runs in a plain browser too)
pnpm dev

# Run desktop app
pnpm tauri dev

# Type-check / test
pnpm typecheck
pnpm test

# Build production app
pnpm tauri build