Files
WebAVP/CLAUDE.md
T

4.3 KiB
Raw Blame History

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:

npm install
npm start

Web/Python mode:

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:

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 enginerequestAnimationFrame 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