# CAMERA PTZ CONTROL - Feature Spec # Control cameras using captured credentials ## PROJECT CONTEXT - Existing project: employee-tracker - Already have: Camera credential extraction (browser_extract.py) - Already have: Camera scanner (ip-camera-scanner.py) - Client cùng LAN với cameras --- ## FEATURES TO IMPLEMENT ### 1. CAMERA DISCOVERY + CREDENTIAL MATCHING - Scan LAN for cameras (existing scanner) - Match with captured credentials from browser_extract - Auto-detect camera type (Hikvision, Dahua, generic ONVIF) - Store matched cameras in database ### 2. ONVIF PTZ CONTROL - Use python-onvif-zeep library - Connect to camera using credentials - Get PTZ capabilities (can pan? tilt? zoom?) - Continuous move (pan left/right, tilt up/down, zoom in/out) - Stop movement - Go to preset positions - Get/set presets ### 3. HIKVISION ISAPI CONTROL - For Hikvision cameras không support ONVIF - HTTP API: /ISAPI/PTZCtrl/channels/{id}/continuous - Pan/Tilt/Zoom commands - Preset management ### 4. LIVE VIEW - Get RTSP stream URL from camera - Relay through server (avoid CORS) - Display in dashboard using MJPEG or HLS ### 5. DASHBOARD UI #### Camera List Tab - Grid of discovered cameras with thumbnails - Status: Online/Offline - Credentials status: Matched/Unknown - Click to open control panel #### PTZ Control Panel (Modal/Sidebar) - Live video feed - Joystick control (drag to move) - Or arrow buttons: ← ↑ → ↓ - Zoom slider: + / - - Speed control - Preset buttons (1-8) - Save preset button #### Quick Actions - Snapshot button - Record button (start/stop) - Full screen - Picture-in-picture --- ## API ENDPOINTS ### Camera Management ``` GET /api/cameras - List all discovered cameras POST /api/cameras/scan - Trigger LAN scan POST /api/cameras/{id}/match - Match with credentials GET /api/cameras/{id}/capabilities - Get PTZ capabilities ``` ### PTZ Control ``` POST /api/cameras/{id}/ptz/move body: { pan: -1..1, tilt: -1..1, zoom: -1..1, speed: 0.1..1 } POST /api/cameras/{id}/ptz/stop POST /api/cameras/{id}/ptz/preset body: { action: "goto" | "set" | "remove", preset: 1-8 } GET /api/cameras/{id}/ptz/presets - List presets ``` ### Streaming ``` GET /api/cameras/{id}/snapshot - Get JPEG snapshot GET /api/cameras/{id}/stream - MJPEG stream proxy ``` --- ## DATABASE SCHEMA ### cameras table ```sql CREATE TABLE cameras ( id INTEGER PRIMARY KEY, ip TEXT NOT NULL, port INTEGER DEFAULT 80, rtsp_port INTEGER DEFAULT 554, name TEXT, manufacturer TEXT, -- hikvision, dahua, generic model TEXT, -- Credentials (matched from extraction) username TEXT, password TEXT, credential_source TEXT, -- 'extracted', 'manual', 'default' -- Capabilities has_ptz BOOLEAN DEFAULT FALSE, has_audio BOOLEAN DEFAULT FALSE, has_presets BOOLEAN DEFAULT FALSE, -- Status online BOOLEAN DEFAULT FALSE, last_seen DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` --- ## CLIENT MODULE (camera_control.py) ### Functions needed: ```python def discover_cameras_lan() -> List[dict] def match_credentials(camera_ip, extracted_creds) -> dict def get_onvif_client(ip, port, user, password) -> ONVIFCamera def ptz_move(camera, pan, tilt, zoom, speed) def ptz_stop(camera) def ptz_goto_preset(camera, preset_number) def get_snapshot(camera) -> bytes def get_rtsp_url(camera) -> str ``` --- ## LIBRARIES ``` python-onvif-zeep # ONVIF protocol opencv-python # Video capture/snapshot requests # HTTP API calls ``` --- ## DASHBOARD UI COMPONENTS ### Joystick Control (CSS + JS) ```html
``` ### Keyboard Shortcuts - Arrow keys: Pan/Tilt - +/-: Zoom - 1-8: Go to preset - Space: Stop - S: Snapshot - R: Record toggle --- ## IMPLEMENTATION ORDER 1. Camera model + database table 2. ONVIF connection + PTZ basics 3. API endpoints for PTZ 4. Dashboard UI - camera list 5. Dashboard UI - PTZ controls 6. Live view streaming 7. Hikvision ISAPI fallback 8. Preset management 9. Keyboard shortcuts Implement step by step, test each feature.