@apocaliss92/nodelink-js 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -603
- package/dist/{DiagnosticsTools-XIIYZDXL.js → DiagnosticsTools-55PR4WFD.js} +2 -2
- package/dist/{chunk-DUHWTZ7U.js → chunk-DEOMUWBN.js} +2 -2
- package/dist/chunk-DEOMUWBN.js.map +1 -0
- package/dist/{chunk-SDRNJQ5U.js → chunk-UHFJPQA4.js} +116 -52
- package/dist/chunk-UHFJPQA4.js.map +1 -0
- package/dist/cli/rtsp-server.cjs +113 -49
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.js +2 -2
- package/dist/index.cjs +113 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -9
- package/dist/index.d.ts +66 -7
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-DUHWTZ7U.js.map +0 -1
- package/dist/chunk-SDRNJQ5U.js.map +0 -1
- /package/dist/{DiagnosticsTools-XIIYZDXL.js.map → DiagnosticsTools-55PR4WFD.js.map} +0 -0
package/README.md
CHANGED
|
@@ -1,418 +1,23 @@
|
|
|
1
|
-
<table>
|
|
2
|
-
<tr>
|
|
3
|
-
<td><img src="app/client/public/icon-512x512.png" alt="nodelink.js" width="256" height="256"></td>
|
|
4
|
-
<td>
|
|
5
|
-
<h1>nodelink.js</h1>
|
|
6
|
-
<p>A TypeScript library for interacting with Reolink IP cameras and NVRs using the proprietary Baichuan protocol and CGI API.</p>
|
|
7
|
-
</td>
|
|
8
|
-
</tr>
|
|
9
|
-
</table>
|
|
10
|
-
|
|
11
|
-
## Credits
|
|
12
|
-
|
|
13
|
-
This library is inspired by and based on the reverse engineering work done by:
|
|
14
|
-
|
|
15
|
-
- **[neolink](https://github.com/thirtythreeforty/neolink)** - Rust implementation of Baichuan protocol
|
|
16
|
-
- **[reolink_aio](https://github.com/starkillerOG/reolink_aio)** - Python async library for Reolink cameras
|
|
17
|
-
|
|
18
|
-
## Features
|
|
19
|
-
|
|
20
|
-
- 🔌 **Baichuan Native Protocol** - Direct binary protocol for low-level camera control
|
|
21
|
-
- 🌐 **CGI HTTP API** - RESTful API for camera configuration and management
|
|
22
|
-
- 📺 **RTSP Server** - Stream camera feeds via standard RTSP protocol
|
|
23
|
-
- 📡 **RFC 4571 Server** - Low-latency TCP streaming for home automation integrations
|
|
24
|
-
- 🎤 **Two-way Audio (Intercom)** - Full duplex audio communication
|
|
25
|
-
- 📹 **Video Clips & Recordings** - Download and manage recorded footage
|
|
26
|
-
- 🔍 **Device Discovery** - Automatic camera detection via UDP broadcast
|
|
27
|
-
- 🎯 **PTZ Control** - Pan, Tilt, Zoom, and Preset management
|
|
28
|
-
- 🔔 **Motion & AI Events** - Real-time event notifications and subscriptions
|
|
29
|
-
- 📷 **Multifocal Support** - Composite streams for dual-lens cameras (TrackMix, Duo)
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## 🖥️ Manager UI (Web Dashboard)
|
|
34
|
-
|
|
35
|
-
The library includes a **complete web-based management interface** for easy camera configuration and streaming control without writing code.
|
|
36
|
-
|
|
37
1
|
<p align="center">
|
|
38
|
-
<
|
|
2
|
+
<img src="app/client/public/brand/logo-wide-light.svg" alt="Nodelink.js" width="420">
|
|
3
|
+
<br><br>
|
|
4
|
+
A TypeScript library for interacting with Reolink IP cameras and NVRs using the proprietary Baichuan protocol and CGI API. Includes a full-featured web-based Manager UI.
|
|
39
5
|
</p>
|
|
40
6
|
|
|
41
|
-
|
|
42
|
-
- 📡 **NVR / Hub Support** - Add NVRs as first-class entities, discover channels, and manage child cameras. All cameras on an NVR share a single connection (like Scrypted). Connect/disconnect at the NVR level; add or remove cameras at any time via channel discovery
|
|
43
|
-
- 🔋 **Battery Camera Support** - Cameras are auto-detected as battery-powered when they emit sleep/wake events. Per-camera battery mode setting: **Stream Only** (default — camera sleeps when no stream clients) or **Always On** (stays awake while connected). Live awake/sleeping badge on each camera card. Controls and stream discovery are paused while the camera sleeps to avoid unnecessary wake-ups
|
|
44
|
-
- 💡 **Camera Controls** - Toggle floodlight, siren, floodlight-on-motion, siren-on-motion, PTZ auto-tracking, and PIR sensor directly from the camera card. PTZ directional controls and preset navigation via a dedicated modal
|
|
45
|
-
- 📹 **Live Streaming via go2rtc** - WebRTC, MSE/MP4, HLS, RTSP, and snapshot output powered by an embedded go2rtc restreamer. Stream options are cached so battery cameras show available streams even while sleeping
|
|
46
|
-
- 🔔 **Real-time Events** - Per-camera event viewer with live SSE updates (motion, doorbell, people, vehicle, animal, face, package, day/night, sleep/wake). Events are broadcast via SSE, NDJSON stream, and MQTT
|
|
47
|
-
- 📊 **Real-time Logs** - Monitor camera events, system logs, and go2rtc process output
|
|
48
|
-
- ⚙️ **Settings** - Configure go2rtc ports, auto-start options, MQTT broker, and Home Assistant discovery
|
|
49
|
-
- 📱 **PWA Support** - Install as a Progressive Web App on mobile devices
|
|
50
|
-
- 🌐 **Responsive Design** - Works on desktop, tablet, and mobile
|
|
51
|
-
|
|
52
|
-
### External Requirements
|
|
53
|
-
|
|
54
|
-
To run the Manager UI outside Docker, you need:
|
|
55
|
-
|
|
56
|
-
Some features also rely on external binaries that must be available on the host when running outside Docker:
|
|
57
|
-
|
|
58
|
-
Install examples:
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
# macOS
|
|
62
|
-
brew install ffmpeg
|
|
63
|
-
|
|
64
|
-
# Debian/Ubuntu
|
|
65
|
-
sudo apt-get update && sudo apt-get install -y ffmpeg
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
If you use the Docker image, FFmpeg is already included (see Docker Deployment below).
|
|
69
|
-
|
|
70
|
-
### Quick Start (Development)
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
cd app
|
|
74
|
-
npm install
|
|
75
|
-
npm run dev
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Production Build
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
cd app
|
|
82
|
-
npm run build
|
|
83
|
-
npm start
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Open http://localhost:3000 in your browser.
|
|
87
|
-
|
|
88
|
-
### SSO (Authentik) via Trusted Proxy
|
|
89
|
-
|
|
90
|
-
See [documentation/authentik-nginx.md](documentation/authentik-nginx.md) for a step-by-step Authentik + NGINX setup and the required environment variables.
|
|
91
|
-
|
|
92
|
-
### Docker Deployment (Recommended)
|
|
93
|
-
|
|
94
|
-
The easiest way to run the Manager UI is with Docker:
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
# Using pre-built image
|
|
98
|
-
docker pull ghcr.io/apocaliss92/nodelink-js-manager:latest
|
|
99
|
-
|
|
100
|
-
docker run -d \
|
|
101
|
-
--name nodelink-manager \
|
|
102
|
-
--network host \
|
|
103
|
-
-v nodelink-data:/data \
|
|
104
|
-
ghcr.io/apocaliss92/nodelink-js-manager:latest
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Or with Docker Compose:
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
docker-compose up -d
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
#### WebRTC in Docker (bridge network)
|
|
114
|
-
|
|
115
|
-
If you run the container in **bridge** mode (i.e. with `ports:` mappings), WebRTC needs two things to work reliably:
|
|
116
|
-
|
|
117
|
-
1. **A fixed UDP port range** exposed from container → host.
|
|
118
|
-
2. ICE candidates that contain an address the browser can reach (usually your **host LAN IP**) — configured in **Settings → WebRTC (ICE)**.
|
|
119
|
-
|
|
120
|
-
Otherwise WebRTC may get stuck and you may see warnings like:
|
|
121
|
-
|
|
122
|
-
```text
|
|
123
|
-
Video data channel not open for session ...: connecting
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Recommended example:
|
|
127
|
-
|
|
128
|
-
```yaml
|
|
129
|
-
services:
|
|
130
|
-
nodelink-manager:
|
|
131
|
-
ports:
|
|
132
|
-
- "3000:3000" # Web UI and API
|
|
133
|
-
- "11984:11984" # go2rtc API + dashboard
|
|
134
|
-
- "18554:18554" # go2rtc RTSP output
|
|
135
|
-
- "18555:18555/udp" # go2rtc WebRTC ICE
|
|
136
|
-
# Then configure Settings → go2rtc:
|
|
137
|
-
# - ICE servers if needed for NAT traversal
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
Notes:
|
|
141
|
-
|
|
142
|
-
- The **Additional host addresses** setting should be an IP address that your browser can reach (typically the host machine IP on your LAN).
|
|
143
|
-
- If you use `network_mode: host`, you usually **don’t need** any of the above (no port mapping).
|
|
144
|
-
|
|
145
|
-
**Environment Variables:**
|
|
146
|
-
|
|
147
|
-
| Variable | Default | Description |
|
|
148
|
-
| --- | --- | --- |
|
|
149
|
-
| `PORT` | `3000` | HTTP server port |
|
|
150
|
-
| `DATA_PATH` | `/data` | Directory for settings.json and logs |
|
|
151
|
-
| `GO2RTC_PATH` | (auto) | Path to go2rtc binary (falls back to bundled `go2rtc-static`) |
|
|
152
|
-
| `GO2RTC_API_PORT` | `11984` | go2rtc REST API + web dashboard port |
|
|
153
|
-
| `GO2RTC_RTSP_PORT` | `18554` | go2rtc RTSP output port |
|
|
154
|
-
| `GO2RTC_WEBRTC_PORT` | `18555` | go2rtc WebRTC ICE port |
|
|
155
|
-
|
|
156
|
-
Environment variables override `settings.json` values. Ports are also configurable in Settings → go2rtc.
|
|
157
|
-
|
|
158
|
-
**WebRTC / ICE (Docker bridge mode):**
|
|
159
|
-
|
|
160
|
-
- Configure the UDP port mapping in Docker.
|
|
161
|
-
- Configure ICE options in **Settings → WebRTC (ICE)**.
|
|
162
|
-
|
|
163
|
-
**Dashboard authentication (optional):**
|
|
164
|
-
|
|
165
|
-
| Variable | Default | Description |
|
|
166
|
-
| ---------------- | ------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
167
|
-
| `AUTH_ENABLED` | (unset) | Enable auth when set to `1/true` (or disable with `0/false`). If unset, auth auto-enables when `ADMIN_PASSWORD` is set. |
|
|
168
|
-
| `ADMIN_PASSWORD` | (unset) | Sets the `admin` password. This credential works for both the web login form and HTTP Basic auth. |
|
|
169
|
-
|
|
170
|
-
### Streaming via go2rtc
|
|
171
|
-
|
|
172
|
-
All streaming is handled by an embedded **go2rtc** process (default API port `11984`, RTSP port `18554`). go2rtc provides:
|
|
173
|
-
|
|
174
|
-
| Format | URL | Notes |
|
|
175
|
-
|--------|-----|-------|
|
|
176
|
-
| **WebRTC** | `POST http://HOST:11984/api/webrtc?src={name}` | WHEP signaling (SDP offer/answer) |
|
|
177
|
-
| **MSE/MP4** | `http://HOST:11984/api/stream.mp4?src={name}` | Fragmented MP4 for browsers |
|
|
178
|
-
| **HLS** | `http://HOST:11984/api/stream.m3u8?src={name}` | Adaptive streaming |
|
|
179
|
-
| **RTSP** | `rtsp://HOST:18554/{name}` | For VLC, ffmpeg, NVR software |
|
|
180
|
-
| **Snapshot** | `http://HOST:11984/api/frame.jpeg?src={name}` | Single JPEG (requires ffmpeg) |
|
|
181
|
-
| **Dashboard** | `http://HOST:11984/` | go2rtc web UI |
|
|
182
|
-
|
|
183
|
-
Stream names follow the pattern `{sanitized_camera_name}_{profile}` (e.g. `studio_main`, `garage_sub`).
|
|
184
|
-
|
|
185
|
-
go2rtc has CORS enabled (`origin: "*"`) so browser-based players can connect directly.
|
|
186
|
-
|
|
187
|
-
### Authentication
|
|
188
|
-
|
|
189
|
-
When authentication is enabled (see `AUTH_ENABLED` / `ADMIN_PASSWORD`), the Manager API endpoints are protected. go2rtc streaming endpoints are currently unauthenticated (accessible on the local network).
|
|
190
|
-
|
|
191
|
-
- Manager API: `Authorization: Bearer <token>` header or session cookie
|
|
192
|
-
- WebSocket logs: `?token=...` in the WS URL
|
|
193
|
-
|
|
194
|
-
Examples:
|
|
7
|
+
## Components
|
|
195
8
|
|
|
196
|
-
|
|
197
|
-
# RTSP via go2rtc (no auth)
|
|
198
|
-
ffmpeg -rtsp_transport tcp -i “rtsp://HOST:18554/studio_main” -f null -
|
|
199
|
-
vlc “rtsp://HOST:18554/studio_main”
|
|
200
|
-
|
|
201
|
-
# WebRTC WHEP signaling
|
|
202
|
-
curl -X POST “http://HOST:11984/api/webrtc?src=studio_main” \
|
|
203
|
-
-H “Content-Type: application/sdp” \
|
|
204
|
-
--data-binary @offer.sdp
|
|
205
|
-
|
|
206
|
-
# Snapshot
|
|
207
|
-
curl -o snap.jpg “http://HOST:11984/api/frame.jpeg?src=studio_main”
|
|
208
|
-
|
|
209
|
-
# WebSocket logs (auth)
|
|
210
|
-
ws://HOST:3000/ws/logs?token=YOUR_TOKEN
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
If authentication is disabled, these endpoints work without credentials.
|
|
214
|
-
|
|
215
|
-
Tip: a personal token is ideal for integrations (Home Assistant, scripts, etc.) because it does not expire.
|
|
216
|
-
|
|
217
|
-
📖 **[Full Docker documentation →](./DOCKER.md)**
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## Manager REST API
|
|
222
|
-
|
|
223
|
-
The Manager UI exposes a REST API for integrations, scripts, and third-party apps. Key endpoints:
|
|
224
|
-
|
|
225
|
-
| Category | Endpoints |
|
|
226
|
-
|----------|-----------|
|
|
227
|
-
| **Auth** | `GET /api/auth/config`, `POST /api/auth/login`, `POST /api/auth/personal-token` |
|
|
228
|
-
| **go2rtc Streaming** | Served directly by go2rtc (default port `11984`): WebRTC, MSE/MP4, HLS, RTSP, Snapshot |
|
|
229
|
-
| **go2rtc Management** | tRPC: `go2rtc.start`, `go2rtc.stop`, `go2rtc.status`, `go2rtc.listStreams` |
|
|
230
|
-
| **Events** | `GET /api/events/sse` (SSE), `GET /api/events/stream` (NDJSON), `GET /api/events/status` |
|
|
231
|
-
| **System** | `GET /api/health`, `GET /api/metrics`, `GET /api/updates` |
|
|
232
|
-
|
|
233
|
-
**Streaming** — All video output (WebRTC, MSE, HLS, RTSP, snapshots) is handled by an embedded go2rtc restreamer. The Manager creates internal RTSP servers per stream and registers them with go2rtc, which provides multi-format output with audio support.
|
|
234
|
-
|
|
235
|
-
**Events** — Real-time camera events (motion, doorbell, people, vehicle, etc.) via Server-Sent Events or NDJSON stream. When MQTT is configured, events are also published to the broker.
|
|
236
|
-
|
|
237
|
-
📖 **[Full Manager API documentation →](./documentation/manager-api.md)**
|
|
238
|
-
|
|
239
|
-
---
|
|
9
|
+
### [Manager UI (Web Dashboard)](./app/README.md)
|
|
240
10
|
|
|
241
|
-
|
|
11
|
+
A complete web-based management interface for camera configuration and live streaming — no code required. Docker deployment, go2rtc restreamer, real-time events, MQTT, Home Assistant integration.
|
|
242
12
|
|
|
243
|
-
|
|
13
|
+
### [Library (`@apocaliss92/nodelink-js`)](./documentation/baichuan-api/README.md)
|
|
244
14
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
| Section | Description |
|
|
248
|
-
| ---------------------------------------------------------- | ----------------------------------------------- |
|
|
249
|
-
| [**Overview**](./documentation/baichuan-api/README.md) | API overview and quick start |
|
|
250
|
-
| [Connection](./documentation/baichuan-api/connection.md) | Login, logout, ping, reboot, dedicated sessions |
|
|
251
|
-
| [Device Info](./documentation/baichuan-api/device-info.md) | Device information, channels, capabilities |
|
|
252
|
-
| [Streaming](./documentation/baichuan-api/streaming.md) | Live video streams, codec configuration |
|
|
253
|
-
| [Recordings](./documentation/baichuan-api/recordings.md) | Search, download, replay recorded clips |
|
|
254
|
-
| [PTZ Control](./documentation/baichuan-api/ptz.md) | Pan, tilt, zoom, presets |
|
|
255
|
-
| [Events](./documentation/baichuan-api/events.md) | Motion, AI, doorbell event subscriptions |
|
|
256
|
-
| [Intercom](./documentation/baichuan-api/intercom.md) | Two-way audio, talk sessions |
|
|
257
|
-
| [Snapshots](./documentation/baichuan-api/snapshots.md) | Capture images, thumbnails |
|
|
258
|
-
| [Detection](./documentation/baichuan-api/detection.md) | Motion, AI, PIR, autotracking settings |
|
|
259
|
-
| [Lights & Chime](./documentation/baichuan-api/lights.md) | Spotlight, floodlight, siren, chime/DingDong |
|
|
260
|
-
| [Battery](./documentation/baichuan-api/battery.md) | Battery status, sleep/wake management |
|
|
261
|
-
| [OSD](./documentation/baichuan-api/osd.md) | On-screen display configuration |
|
|
262
|
-
| [Network](./documentation/baichuan-api/network.md) | Network, WiFi, storage, system settings |
|
|
263
|
-
|
|
264
|
-
### CGI HTTP API
|
|
265
|
-
|
|
266
|
-
| Section | Description |
|
|
267
|
-
| ---------------------------------------------------------- | ----------------------------------- |
|
|
268
|
-
| [**CGI API Reference**](./documentation/cgi-api/README.md) | Complete HTTP/CGI API documentation |
|
|
269
|
-
|
|
270
|
-
### Additional Features
|
|
271
|
-
|
|
272
|
-
| Section | Description |
|
|
273
|
-
| ------------------------------------------------- | ------------------------------------- |
|
|
274
|
-
| [**Manager REST API**](./documentation/manager-api.md) | HTTP API for auth, streaming, events, metrics |
|
|
275
|
-
| [Streaming Servers](./documentation/streaming.md) | RTSP, RFC4571, HTTP streaming servers |
|
|
276
|
-
| [Network Discovery](./documentation/discovery.md) | Automatic camera discovery via UDP |
|
|
277
|
-
|
|
278
|
-
---
|
|
279
|
-
|
|
280
|
-
## Installation
|
|
15
|
+
TypeScript library implementing the Reolink Baichuan binary protocol (port 9000) for direct camera/NVR communication. Streaming, events, PTZ, intercom, recordings, battery cameras, multifocal support.
|
|
281
16
|
|
|
282
17
|
```bash
|
|
283
18
|
npm install @apocaliss92/nodelink-js
|
|
284
19
|
```
|
|
285
20
|
|
|
286
|
-
## Quick Start
|
|
287
|
-
|
|
288
|
-
### Baichuan Native API
|
|
289
|
-
|
|
290
|
-
The Baichuan API provides direct access to camera functions through the proprietary binary protocol:
|
|
291
|
-
|
|
292
|
-
```typescript
|
|
293
|
-
import { ReolinkBaichuanApi } from "@apocaliss92/nodelink-js";
|
|
294
|
-
|
|
295
|
-
const api = new ReolinkBaichuanApi({
|
|
296
|
-
host: "192.168.1.100",
|
|
297
|
-
port: 9000, // Baichuan port
|
|
298
|
-
username: "admin",
|
|
299
|
-
password: "your-password",
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
await api.login();
|
|
303
|
-
|
|
304
|
-
// Get device info
|
|
305
|
-
const deviceInfo = await api.getDeviceInfo();
|
|
306
|
-
console.log("Camera:", deviceInfo.name, deviceInfo.model);
|
|
307
|
-
|
|
308
|
-
// Get stream info
|
|
309
|
-
const streamInfo = await api.getStreamInfoList();
|
|
310
|
-
|
|
311
|
-
// Subscribe to events
|
|
312
|
-
api.onMotionAlarm((event) => {
|
|
313
|
-
console.log("Motion detected:", event);
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
await api.close();
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
📖 **[View full Baichuan API documentation →](./documentation/baichuan-api/README.md)**
|
|
320
|
-
|
|
321
|
-
### CGI HTTP API
|
|
322
|
-
|
|
323
|
-
The CGI API provides HTTP-based access for configuration and management:
|
|
324
|
-
|
|
325
|
-
```typescript
|
|
326
|
-
import { ReolinkCgiApi } from "@apocaliss92/nodelink-js";
|
|
327
|
-
|
|
328
|
-
const cgi = new ReolinkCgiApi({
|
|
329
|
-
host: "192.168.1.100",
|
|
330
|
-
port: 80, // HTTP port
|
|
331
|
-
username: "admin",
|
|
332
|
-
password: "your-password",
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
// Get device info
|
|
336
|
-
const info = await cgi.getDevInfo();
|
|
337
|
-
|
|
338
|
-
// Get recording files
|
|
339
|
-
const recordings = await cgi.searchRecordings({
|
|
340
|
-
startTime: new Date("2024-01-01"),
|
|
341
|
-
endTime: new Date("2024-01-02"),
|
|
342
|
-
channel: 0,
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
// Get encoding settings
|
|
346
|
-
const enc = await cgi.getEnc(0);
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
📖 **[View full CGI API documentation →](./documentation/cgi-api/README.md)**
|
|
350
|
-
|
|
351
|
-
## Streaming
|
|
352
|
-
|
|
353
|
-
### RTSP Server
|
|
354
|
-
|
|
355
|
-
Create a local RTSP server that restreams camera feeds:
|
|
356
|
-
|
|
357
|
-
```typescript
|
|
358
|
-
import {
|
|
359
|
-
BaichuanRtspServer,
|
|
360
|
-
ReolinkBaichuanApi,
|
|
361
|
-
} from "@apocaliss92/nodelink-js";
|
|
362
|
-
|
|
363
|
-
const api = new ReolinkBaichuanApi({
|
|
364
|
-
host: "192.168.1.100",
|
|
365
|
-
port: 9000,
|
|
366
|
-
username: "admin",
|
|
367
|
-
password: "your-password",
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
const rtspServer = new BaichuanRtspServer({
|
|
371
|
-
api,
|
|
372
|
-
profile: "main", // main, sub, or ext
|
|
373
|
-
channel: 0,
|
|
374
|
-
port: 8554,
|
|
375
|
-
logger: console,
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
await rtspServer.start();
|
|
379
|
-
// Stream available at rtsp://localhost:8554/stream
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
### RFC 4571 Server
|
|
383
|
-
|
|
384
|
-
Low-latency TCP streaming optimized for home automation systems like Scrypted:
|
|
385
|
-
|
|
386
|
-
```typescript
|
|
387
|
-
import {
|
|
388
|
-
createRfc4571TcpServer,
|
|
389
|
-
ReolinkBaichuanApi,
|
|
390
|
-
} from "@apocaliss92/nodelink-js";
|
|
391
|
-
|
|
392
|
-
const api = new ReolinkBaichuanApi({
|
|
393
|
-
host: "192.168.1.100",
|
|
394
|
-
port: 9000,
|
|
395
|
-
username: "admin",
|
|
396
|
-
password: "your-password",
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
const server = await createRfc4571TcpServer({
|
|
400
|
-
api,
|
|
401
|
-
profile: "main",
|
|
402
|
-
channel: 0,
|
|
403
|
-
host: "0.0.0.0",
|
|
404
|
-
logger: console,
|
|
405
|
-
username: "admin",
|
|
406
|
-
password: "your-password",
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
// Connect your home automation system to the server
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
## Two-Way Audio (Intercom)
|
|
413
|
-
|
|
414
|
-
Send and receive audio for intercom functionality:
|
|
415
|
-
|
|
416
21
|
```typescript
|
|
417
22
|
import { ReolinkBaichuanApi } from "@apocaliss92/nodelink-js";
|
|
418
23
|
|
|
@@ -424,235 +29,83 @@ const api = new ReolinkBaichuanApi({
|
|
|
424
29
|
});
|
|
425
30
|
|
|
426
31
|
await api.login();
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
// Send audio data (raw PCM or G.711)
|
|
432
|
-
await api.sendTalkAudio(audioBuffer);
|
|
433
|
-
|
|
434
|
-
// Stop talk session
|
|
435
|
-
await api.stopTalk();
|
|
436
|
-
```
|
|
437
|
-
|
|
438
|
-
## Video Clips & Recordings
|
|
439
|
-
|
|
440
|
-
Download and manage recorded video clips:
|
|
441
|
-
|
|
442
|
-
```typescript
|
|
443
|
-
import { ReolinkBaichuanApi } from "@apocaliss92/nodelink-js";
|
|
444
|
-
|
|
445
|
-
const api = new ReolinkBaichuanApi({
|
|
446
|
-
host: "192.168.1.100",
|
|
447
|
-
port: 9000,
|
|
448
|
-
username: "admin",
|
|
449
|
-
password: "your-password",
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
await api.login();
|
|
453
|
-
|
|
454
|
-
// Search recordings by date
|
|
455
|
-
const recordings = await api.searchRecordings({
|
|
456
|
-
channel: 0,
|
|
457
|
-
startTime: new Date("2024-01-01"),
|
|
458
|
-
endTime: new Date("2024-01-02"),
|
|
459
|
-
});
|
|
460
|
-
|
|
461
|
-
// Download a recording
|
|
462
|
-
const stream = await api.downloadRecording(recordings[0].filename);
|
|
463
|
-
|
|
464
|
-
// Pipe to file
|
|
465
|
-
import { createWriteStream } from "node:fs";
|
|
466
|
-
stream.pipe(createWriteStream("recording.mp4"));
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
## Device Discovery
|
|
470
|
-
|
|
471
|
-
Automatically discover cameras on your network:
|
|
472
|
-
|
|
473
|
-
```typescript
|
|
474
|
-
import { AutodiscoveryClient } from "@apocaliss92/nodelink-js";
|
|
475
|
-
|
|
476
|
-
const discovery = new AutodiscoveryClient();
|
|
477
|
-
|
|
478
|
-
discovery.on("device", (device) => {
|
|
479
|
-
console.log("Found camera:", device.ip, device.name, device.uid);
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
await discovery.startDiscovery();
|
|
483
|
-
|
|
484
|
-
// Stop after 10 seconds
|
|
485
|
-
setTimeout(() => {
|
|
486
|
-
discovery.stopDiscovery();
|
|
487
|
-
}, 10000);
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
## PTZ Control
|
|
491
|
-
|
|
492
|
-
Control Pan-Tilt-Zoom cameras:
|
|
493
|
-
|
|
494
|
-
```typescript
|
|
495
|
-
import { ReolinkBaichuanApi } from "@apocaliss92/nodelink-js";
|
|
496
|
-
|
|
497
|
-
const api = new ReolinkBaichuanApi({
|
|
498
|
-
host: "192.168.1.100",
|
|
499
|
-
port: 9000,
|
|
500
|
-
username: "admin",
|
|
501
|
-
password: "your-password",
|
|
32
|
+
const info = await api.getInfo();
|
|
33
|
+
await api.onSimpleEvent((event) => {
|
|
34
|
+
console.log(event.type, "on channel", event.channel);
|
|
502
35
|
});
|
|
503
|
-
|
|
504
|
-
await api.login();
|
|
505
|
-
|
|
506
|
-
// Move camera
|
|
507
|
-
await api.ptzControl({ channel: 0, command: "Right", speed: 32 });
|
|
508
|
-
await api.ptzControl({ channel: 0, command: "Stop" });
|
|
509
|
-
|
|
510
|
-
// Go to preset
|
|
511
|
-
await api.ptzGotoPreset({ channel: 0, preset: 1 });
|
|
512
|
-
|
|
513
|
-
// Get current position
|
|
514
|
-
const position = await api.getPtzPosition(0);
|
|
515
|
-
|
|
516
|
-
// Zoom control
|
|
517
|
-
await api.setZoomFocus({ channel: 0, zoom: { pos: 100 } });
|
|
518
36
|
```
|
|
519
37
|
|
|
520
|
-
|
|
38
|
+
---
|
|
521
39
|
|
|
522
|
-
|
|
40
|
+
## Contributing: Share Your Camera Fixtures
|
|
523
41
|
|
|
524
|
-
|
|
525
|
-
import { ReolinkBaichuanApi } from "@apocaliss92/nodelink-js";
|
|
42
|
+
Help improve device support by sharing the API responses from your camera model. The diagnostics dump captures all capability and configuration data (credentials, IPs, and serial numbers are **automatically sanitized**).
|
|
526
43
|
|
|
527
|
-
|
|
528
|
-
host: "192.168.1.100",
|
|
529
|
-
port: 9000,
|
|
530
|
-
username: "admin",
|
|
531
|
-
password: "your-password",
|
|
532
|
-
});
|
|
44
|
+
There are three ways to generate a dump:
|
|
533
45
|
|
|
534
|
-
|
|
46
|
+
**1. From the Manager UI** — Open a camera's detail panel and click the **"Dump"** button (next to Debug). The dump runs on the server and downloads a sanitized zip file automatically. Results are also available in the **Reports** section alongside stream analysis reports.
|
|
535
47
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
});
|
|
48
|
+
<p align="center">
|
|
49
|
+
<img src="documentation/screenshots/manager-ui-camera-detail.png" alt="Manager UI — Camera detail panel with Analyze and Dump buttons" width="800">
|
|
50
|
+
</p>
|
|
540
51
|
|
|
541
|
-
|
|
542
|
-
api.onAiAlarm((event) => {
|
|
543
|
-
console.log("AI detection:", event.type, event.state);
|
|
544
|
-
});
|
|
52
|
+
**2. Via CLI script** — For developers with a local clone:
|
|
545
53
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
54
|
+
```bash
|
|
55
|
+
git clone https://github.com/apocaliss92/nodelink-js.git && cd nodelink-js && npm install
|
|
56
|
+
# Configure your camera in .env (see env.template)
|
|
57
|
+
npx tsx test/capture-model-fixtures.ts
|
|
550
58
|
```
|
|
551
59
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
Work with NVRs and their connected channels:
|
|
60
|
+
**3. Via the library API** — From any project that depends on `@apocaliss92/nodelink-js`:
|
|
555
61
|
|
|
556
62
|
```typescript
|
|
557
|
-
import { ReolinkBaichuanApi } from "@apocaliss92/nodelink-js";
|
|
558
|
-
|
|
559
|
-
const api = new ReolinkBaichuanApi({
|
|
560
|
-
host: "192.168.1.100",
|
|
561
|
-
port: 9000,
|
|
562
|
-
username: "admin",
|
|
563
|
-
password: "your-password",
|
|
564
|
-
});
|
|
63
|
+
import { ReolinkBaichuanApi, captureModelFixtures } from "@apocaliss92/nodelink-js";
|
|
565
64
|
|
|
65
|
+
const api = new ReolinkBaichuanApi({ host: "192.168.1.100", port: 9000, username: "admin", password: "your-password" });
|
|
566
66
|
await api.login();
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
const channels = await api.getChannelInfoAll();
|
|
570
|
-
|
|
571
|
-
// Stream from a specific channel
|
|
572
|
-
const rtspServer = new BaichuanRtspServer({
|
|
573
|
-
api,
|
|
574
|
-
profile: "main",
|
|
575
|
-
channel: 2, // Channel index
|
|
576
|
-
port: 8554,
|
|
577
|
-
logger: console,
|
|
578
|
-
});
|
|
579
|
-
```
|
|
580
|
-
|
|
581
|
-
## Configuration
|
|
582
|
-
|
|
583
|
-
### Environment Variables
|
|
584
|
-
|
|
585
|
-
Create a `.env` file based on `env.template`:
|
|
586
|
-
|
|
587
|
-
```env
|
|
588
|
-
CAMERA_HOST=192.168.1.100
|
|
589
|
-
CAMERA_PORT=9000
|
|
590
|
-
CAMERA_USERNAME=admin
|
|
591
|
-
CAMERA_PASSWORD=your-password
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
### Logging
|
|
595
|
-
|
|
596
|
-
The library supports custom loggers:
|
|
597
|
-
|
|
598
|
-
```typescript
|
|
599
|
-
import { ReolinkBaichuanApi, createLogger } from "@apocaliss92/nodelink-js";
|
|
600
|
-
|
|
601
|
-
const logger = createLogger({ level: "debug" });
|
|
602
|
-
|
|
603
|
-
const api = new ReolinkBaichuanApi({
|
|
604
|
-
host: "192.168.1.100",
|
|
605
|
-
port: 9000,
|
|
606
|
-
username: "admin",
|
|
607
|
-
password: "your-password",
|
|
608
|
-
logger,
|
|
609
|
-
});
|
|
67
|
+
await captureModelFixtures({ api, channel: 0, outDir: "./my-camera-dump", log: console.log });
|
|
68
|
+
await api.close();
|
|
610
69
|
```
|
|
611
70
|
|
|
612
|
-
|
|
71
|
+
Then open a PR with the generated fixtures. Each new camera model helps us detect capabilities more accurately and prevents regressions. If your model isn't listed in [Supported Devices](#supported-devices), your contribution is especially valuable.
|
|
613
72
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
Run a standalone RTSP server:
|
|
617
|
-
|
|
618
|
-
```bash
|
|
619
|
-
npm run rtsp-server
|
|
620
|
-
```
|
|
73
|
+
---
|
|
621
74
|
|
|
622
|
-
|
|
75
|
+
## API Documentation
|
|
623
76
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
77
|
+
| Section | Description |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| [Baichuan Protocol API](./documentation/baichuan-api/README.md) | Binary protocol (port 9000) — streaming, events, PTZ, intercom, recordings |
|
|
80
|
+
| [CGI HTTP API](./documentation/cgi-api/README.md) | HTTP REST API (port 80) — configuration, settings, system administration |
|
|
81
|
+
| [Manager REST API](./documentation/manager-api.md) | Web dashboard HTTP API — auth, streaming, events, metrics |
|
|
82
|
+
| [Streaming Servers](./documentation/streaming.md) | RTSP, RFC4571, HTTP servers |
|
|
83
|
+
| [Network Discovery](./documentation/discovery.md) | UDP autodiscovery |
|
|
629
84
|
|
|
630
85
|
## Supported Devices
|
|
631
86
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
- Reolink IP cameras (RLC series, E1 series, Argus series)
|
|
635
|
-
- Reolink NVRs (RLN series)
|
|
636
|
-
- Reolink Home Hub
|
|
637
|
-
- Reolink TrackMix and Duo (multifocal cameras)
|
|
638
|
-
- Reolink battery cameras (Argus, TrackMix WiFi Battery)
|
|
87
|
+
<!-- AUTO-UPDATED: regenerated from test/fixtures/models/ folders -->
|
|
88
|
+
<!-- To update: npx tsx test/capture-model-fixtures.ts then update this list -->
|
|
639
89
|
|
|
640
|
-
|
|
90
|
+
Devices with captured fixtures (verified API compatibility):
|
|
641
91
|
|
|
642
|
-
|
|
92
|
+
| Model | Type | Firmware |
|
|
93
|
+
| --- | --- | --- |
|
|
94
|
+
| E1 Outdoor PoE | Wired camera | v3.1.0.5223 |
|
|
95
|
+
| E1 Zoom | Wired camera (H.265, PTZ) | v3.2.0.4741 |
|
|
96
|
+
| Argus 3E | Battery camera (via Home Hub) | v3.0.0.3623 |
|
|
97
|
+
| Argus PT Ultra | Battery camera with PTZ (via Home Hub) | v3.0.0.3911 |
|
|
98
|
+
| Reolink Home Hub | NVR / Hub | v3.3.0.456 |
|
|
643
99
|
|
|
644
|
-
|
|
645
|
-
- [CGI HTTP API](./documentation/cgi-api/README.md) - HTTP REST API (port 80)
|
|
646
|
-
- [Manager REST API](./documentation/manager-api.md) - Web dashboard HTTP API (auth, streaming, events, metrics)
|
|
647
|
-
- [Streaming Servers](./documentation/streaming.md) - RTSP, RFC4571, HTTP servers
|
|
648
|
-
- [Network Discovery](./documentation/discovery.md) - UDP autodiscovery
|
|
100
|
+
Also expected to work with other Reolink devices using the Baichuan protocol (port 9000): RLC series, RLN NVRs, TrackMix, Duo, and other Argus battery cameras.
|
|
649
101
|
|
|
650
|
-
##
|
|
102
|
+
## Credits
|
|
651
103
|
|
|
652
|
-
|
|
104
|
+
Based on the reverse engineering work of:
|
|
653
105
|
|
|
654
|
-
|
|
106
|
+
- **[neolink](https://github.com/thirtythreeforty/neolink)** - Rust implementation of Baichuan protocol
|
|
107
|
+
- **[reolink_aio](https://github.com/starkillerOG/reolink_aio)** - Python async library for Reolink cameras
|
|
655
108
|
|
|
656
|
-
|
|
109
|
+
## Disclaimer
|
|
657
110
|
|
|
658
|
-
|
|
111
|
+
This project is **not affiliated with, endorsed by, or connected to Reolink** in any way. "Reolink" is a trademark of Reolink Innovation Inc. This is an independent, community-driven open-source project created for **interoperability purposes**. No proprietary code or firmware from Reolink is included. The protocol implementation is based on publicly available reverse engineering efforts.
|