ip cameras Service Summary: The DrHeck Camera Hub ( https://cam.drheck.dev) provides automatic LAN discovery, low-latency live video and MP3 audio streaming, two-way RTSP ONVIF backchannel voice talk, YOLOv8n + hardware AI event capture with a web-viewable timeline and text metadata log, optical 3D click-to-zoom and optional auto-zoom on moving objects, smart floodlight/IR/LED controls, privacy sleep mode, bandwidth adaptation, and a sideloadable Google TV interface for the Reolink PoE IP cameras on 10.0.0.0/24. Access is restricted via Authentik ForwardAuth to members of the camera_access group ( luke, ikura, and haruka). Hardware Inventory & Detected Cameras Two Reolink RLC-811A ( P430) 4K 8MP PoE Spotlight IP cameras are connected to the 10.0.0.0/24 LAN on interface eth77 of host ul with static DHCP leases on danknasty: Property Camera 1 ( RLC-811A (122)) Camera 2 ( RLC-811A (123)) IPv4 Address (Static Lease) 10.0.0.122 ( host cam1) 10.0.0.123 ( host cam2) MAC Address ec:71:db:f1:25:5a ec:71:db:6d:84:ce Vendor / OUI Reolink ( ec:71:db) Reolink ( ec:71:db) Model / Item No. RLC-811A / P430 RLC-811A / P430 Hardware Revision IPC_560B158MP IPC_560B158MP Firmware Version v3.1.0.4695_2504301440 v3.1.0.4695_2504301440 Serial Number 141484731968753 141484731989233 Ethernet Link 100M_FULL (802.3af PoE) 100M_FULL (802.3af PoE) Optical Zoom Range 5X Motorized ( ZoomPos 0..28, FocusPos 0..238, 3D Box Zoom) 5X Motorized ( ZoomPos 0..28, FocusPos 0..238, 3D Box Zoom) Illumination IR Night Vision ( auto/ close) + 450 lm Warm Floodlight ( 1..100%) IR Night Vision ( auto/ close) + 450 lm Warm Floodlight ( 1..100%) Audio Live Mic ( 16 kHz AAC -> MP3) + Two-Way Backchannel ( 8 kHz G.711 PCMU) + Siren Live Mic ( 16 kHz AAC -> MP3) + Two-Way Backchannel ( 8 kHz G.711 PCMU) + Siren Time Sync (NTP) time.google.com:123 ( America/New_York EDT/ EST) time.google.com:123 ( America/New_York EDT/ EST) Camera Services, Network Ports & Internal Operation On firmware v3.1.0.4695_2504301440, Reolink cameras lock down legacy plaintext web/streaming ports out of the box and expose only the proprietary Baichuan management port ( 9000/tcp) until explicitly instructed to enable standard streaming protocols. 1. Port & Service Matrix ( cmd_id = 37 GetNetPort / cmd_id = 36 SetNetPort) Service Protocol / Port Factory Default Active State on ul Purpose & Operation Baichuan ( server) 9000/tcp Enabled Enabled Proprietary binary + XML control, telemetry, snapshot, PTZ/zoom, AI/motion alarm, and configuration bus. RTSP ( rtsp) 554/tcp, 554/udp Disabled Enabled (Auto-enabled by cam) Real-Time Streaming Protocol serving hardware-encoded main (H.265 4K) and sub (H.264 360p) video, 16 kHz AAC microphone audio, and ONVIF Backchannel ( track3 PCMU/8000) speaker talkback. ONVIF ( onvif) 8000/tcp Disabled Disabled (Toggleable) Open Network Video Interface Forum profile for third-party NVR integration. RTMP ( rtmp) 1935/tcp Disabled Disabled (Toggleable) Flash/RTMP H.264 sub-stream ( rtmp://:1935/bcs/channel0_sub.bcs). HTTP ( http) 80/tcp Disabled Disabled (Toggleable) Embedded camera web UI and /cgi-bin/api.cgi JSON endpoint. HTTPS ( https) 443/tcp Disabled Disabled (Toggleable) Self-signed TLS embedded camera web UI and /cgi-bin/api.cgi JSON endpoint. 2. How the Baichuan Protocol ( 9000/tcp) Works All discovery, hardware control, and instantaneous snapshots are performed over TCP port 9000 using Reolink's Baichuan protocol: Binary Framing Header: Every Baichuan packet begins with a 20-byte or 24-byte little-endian binary header starting with magic bytes 0xf0debc0a, followed by cmd_id (uint32), payload length (uint32), channel_id (uint8), status code ( 200 OK, 400 Bad Request), and payload offset. Modern Nonce Authentication ( cmd_id = 1): The client sends an initial unauthenticated cmd_id = 1 request. The camera replies with an XML challenge containing a random . The client computes uppercase MD5 digests of username + nonce and password + nonce (truncated to 31 characters) and submits the authenticated login frame. Once authenticated, payload bodies are encrypted using AES-128-CFB (or XOR stream cipher depending on message class) keyed from the session nonce. Complete Baichuan Command IDs Used by cam.drheck.dev: cmd_id = 80 ( GetDevInfo): Model ( RLC-811A), item number ( P430), firmware version, serial number. cmd_id = 37 / 36 ( GetNetPort / SetNetPort): Inspects and enables rtsp ( 554/tcp), onvif ( 8000/tcp), rtmp ( 1935/tcp), http ( 80/tcp), and https ( 443/tcp). cmd_id = 76 / 75 ( GetLocalLink / SetLocalLink): Reads or writes DHCP vs. static IPv4 settings and MAC address. cmd_id = 182 ( Snap): Captures an immediate hardware-encoded JPEG frame ( main 4K or sub 640x360) directly over the control socket in ~110 ms. cmd_id = 56 / 57 ( GetEnc / SetEnc): Reads and updates H.265/H.264 resolution, frame rate ( frame), target bitrate ( bitRate in kbps), and audio track embedding ( ) for mainStream and subStream. cmd_id = 26 / 25 ( GetImage / SetImage): Reads and updates ISP sensor parameters ( bright, contrast, saturation, hue, sharpen, DayNight/mode auto|color|black&white, nr3d, mirror, flip). cmd_id = 44 / 45 ( GetOsd / SetOsd): Reads and updates On-Screen Display overlays, including the Reolink logo watermark ( 0|1), camera name overlay, and timestamp overlay. cmd_id = 288 ( SetWhiteLed manual) & cmd_id = 289 / 290 ( FloodlightTask): Controls manual spotlight toggle ( 0|1), brightness ( 1..100), automatic lighting mode ( 0 Off/Manual, 1 Smart Night AI Trigger, 3 Night Schedule), duration ( 60..600s), and AI trigger classes ( people,vehicle,dog_cat). cmd_id = 208 / 209 ( LedState): Controls Infrared Night Vision LEDs ( auto|close) and the front power status LED ( open|close). cmd_id = 263 ( AudioAlarmPlay) & cmd_id = 232 / 231 ( GetAudioAlarm / SetAudioAlarm): Triggers manual 1x siren or configures automatic siren on AI/motion alarm ( 0|1, disabled 0 by default). cmd_id = 264 / 265 ( GetAudioCfg / SetAudioCfg) & cmd_id = 439 / 440 ( GetAudioNoise / SetAudioNoise): Controls speaker volume ( 0..100) and microphone 3D AI noise reduction ( level 0..3). cmd_id = 574 / 575 ( get_privacy_mode / set_privacy_mode) & cmd_id = 52 / 53 ( GetMask / SetMask): Toggles hardware Privacy / Sleep mode ( 0|1) and hardware privacy masks ( 0|1). cmd_id = 295 ( StartZoomFocus), cmd_id = 445 ( Set3DPos), & cmd_id = 224 / 225 ( GetAutoFocus / SetAutoFocus): Steps the 5X motorized varifocal lens ( ZoomPos 0..28, FocusPos 0..238), executes 3D area click-to-zoom ( posX, posY, posWidth, posHeight in 0..1000 normalized coordinates), and locks/unlocks autofocus ( disable 0|1). cmd_id = 342 / 343 ( GetAiAlarm / SetAiAlarm) & cmd_id = 46 / 47 ( GetMdAlarm / SetMdAlarm): Configures per-class on-camera AI sensitivity ( 0..100) and stay-time ( 0..8s) for people, vehicle, dog_cat, face, plus general motion sensitivity ( 1..50). cmd_id = 38 / 39 ( GetNtp / SetNtp), cmd_id = 104 / 105 ( SystemGeneral), cmd_id = 106 / 107 ( Dst), & cmd_id = 23 ( reboot): Configures NTP synchronization ( time.google.com:123), US Daylight Saving Time, EDT/EST clock sync, and device reboot. 3. RTSP Stream Endpoints & ONVIF Two-Way Audio Backchannel ( 554/tcp) Once rtspEnable = 1 is set via Baichuan cmd_id = 36, each camera serves two RTSP streams plus an ONVIF two-way audio backchannel track: Sub Stream (Low-Latency H.264 + AAC Audio + PCMU Backchannel): rtsp://admin:@10.0.0.122:554/h264Preview_01_sub rtsp://admin:@10.0.0.123:554/h264Preview_01_sub track1: H.264 High Profile ( yuv420p, 640x360, default 10 fps at 256 kbps, GOP = 4, recvonly). track2: MPEG4-GENERIC AAC-hbr ( 16 kHz mono audio, recvonly). track3 (when negotiated with Require: www.onvif.org/ver20/backchannel): G.711 PCMU ( PCMU/8000, payload type 0, sendonly) for transmitting two-way voice audio directly to the camera's built-in speaker. Main Stream (4K UHD H.265/HEVC): rtsp://admin:@10.0.0.122:554/h265Preview_01_main rtsp://admin:@10.0.0.123:554/h265Preview_01_main Encoded as HEVC / H.265 ( yuvj420p, 3840x2160, default 25 fps at 6144 kbps, GOP = 2) with 16 kHz mono AAC audio. Architecture of cam.drheck.dev The web service on host ul ( /data/docker/cam) bridges the isolated IPv4 camera LAN ( 10.0.0.0/24) to an authenticated, browser-compatible HTTPS service at https://cam.drheck.dev. Component Configuration on Host ul Service Directory /data/docker/cam ( app.py, static/index.html, static/tv.html, tests/app_test.py) Persistent State & Models /data/docker/cam/data/cameras.json, /data/docker/cam/data/yolov8n.onnx ( 13 MB), /data/docker/cam/data/events/ ( events.json + .jpg) Container Name cam ( cam:latest, Python 3.12 + FastAPI + reolink-aio + onnxruntime + Pillow + numpy + espeak-ng + FFmpeg 7.1) ULA IPv6 Binding [fd77:7777:5010:0:1337:f1ac:d00d:ca30]:8000 on eth77 Nginx Reverse Proxy /etc/nginx/sites-available/cam ( X-Accel-Buffering: no, proxy_buffering off, X-Authentik-Groups forwarding) Authentik SSO & Group ProxyProvider ( cam-provider, ForwardAuth) -> Application ( cam) bound to Group ( camera_access) Backup & Restore /home/luke/git/backups/ul/scripts/backup/cam & /home/luke/git/backups/ul/scripts/restore/cam ( .tar.xz + par2 -r10) Key Subsystems Implemented in app.py Zero-Config Discovery ( discover_cameras): Reads the host kernel ARP table ( /proc/net/arp mounted read-only at /host_proc_arp), matches Reolink OUIs ( ec:71:db, 9c:8e:cd), queries all Baichuan settings ( cmd_id 80, 37, 76, 56, 26, 264, 44, 289, 208, 232, 439, 574, 52, 224, 38, 46, 342), and auto-enables RTSP ( 554/tcp) and audio encoding ( ). Motion & YOLOv8n AI Event Capture + Web-Viewable Timeline ( event_monitor_loop, record_camera_event): A background monitor coroutine ( event_monitor_loop) samples sub-stream snapshots from online, non-sleeping cameras every 3.5 seconds, computing downscaled 160x90 grayscale pixel frame-differences ( compute_frame_motion). Whenever motion ( >= 2.2% of frame pixels) or a manual capture ( POST /api/cameras/{ip}/capture_event) occurs, classify_snapshot_yolo runs the 80-class COCO YOLOv8n model ( yolov8n.onnx via onnxruntime, ~62 ms CPU inference on letterboxed 640x640 input with IoU 0.45 Non-Maximum Suppression). Clean Unannotated Snapshots + Text Metadata: The raw JPEG snapshot is saved without drawn bounding boxes to /data/docker/cam/data/events/.jpg, while the detected class labels, confidence percentages ( confidence_pct), normalized target coordinates ( box_norm), trigger types ( people, vehicle, dog_cat, motion, manual), frame motion percentage, and EDT/ EST timestamp ( format_edt_timestamp) are recorded in /data/docker/cam/data/events/events.json and displayed in the Detection Event Timeline & Metadata Log on https://cam.drheck.dev/. Optional Auto-Zoom on Moving Objects ( apply_auto_zoom_on_box): Each camera has an optional Auto-Zoom on Moving Objects toggle ( auto_zoom_motion, off by default). When enabled, detecting a moving person/object or motion region ( [x, y, w, h] in 0..1000 normalized coordinates) automatically issues Baichuan cmd_id = 445 ( Set3DPos set_ptz_3d_zoom) to zoom the 5X motorized lens onto the moving target, marks the timeline event with an Auto-Zoomed badge, and restores the lens to baseline_zoom after 20 seconds of inactivity. Two-Way Audio Talk ( POST /api/cameras/{ip}/talk): Supports both Push-to-Talk (Browser Microphone) (recording audio/webm via MediaRecorder in the browser) and Speak Text (TTS) (synthesizing speech via espeak-ng --stdout). transcode_to_mulaw converts the audio stream via ffmpeg -i pipe:0 -ar 8000 -ac 1 -f mulaw pipe:1 into 8 kHz G.711 mu-law ( PCMU/8000), and stream_rtsp_backchannel_mulaw negotiates an RTSP Digest session on 554/tcp with Require: www.onvif.org/ver20/backchannel, sets up track3 ( Transport: RTP/AVP/TCP;unicast;interleaved=0-1), and transmits 160-byte ( 20 ms) RTP packets directly to the camera's speaker. Static DHCP Reservations on danknasty & IPv6 Support 1. Static DHCP Reservations ( /etc/dhcpd.conf & ~/git/router_config/dhcpd.conf) Both cameras have permanent static DHCP leases configured in /etc/dhcpd.conf (and synced to ~/git/router_config/dhcpd.conf) on danknasty: host cam1 { # RLC-811A (141484731968753) hardware ethernet ec:71:db:f1:25:5a; fixed-address 10.0.0.122; } host cam2 { # RLC-811A (141484731989233) hardware ethernet ec:71:db:6d:84:ce; fixed-address 10.0.0.123; } 2. IPv6 Support Camera Hardware ( RLC-811A Firmware v3.1.0.4695_2504301440): No native IPv6 stack on the camera SoC ( 10.0.0.0/24 IPv4 only). Service Frontend ( cam.drheck.dev): Full dual-stack IPv4 and IPv6 support via Nginx -> [fd77:7777:5010:0:1337:f1ac:d00d:ca30]:8000. Complete Camera Controls & Settings Matrix All settings are available interactively in https://cam.drheck.dev/ or via POST /api/cameras/{ip}/control: Category Setting Supported Range / Values Default on ul Baichuan cmd_id Web UI / API Action Events & AI Auto Event Capture to Timeline true / false true (Enabled) Local + 182 Auto Event Capture ( action: "auto_zoom_config") Events & AI Manual Event Capture & Classify Captures JPEG + YOLOv8n text metadata On-demand 182 + ONNX Capture Event ( POST /api/cameras/{ip}/capture_event) Events & AI Person / Vehicle / Pet AI Sensitivity 0 .. 100 (stayTime 0..8s) 60 342 / 343 ( SetAiAlarm) Person / Vehicle / Pet AI Sensitivity ( action: "ai_sensitivity") Events & AI Motion Detection Sensitivity 1 .. 50 10 46 / 47 ( SetMdAlarm) Motion Sensitivity ( action: "ai_sensitivity") Optics & PTZ Optical Zoom ( ZoomPos) 0 .. 28 ( 1X .. 5X optical) 0 295 ( StartZoomFocus) Zoom slider ( action: "zoom") Optics & PTZ Optical Focus ( FocusPos) 0 .. 238 Auto 295 ( StartZoomFocus) Focus slider ( action: "focus") Optics & PTZ 3D Click-to-Zoom ( Set3DPos) posX, posY, posWidth, posHeight ( 0..1000) Interactive 445 ( set_ptz_3d_zoom) 3D Click-Zoom button ( action: "zoom_3d") Optics & PTZ Auto-Zoom on Moving Objects false (Off) or true (On) + baseline_zoom false (Off) 445 + 295 Auto-Zoom on Moving Objects ( action: "auto_zoom_config") Optics & PTZ Autofocus Lock false (Auto) or true (Locked) false (Auto) 224 / 225 ( SetAutoFocus) Autofocus Lock ( action: "autofocus") Lighting Floodlight Manual Toggle & Brightness `state: true false , brightness: 1..100` Off, 85% 288 ( SetWhiteLed) Lighting Floodlight Auto Behavior ( FloodlightTask) Mode 0 (Manual), 1 (Smart Night AI), 3 (Schedule); Duration 60..600s; Triggers people,vehicle,dog_cat Mode 1, 180s 289 / 290 ( FloodlightTask) Spotlight Automatic Mode / Triggers / Duration ( action: "floodlight_config") Lighting IR Night Vision LEDs auto (Auto Night IR) or close (Off) auto 208 / 209 ( LedState) IR Night Vision LEDs ( action: "leds") Lighting Front Status Power LED open (On) or close (Off / Stealth) open 208 / 209 ( LedState) Front Status Power LED ( action: "leds") Lighting Day / Night Sensor Mode auto, color (24/7 Color), black&white auto 26 / 25 ( SetImage) Day / Night Sensor Mode ( action: "image") Deterrents & Audio Auto-Siren on Detection false (Off) or true (On) false (Off) 232 / 231 ( SetAudioAlarm) Auto-Siren on Detection ( action: "audio_alarm") Deterrents & Audio Manual Security Siren Trigger 1x Off 263 ( AudioAlarmPlay) Siren (1x) ( action: "siren") Deterrents & Audio Live Microphone Audio Stream 16 kHz AAC -> 64 kbps MP3 Enabled 57 + RTSP Audio: Muted / LIVE ( GET /api/cameras/{ip}/audio.mp3) Deterrents & Audio Two-Way Audio Talk (Mic & TTS) Browser MediaRecorder or espeak-ng -> 8 kHz G.711 PCMU On-demand RTSP track3 ( 554) Push-to-Talk (Mic) & Speak Text ( POST /api/cameras/{ip}/talk) Deterrents & Audio Mic 3D Noise Reduction Level 0 (Off), 1 (Low), 2 (Med), 3 (High) 3 (High) 439 / 440 ( SetAudioNoise) Mic 3D Noise Reduction ( action: "audio_noise") Deterrents & Audio Speaker Volume 0 .. 100 ( %) 92 265 ( SetAudioCfg) Speaker Volume ( action: "volume") Privacy Privacy / Sleep Mode false (Awake) or true (Sleeping) false (Awake) 574 / 575 ( set_privacy_mode) Privacy Sleep button ( action: "privacy_mode") Privacy Hardware Privacy Mask ( Shelter) false (Off) or true (On) false (Off) 52 / 53 ( SetMask) Hardware Privacy Mask ( action: "privacy_mask") Image & OSD Mounting / Orientation ( mirror, flip) Normal, 180° Upside-Down, Flip, Mirror Normal 25 ( SetImage) Flip 180° button ( action: "image") Image & OSD Reolink Logo Watermark false (Hidden) or true (Visible) false (Hidden) 45 ( SetOsd) Reolink Logo Watermark ( action: "osd") Time & System NTP Server & Clock Sync time.google.com:123 ( EDT/ EST) time.google.com 38 / 39 ( SetNtp) & 105 Set time.google.com & Sync EDT Clock ( action: "ntp", action: "sync_time") Time & System Reboot Camera Hardware reboot On-demand 23 ( reboot) Reboot Camera ( action: "reboot") Bandwidth Adjustments for Unreliable or Slow Internet When viewing two cameras simultaneously over a slow, high-latency, or lossy internet connection, total downstream bandwidth for $N$ cameras is governed by: $$B_{\text{total}} = N \times f_{\text{fps}} \times S_{\text{frame}}(W, H, q) \times 8 \quad \text{bits/sec}$$ where $f_{\text{fps}}$ is the frame rate, $W \times H$ is the scaled resolution, and $q \in [2, 24]$ is the FFmpeg MJPEG quantization factor ( -q:v). Preset Mode Resolution Frame Rate JPEG q Avg Frame Size Per-Camera Bitrate 2-Camera Total WAN Bitrate Best For HD Main Stream 1280x720 10 fps 5 ~25 KB ~2.0 Mbps ~4.0 Mbps Fast fiber / LAN full-screen inspection Standard Live (Default) 640x360 10 fps 5 ~6.2 KB ~500 kbps ~1.0 Mbps Normal broadband / Wi-Fi Low Bandwidth 480x270 5 fps 10 ~4.0 KB ~160 kbps ~320 kbps Congested Wi-Fi / mobile hotspot Ultra-Low WAN 320x180 2 fps 15 ~3.1 KB ~50 kbps ~100 kbps Throttled cellular / international roaming Unreliable WAN Snapshot (2s) 640x360 0.5 fps ( 1 / 2s) Native ~9.0 KB ~36 kbps ~72 kbps High packet loss / TCP reset prone links Minimal WAN Snapshot (5s) 640x360 0.2 fps ( 1 / 5s) Native ~9.0 KB ~14 kbps ~28 kbps Extreme low-speed satellite / 2G fallback Authentik Access Control ( camera_access Group) & Google TV App Authorized Group ( camera_access): luke, ikura, haruka. Enforced at both the Nginx ForwardAuth edge ( PolicyBinding on cam) and inside check_camera_access_headers() in app.py. Google TV Sideloadable App ( dev.drheck.cam): Built APK on ul: /data/docker/cam/googletv_src/cam-googletv.apk 10-Foot TV Interface: https://cam.drheck.dev/tv (authenticated automatically via baked-in 256-bit TV_AUTH_TOKEN).