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://<ip>: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 bycmd_id(uint32), payload length (uint32),channel_id(uint8), status code (200OK,400Bad Request), and payload offset. - Modern Nonce Authentication (
cmd_id = 1):- The client sends an initial unauthenticated
cmd_id = 1request. - The camera replies with an XML
<Encryption>challenge containing a random<nonce>. - The client computes uppercase MD5 digests of
username + nonceandpassword + 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.
- The client sends an initial unauthenticated
- 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 enablesrtsp(554/tcp),onvif(8000/tcp),rtmp(1935/tcp),http(80/tcp), andhttps(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 (main4K orsub640x360) 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 (bitRatein kbps), and audio track embedding (<audio>1</audio>) formainStreamandsubStream.cmd_id = 26/25(GetImage/SetImage): Reads and updates ISP sensor parameters (bright,contrast,saturation,hue,sharpen,DayNight/modeauto|color|black&white,nr3d,mirror,flip).cmd_id = 44/45(GetOsd/SetOsd): Reads and updates On-Screen Display overlays, including the Reolink logo watermark (<OsdChannelName><enWatermark>0|1</enWatermark></OsdChannelName>), camera name overlay, and timestamp overlay.cmd_id = 288(SetWhiteLedmanual) &cmd_id = 289/290(FloodlightTask): Controls manual spotlight toggle (0|1), brightness (1..100), automatic lighting mode (0Off/Manual,1Smart Night AI Trigger,3Night Schedule), duration (60..600s), and AI trigger classes (people,vehicle,dog_cat).cmd_id = 208/209(LedState): Controls Infrared Night Vision LEDs (<state>auto|close</state>) and the front power status LED (<lightState>open|close</lightState>).cmd_id = 263(AudioAlarmPlay) &cmd_id = 232/231(GetAudioAlarm/SetAudioAlarm): Triggers manual 1x siren or configures automatic siren on AI/motion alarm (<AudioTask><enable>0|1</enable></AudioTask>, disabled0by 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 (<sleepState><sleep>0|1</sleep></sleepState>) and hardware privacy masks (<Shelter><enable>0|1</enable></Shelter>).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,posHeightin0..1000normalized 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) forpeople,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:<password>@10.0.0.122:554/h264Preview_01_sub rtsp://admin:<password>@10.0.0.123:554/h264Preview_01_subtrack1: H.264 High Profile (yuv420p,640x360, default10 fpsat256 kbps, GOP =4,recvonly).track2: MPEG4-GENERIC AAC-hbr (16 kHzmono audio,recvonly).track3(when negotiated withRequire: www.onvif.org/ver20/backchannel): G.711 PCMU (PCMU/8000, payload type0,sendonly) for transmitting two-way voice audio directly to the camera's built-in speaker.
- Main Stream (4K UHD H.265/HEVC):
Encoded as HEVC / H.265 (rtsp://admin:<password>@10.0.0.122:554/h265Preview_01_main rtsp://admin:<password>@10.0.0.123:554/h265Preview_01_mainyuvj420p,3840x2160, default25 fpsat6144 kbps, GOP =2) with16 kHzmono 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 + <event_id>.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/arpmounted read-only at/host_proc_arp), matches Reolink OUIs (ec:71:db,9c:8e:cd), queries all Baichuan settings (cmd_id80,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 (<audio>1</audio>).
- Reads the host kernel ARP table (
- 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 every3.5 seconds, computing downscaled160x90grayscale 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_yoloruns the 80-class COCO YOLOv8n model (yolov8n.onnxviaonnxruntime,~62 msCPU inference on letterboxed640x640input with IoU0.45Non-Maximum Suppression). - Clean Unannotated Snapshots + Text Metadata: The raw JPEG snapshot is saved without drawn bounding boxes to
/data/docker/cam/data/events/<event_id>.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, andEDT/ESTtimestamp (format_edt_timestamp) are recorded in/data/docker/cam/data/events/events.jsonand displayed in the Detection Event Timeline & Metadata Log onhttps://cam.drheck.dev/.
- A background monitor coroutine (
- 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]in0..1000normalized coordinates) automatically issues Baichuancmd_id = 445(Set3DPosset_ptz_3d_zoom) to zoom the 5X motorized lens onto the moving target, marks the timeline event with anAuto-Zoomedbadge, and restores the lens tobaseline_zoomafter20 secondsof inactivity.
- Each camera has an optional Auto-Zoom on Moving Objects toggle (
- Two-Way Audio Talk (
POST /api/cameras/{ip}/talk):- Supports both Push-to-Talk (Browser Microphone) (recording
audio/webmviaMediaRecorderin the browser) and Speak Text (TTS) (synthesizing speech viaespeak-ng --stdout). transcode_to_mulawconverts the audio stream viaffmpeg -i pipe:0 -ar 8000 -ac 1 -f mulaw pipe:1into8 kHzG.711 mu-law (PCMU/8000), andstream_rtsp_backchannel_mulawnegotiates an RTSP Digest session on554/tcpwithRequire: www.onvif.org/ver20/backchannel, sets uptrack3(Transport: RTP/AVP/TCP;unicast;interleaved=0-1), and transmits160-byte(20 ms) RTP packets directly to the camera's speaker.
- Supports both Push-to-Talk (Browser Microphone) (recording
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-811AFirmwarev3.1.0.4695_2504301440): No native IPv6 stack on the camera SoC (10.0.0.0/24IPv4 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 |
No comments to display
No comments to display