Files
WebAVP/CLAUDE.md
T

81 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
**Alta Video Player (WebAVP)** — a web-based surveillance video player for Alta/Ava Security camera exports. Users drag-drop video files or ZIP archives (including AES-256 encrypted ones) and get a multi-camera synchronized playback experience with timeline, digital zoom, and cryptographic integrity verification.
## Running the App
Desktop mode:
```bash
npm install
npm start
```
Web/Python mode:
```bash
python3 app.py
# Serves on http://0.0.0.0:5152
```
The Python server uses only stdlib modules. Electron dependencies are managed through `package.json` and `package-lock.json`.
Checks:
```bash
npm run check
xvfb-run -a npm run smoke
```
## Architecture
### Backend (`app.py`)
Minimal HTTP server with three routes:
- `GET /` — serves `templates/index.html`
- `GET /static/*` — serves static files with path traversal protection
- `GET /api/verify-cert?serial=...&certificateHash=...` — proxies certificate verification to `https://aware.avasecurity.com/api/v1/public/verifyServerCertificate`
### Frontend (`templates/index.html`)
Single self-contained HTML file (~4000 lines) with inline CSS and JavaScript in an IIFE. This is the entire application — there is no framework, no build system, no separate JS modules.
**State model:** Global `channels` Map keyed by channel name. Each channel holds segments (video blobs + time ranges), metadata, DOM references, color, and zoom state. Global timeline state (`globalStart`, `globalEnd`, `currentTime`) synchronizes all cameras.
**Key subsystems:**
- **File ingestion** — drag-drop files/folders, ZIP extraction (JSZip for plain, custom AES-256-CTR for encrypted), metadata pairing by base filename, concurrent import guard (`isImporting` flag)
- **Multi-camera grid** — responsive CSS grid (19 cameras), drag-to-reorder, click-to-expand
- **Playback engine** — `requestAnimationFrame` tick loop, per-channel segment visibility management, variable speed (0.25x8x), frame stepping
- **Timeline** — interactive scrub bar with zoom (mouse wheel), minimap, per-channel segment indicators with color-coded dots
- **Digital zoom** — per-camera scroll-to-zoom (up to 10x) with click-drag panning
- **Magnifier tool** — draw rectangle to zoom into region
- **Slideshow mode** — animated grid showing only currently active feeds with transitions
- **Integrity verification** — offline X.509 certificate parsing, RSASSA-PKCS1-v1_5 and ECDSA signature verification via Web Crypto API, optional cloud verification through `/api/verify-cert`
- **Session persistence** — IndexedDB caching of video blobs and metadata for page refresh survival
**External dependency:** `/static/jszip.min.js` (vendored, for unencrypted ZIP parsing).
Motion analytics were intentionally removed. Keep future work focused on core video player behavior unless the product direction changes.
## Memory Management
Video elements must be properly destroyed to avoid browser memory exhaustion:
- **`destroyVideoEl(videoEl)`** — pauses video, removes `src`, calls `.load()` to force browser to release buffered data. Must be called before removing video elements from DOM.
- **`video.preload = 'metadata'`** — all playback videos use metadata-only preloading to avoid buffering entire files into RAM.
- **`newSession()`** — comprehensive teardown: destroys all video elements, revokes all blob URLs, nulls blob references, releases WebGL contexts, clears all state.
- **`isImporting` guard** — prevents concurrent file imports which could cause race conditions and duplicate segments.
- Slideshow video elements are destroyed on pane transitions and when slideshow is toggled off.
## Key Conventions
- All frontend code lives in `templates/index.html` — CSS at top, then the IIFE script block
- Video elements are created on-demand and hidden (not removed) for performance
- Segment visibility is recalculated every animation frame during playback
- The `batchingSegments` flag defers rendering during bulk file imports
- Keyboard shortcuts are defined inline (Space=play/pause, arrows=seek, S=slideshow, M=magnifier, F=fullscreen, [/]=speed, 0=reset zoom)
- Right-side panel (log) is the only slide-out; opening it does not affect other panels