### Quick Start: Initialize and Connect to UniFi Protect API Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md This snippet demonstrates how to create an instance of the ProtectApi, log in to your Protect controller, and bootstrap the API to get the current state. It also shows how to access camera devices and listen for real-time events. ```typescript import { ProtectApi } from "unifi-protect"; // Create an API instance. const protect = new ProtectApi(); // Login to your Protect controller. await protect.login("192.168.1.1", "username", "password"); // Bootstrap to get the current state. await protect.getBootstrap(); // Access your devices. const cameras = protect.bootstrap?.cameras ?? []; console.log("Found " + cameras.length.toString() + " cameras."); // Listen for real-time events. protect.on("message", (packet) => { console.log("Event received:", packet); }); ``` -------------------------------- ### Install UniFi Protect Library Source: https://github.com/hjdhjd/unifi-protect/blob/main/README.md Install the unifi-protect library using npm. This is the first step to using the library in your Node.js project. ```sh npm install unifi-protect ``` -------------------------------- ### Example Codec String Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectLivestream.md An example of the codec string format returned by the 'codec' accessor. ```plaintext `hev1.1.6.L150,mp4a.40.2` ``` -------------------------------- ### Complete UniFi Protect API Example Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md This example demonstrates how to connect to a UniFi Protect controller, handle login and real-time events, and manage camera settings like enabling RTSP streams. It includes comprehensive error handling and utilizes the ProtectApi class for interaction. ```typescript import { ProtectApi, ProtectCameraConfig } from "unifi-protect"; class ProtectManager { private api: ProtectApi; constructor() { this.api = new ProtectApi(); this.setupEventHandlers(); } private setupEventHandlers(): void { // Handle login events. this.api.on("login", (success: boolean) => { console.log(success ? "Login successful." : "Login failed."); }); // Process real-time events. this.api.on("message", (packet) => { if(packet.header.modelKey === "camera") { console.log("Camera event:", packet); } }); } async connect(host: string, username: string, password: string): Promise { try { // Login to the controller. if(!await this.api.login(host, username, password)) { throw new Error("Authentication failed."); } // Bootstrap the configuration. if(!await this.api.getBootstrap()) { throw new Error("Bootstrap failed."); } console.log("Connected to " + this.api.name + "."); return true; } catch(error) { console.error("Connection failed:", error); return false; } } async enableAllRtspStreams(): Promise { const cameras = this.api.bootstrap?.cameras ?? []; for(const camera of cameras) { const updated = await this.api.enableRtsp(camera); if(updated) { console.log("RTSP enabled for " + this.api.getDeviceName(camera) + "."); } } } } ``` -------------------------------- ### start() Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectLivestream.md Starts an fMP4 livestream session from the Protect controller. It allows customization through optional parameters and provides feedback on the session's success and events. ```APIDOC ## start() ### Description Starts an fMP4 livestream session from the Protect controller. ### Method Not applicable (SDK method) ### Endpoint Not applicable (SDK method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```ts start(cameraId: string, channel: number, options?: Partial): Promise; ``` ### Response #### Success Response `Promise` - Returns `true` if the livestream has successfully started, `false` otherwise. #### Response Example ```json true ``` ### Remarks Once a livestream session has started, the following events can be listened for (unless `useStream` is specified in `options`, in which case only the `close` event is available): - **close**: Emitted when the livestream connection terminates for any reason, including manual stops or errors. - **codec**: Emitted with the codec information string when received from the controller (stream mode disabled only). - **initsegment**: Emitted with the initialization segment Buffer containing FTYP and MOOV boxes (stream mode disabled only). - **message**: Emitted with each complete fMP4 segment Buffer, both initialization and regular segments (stream mode disabled only). - **segment**: Emitted with each complete non-initialization segment Buffer containing MOOF/MDAT pairs (stream mode disabled only). - **timestamps**: Emitted with decode timestamp arrays when emitTimestamps is enabled in options. ``` -------------------------------- ### Record Livestream to File Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md This example demonstrates how to record a livestream from a UniFi Protect camera to a file using the Readable stream interface. Ensure you have logged in and retrieved the bootstrap configuration before starting the livestream. The recording will stop after a specified duration. ```typescript import { ProtectApi } from "unifi-protect"; import { createWriteStream } from "fs"; const protect = new ProtectApi(); async function recordLivestream(cameraId: string, durationMs: number) { await protect.login("192.168.1.1", "admin", "password"); await protect.getBootstrap(); const camera = protect.bootstrap?.cameras.find((c) => c.id === cameraId); if(!camera) return; // Create a livestream instance and start streaming on channel 0 (highest quality) with the Readable stream interface enabled. const livestream = protect.createLivestream(); if(!await livestream.start(camera.id, 0, { useStream: true })) { console.error("Failed to start livestream."); return; } // Pipe the fMP4 stream to a file. const output = createWriteStream("recording-" + Date.now().toString() + ".mp4"); livestream.stream?.pipe(output); // Stop after the requested duration. setTimeout(() => { livestream.stop(); output.end(); console.log("Recording complete."); }, durationMs); } ``` -------------------------------- ### Instantiate ProtectApi with Custom Logger Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md This example shows how to create an instance of the ProtectApi class using a custom logging implementation, such as Winston. This allows for integration with your application's existing logging infrastructure. ```typescript import { ProtectApi, ProtectLogging } from "unifi-protect"; import winston from "winston"; const logger = winston.createLogger({ level: "info", format: winston.format.simple(), transports: [new winston.transports.Console()] }); const customLog: ProtectLogging = { debug: (message: string, ...args: unknown[]) => logger.debug(message, args), error: (message: string, ...args: unknown[]) => logger.error(message, args), info: (message: string, ...args: unknown[]) => logger.info(message, args), warn: (message: string, ...args: unknown[]) => logger.warn(message, args) }; const protect = new ProtectApi(customLog); ``` -------------------------------- ### Build Custom API URLs for Protect Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md This example shows how to construct custom API URLs for the UniFi Protect API. It demonstrates retrieving base endpoints like the camera endpoint and then building a specific URL for a particular camera to make a custom request. ```typescript import { ProtectApi } from "unifi-protect"; const protect = new ProtectApi(); async function customEndpoints() { await protect.login("192.168.1.1", "admin", "password"); // Get base endpoints. const cameraEndpoint = protect.getApiEndpoint("camera"); // Returns: "https://192.168.1.1/proxy/protect/api/cameras" // Build specific camera URL. const cameraId = "abc123"; const specificCamera = cameraEndpoint + "/" + cameraId; // Make custom request. const response = await protect.retrieve(specificCamera); if(response) { const camera = await response.body.json(); console.log("Camera: " + camera.name); } } ``` -------------------------------- ### Start Livestream Session Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectLivestream.md Initiates an fMP4 livestream session from a Protect controller. Requires camera ID and channel. Optional parameters can customize the session. ```typescript start( cameraId, channel, options?): Promise; ``` -------------------------------- ### Get Full Device Name with Controller Context Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Generates a combined device and controller information string. Useful for logging in multi-controller environments. ```typescript import { ProtectApi } from "unifi-protect"; const protect = new ProtectApi(); async function monitorDevices() { await protect.login("192.168.1.1", "admin", "password"); await protect.getBootstrap(); protect.on("message", (packet) => { const device = protect.bootstrap?.cameras.find((c) => c.id === packet.header.id); if(device) { // Logs: "Dream Machine Pro [UDMP] Front Door [G4 Doorbell Pro]" console.log(protect.getFullName(device) + ": " + packet.header.action); } }); } ``` -------------------------------- ### name Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Gets a formatted name for the Protect controller. Before bootstrap, it returns the connection address; after bootstrap, it includes the controller's configured name and model type. ```APIDOC ## name ### Description Gets a formatted name for the Protect controller. Returns a human-readable controller identifier. After bootstrap, includes the controller's configured name and model type. Before bootstrap, returns the hostname or IP address used for connection. ### Method GET (implied by SDK getter) ### Endpoint Not explicitly defined, SDK getter. ### Parameters None ### Request Example ```typescript // Before bootstrap: "192.168.1.1" // After bootstrap: "Dream Machine Pro [UDMP]" console.log(protect.name); ``` ### Response #### Success Response (200) - **name** (string) - Controller name in format: `Name [Type]` or just the address if not bootstrapped. #### Response Example ```json "Dream Machine Pro [UDMP]" ``` ``` -------------------------------- ### Get Codec Information Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectLivestream.md Retrieves the codec and container format for the livestream session. The format is 'codec,container'. ```typescript const codecInfo = livestream.codec; ``` -------------------------------- ### Get Formatted Device Name Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Generates a formatted device information string. Can include custom names and network details like IP and MAC addresses. ```typescript import { ProtectApi } from "unifi-protect"; const protect = new ProtectApi(); async function listDevices() { await protect.login("192.168.1.1", "admin", "password"); await protect.getBootstrap(); // List all devices with full information. const allDevices = [ ...(protect.bootstrap?.cameras ?? []), ...(protect.bootstrap?.lights ?? []), ...(protect.bootstrap?.sensors ?? []), ...(protect.bootstrap?.chimes ?? []), ...(protect.bootstrap?.viewers ?? []) ]; for(const device of allDevices) { // Basic format. console.log(protect.getDeviceName(device)); // Output: "Front Door [G4 Doorbell Pro]" // With network info. console.log(protect.getDeviceName(device, device.name, true)); // Output: "Front Door [G4 Doorbell Pro] (address: 192.168.1.50 mac: 00:00:00:00:00:00)" // Custom name. console.log(protect.getDeviceName(device, "Custom Name")); // Output: "Custom Name [G4 Doorbell Pro]" } } ``` -------------------------------- ### Get Controller Name Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Retrieves a formatted name for the UniFi Protect controller. Before bootstrap, it shows the connection address; after bootstrap, it includes the configured name and model type. ```typescript // Before bootstrap: "192.168.1.1" // After bootstrap: "Dream Machine Pro [UDMP]" console.log(protect.name); ``` -------------------------------- ### Get Node.js Readable Stream Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectLivestream.md Retrieves a Node.js Readable stream for the livestream if 'useStream' was enabled during livestream startup. Otherwise, returns null. ```typescript const stream = livestream.stream; ``` -------------------------------- ### Get Initialization Segment Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectLivestream.md Retrieves the fMP4 initialization segment. This segment is required at the start of every fMP4 stream. The promise may never settle if the stream stops or fails before the segment is received. ```typescript const initSegment = await livestream.getInitSegment(); ``` -------------------------------- ### getBootstrap Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Retrieves the controller configuration, including all device states and system settings. This is a necessary step after successful login. ```APIDOC ## getBootstrap ### Description Retrieves the controller configuration. Emitted when bootstrap data is successfully retrieved from the controller, including the complete ProtectNvrBootstrap configuration object. ### Method GET ### Endpoint `/api/bootstrap` ### Response #### Success Response (200) - **bootstrap** (ProtectNvrBootstrap) - The complete controller configuration object. #### Response Example ```json { "cameras": [...], "nvr": {...} } ``` ``` -------------------------------- ### Setting up Two-Way Audio with Protect API Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Establishes a two-way audio connection to a camera using the talkback WebSocket endpoint. Requires camera ID and login credentials. ```typescript import { ProtectApi } from "unifi-protect"; import { WebSocket } from "ws"; const protect = new ProtectApi(); async function setupTalkback(cameraId: string) { await protect.login("192.168.1.1", "admin", "password"); // Get the talkback endpoint. const params = new URLSearchParams({ camera: cameraId }); const wsUrl = await protect.getWsEndpoint("talkback", params); if(!wsUrl) { console.error("Failed to get talkback endpoint."); return; } // Connect to the WebSocket. const ws = new WebSocket(wsUrl); ws.on("open", () => { console.log("Talkback connection established."); // Send AAC-encoded audio data. // ws.send(aacAudioBuffer); }); ws.on("error", (error) => { console.error("Talkback error:", error); }); } ``` -------------------------------- ### ProtectLivestream.stream Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectLivestream.md Retrieves a Node.js Readable stream if the livestream was started with the `useStream` option enabled. ```APIDOC ## Accessor: stream ### Get Signature ```ts get stream(): Nullable; ``` ### Description Retrieve a Node.js Readable stream if `useStream` was set to true (defaults to false) when starting the livestream. Otherwise, returns `null`. ### Returns - `Nullable` - A Node.js Readable stream or `null`. ``` -------------------------------- ### ProtectApi.getBootstrap Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Retrieves the initial state of the UniFi Protect system, including all connected devices and their configurations. ```APIDOC ## ProtectApi.getBootstrap ### Description Retrieves the initial state of the UniFi Protect system, including all connected devices and their configurations. ### Method GET ### Endpoint /api/bootstrap ### Response #### Success Response (200) - **cameras** (array) - An array of camera configurations. - **lights** (array) - An array of light configurations. - **sensors** (array) - An array of sensor configurations. - **nvr** (object) - The NVR configuration. #### Response Example ```json { "cameras": [ { "id": "camera1", "name": "Front Door Camera" } ], "lights": [], "sensors": [], "nvr": { "version": "1.0.0" } } ``` ``` -------------------------------- ### Configure UniFi Protect Devices Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Update camera names, recording settings, smart detection, light configurations, and doorbell chime volumes. Requires administrative privileges and successful login to the Protect controller. ```typescript import { ProtectApi, ProtectCameraConfig } from "unifi-protect"; const protect = new ProtectApi(); async function configureDevices() { await protect.login("192.168.1.1", "admin", "password"); await protect.getBootstrap(); const camera = protect.bootstrap?.cameras[0]; if(!camera) return; // Update camera name and recording settings. const updatedCamera = await protect.updateDevice(camera, { name: "Front Door Camera", recordingSettings: { mode: "always", postPaddingSecs: 3, prePaddingSecs: 3, retentionDurationMs: 7 * 24 * 60 * 60 * 1000 } }); // Configure smart detection. await protect.updateDevice(camera, { smartDetectSettings: { autoTrackingObjectTypes: ["person"], objectTypes: [ "person", "vehicle" ] } }); // Update light device. const light = protect.bootstrap?.lights[0]; if(light) { await protect.updateDevice(light, { lightDeviceSettings: { ledLevel: 6, pirDuration: 15000, pirSensitivity: 50 }, lightModeSettings: { mode: "motion" } }); } // Configure doorbell chime volume. const chime = protect.bootstrap?.chimes[0]; if(chime) { await protect.updateDevice(chime, { volume: 75 }); } } ``` -------------------------------- ### Initialize and Login to UniFi Protect API Source: https://github.com/hjdhjd/unifi-protect/blob/main/README.md Initialize the ProtectApi, log in to your UniFi Protect controller, and retrieve bootstrap data. This sets up the connection for further API interactions. ```typescript import { ProtectApi } from "unifi-protect"; const protect = new ProtectApi(); await protect.login("192.168.1.1", "username", "password"); await protect.getBootstrap(); // Access your devices. const cameras = protect.bootstrap?.cameras ?? []; // Listen for real-time events. protect.on("message", (packet) => console.log(packet.header.modelKey, packet.header.action)); ``` -------------------------------- ### Connect to UniFi Protect Controller Source: https://github.com/hjdhjd/unifi-protect/blob/main/README.md Obtain the bootstrap JSON from the UniFi Protect controller to initiate the connection process. This JSON contains necessary information for subsequent steps. ```bash https://protect-nvr-ip/proxy/protect/api/bootstrap ``` -------------------------------- ### getFullName Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Generates a combined device and controller information string for complete context. ```APIDOC ## getFullName ### Description Utility method that generates a combined device and controller information string. It is useful for logging and multi-controller environments. ### Method GET (assumed for retrieving information) ### Endpoint (Internal method, not a direct API endpoint) ### Parameters #### Path Parameters (Not applicable) #### Query Parameters (Not applicable) #### Request Body (Not applicable) #### Parameters - **device** ([`ProtectKnownDeviceTypes`](#protectknowndevicetypes)) - Required - Protect device object. ### Request Example ```typescript console.log(protect.getFullName(device)); ``` ### Response #### Success Response (200) - **string** - Formatted string including both controller and device information. ### Remarks Combines controller and device information for complete context: `Controller Name [Controller Type] Device Name [Device Type]` ``` -------------------------------- ### ProtectApi Constructor Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Initializes a new instance of the UniFi Protect API. Optionally accepts a custom logging implementation. ```APIDOC ## new ProtectApi() ### Description Creates an instance of the UniFi Protect API. Allows for custom logging integration. ### Constructor `new ProtectApi(log?: ProtectLogging): ProtectApi` ### Parameters #### Parameters - **log** (ProtectLogging) - Optional - Custom logging implementation. Defaults to console logging. ### Returns - ProtectApi - An instance of the ProtectApi. ### Remarks The logging interface enables integration with your application's logging system. By default, errors and warnings are logged to the console, while debug messages are suppressed. ### Example ```typescript import { ProtectApi, ProtectLogging } from "unifi-protect"; import winston from "winston"; const logger = winston.createLogger({ level: "info", format: winston.format.simple(), transports: [new winston.transports.Console()] }); const customLog: ProtectLogging = { debug: (message: string, ...args: unknown[]) => logger.debug(message, args), error: (message: string, ...args: unknown[]) => logger.error(message, args), info: (message: string, ...args: unknown[]) => logger.info(message, args), warn: (message: string, ...args: unknown[]) => logger.warn(message, args) }; const protect = new ProtectApi(customLog); ``` ``` -------------------------------- ### Making Custom API Calls with Protect API Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Executes custom HTTP requests to the Protect controller for advanced use cases. Supports GET and POST methods with options for error handling and timeouts. ```typescript import { ProtectApi } from "unifi-protect"; const protect = new ProtectApi(); async function customApiCalls() { await protect.login("192.168.1.1", "admin", "password"); // Get events from the last hour. const end = Date.now(); const start = end - (60 * 60 * 1000); const response = await protect.retrieve( "https://192.168.1.1/proxy/protect/api/events?start=" + start.toString() + "&end=" + end.toString(), { method: "GET" } ); if(response) { const events = await response.body.json(); console.log("Found " + events.length.toString() + " events."); } // Download a video clip. const videoResponse = await protect.retrieve( "https://192.168.1.1/proxy/protect/api/video/export", { body: JSON.stringify({ camera: "camera-id", end: end, start: start, type: "timelapse" }), method: "POST" }, { timeout: 30000 } ); if(videoResponse) { const videoBuffer = Buffer.from(await videoResponse.body.arrayBuffer()); // Save or process the video. } } ``` -------------------------------- ### getBootstrap() Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Retrieve the bootstrap JSON from a UniFi Protect controller. ```APIDOC ## getBootstrap() ### Description Retrieve the bootstrap JSON from a UniFi Protect controller. ### Returns `Promise` Indicates if the bootstrap retrieval was successful. ``` -------------------------------- ### login() Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Executes a login attempt to the UniFi Protect API, handling authentication and session management. ```APIDOC ## login() ### Description Executes a login attempt to the UniFi Protect API. This method terminates existing sessions, acquires CSRF tokens, establishes cookie-based authentication, and emits a `login` event with the result. ### Method `login(nvrAddress: string, username: string, password: string): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import { ProtectApi } from "unifi-protect"; const protect = new ProtectApi(); async function connectWithAwait() { const success = await protect.login("192.168.1.1", "admin", "password"); if(success) { console.log("Connected successfully."); } } ``` ### Response #### Success Response `Promise` resolving to `true` on successful authentication. #### Response Example `true` (on success) #### Error Response `Promise` resolving to `false` on authentication failure. #### Remarks Emits a `login` event with `true` on success and `false` on failure. Handles UniFi OS CSRF protection and maintains session state. Administrative privileges are determined during login and cached. ``` -------------------------------- ### Get Protect API Endpoint URL Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Returns an API endpoint URL for the requested endpoint type. This method generates properly formatted URLs for various Protect API endpoints, including bootstrap, camera, chime, light, login, NVR, self, sensor, websocket, and viewer. ```typescript getApiEndpoint(endpoint): string; ``` -------------------------------- ### enableRtsp Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Utility method that enables all RTSP channels on a given Protect camera. Requires Super Admin privileges. ```APIDOC ## enableRtsp ### Description Utility method that enables all RTSP channels on a given Protect camera. RTSP streams allow third-party applications to access camera feeds directly. Enabling RTSP requires Super Admin privileges. ### Method POST (implied by SDK usage) ### Endpoint Not explicitly defined, SDK method. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **device** ([ProtectCameraConfigInterface](ProtectTypes.md#protectcameraconfiginterface)) - Required - The Protect camera object to modify. ### Request Example ```typescript const camera = protect.bootstrap?.cameras[0]; if(camera) { await protect.enableRtsp(camera); } ``` ### Response #### Success Response (200) - **updatedCameraConfig** ([ProtectCameraConfigInterface](ProtectTypes.md#protectcameraconfiginterface)) - Promise resolving to the updated camera configuration. #### Response Example ```json { "id": "camera-id", "name": "Camera Name", "rtspEnabled": true, "streamUrl": "rtsp://[NVR_IP]:7447/[CAMERA_GUID]_0" } ``` ``` -------------------------------- ### ProtectApi.on Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Listens for real-time events from the UniFi Protect system via WebSocket. ```APIDOC ## ProtectApi.on ### Description Listens for real-time events from the UniFi Protect system via WebSocket. This method allows for real-time updates on device status, motion detection, and other events. ### Method WebSocket ### Endpoint /ws/protect ### Parameters #### Event Listener - **message** (function) - A callback function that receives event packets. ### Event Example ```json { "message": { "event": "motion", "cameraId": "camera1" } } ``` ``` -------------------------------- ### bootstrap Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Access the Protect controller bootstrap JSON. The bootstrap must be retrieved via getBootstrap() before accessing this property. It contains the complete system state and is automatically updated when configuration changes occur. ```APIDOC ## bootstrap ### Description Access the Protect controller bootstrap JSON. The bootstrap contains the complete system state and is automatically updated when configuration changes occur. ### Remarks The bootstrap must be retrieved via [getBootstrap](#getbootstrap) before accessing this property. ### Returns [`ProtectNvrBootstrapData`](#protectnvrbootstrapdata) Bootstrap configuration if available, `null` otherwise. ``` -------------------------------- ### ProtectLivestream Constructor Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectLivestream.md Initializes a new ProtectLivestream instance. This requires an existing UniFi Protect API instance and a logging instance. ```APIDOC ## Constructor ```ts new ProtectLivestream(api, log): ProtectLivestream; ``` ### Parameters - **api** (`ProtectApi`) - An instance of the UniFi Protect API. - **log** (`ProtectLogging`) - An instance for logging. ### Returns - `ProtectLivestream` - A new instance of the ProtectLivestream class. ``` -------------------------------- ### Login and Retrieve Bootstrap Data Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Logs into the Unifi Protect controller and retrieves the complete system bootstrap configuration. This is essential for accessing device and system information. ```typescript import { ProtectApi, ProtectCameraConfig } from "unifi-protect"; const protect = new ProtectApi(); async function analyzeSystem() { // Login and bootstrap. await protect.login("192.168.1.1", "admin", "password"); await protect.getBootstrap(); // Access the bootstrap data. const bootstrap = protect.bootstrap; if(!bootstrap) return; // System information. console.log("NVR: " + bootstrap.nvr.name); console.log("Version: " + bootstrap.nvr.version); console.log("Up since: " + new Date(bootstrap.nvr.upSince).toString()); // Device inventory. console.log("Cameras: " + bootstrap.cameras.length.toString()); console.log("Lights: " + bootstrap.lights.length.toString()); console.log("Sensors: " + bootstrap.sensors.length.toString()); // Find specific devices. const doorbells = bootstrap.cameras.filter((cam) => cam.featureFlags.isDoorbell); const motionSensors = bootstrap.sensors.filter((sensor) => sensor.type === "motion"); // Check recording status. const recording = bootstrap.cameras.filter((cam) => cam.isRecording && cam.isConnected); console.log(recording.length.toString() + " cameras actively recording."); } ``` -------------------------------- ### updateDevice Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Applies configuration changes to any Protect device, such as cameras, lights, sensors, or chimes. Requires administrative privileges. ```APIDOC ## updateDevice ### Description Applies configuration changes to any Protect device. Common modifications include camera settings, light settings, sensor settings, and chime settings. Most configuration changes require administrative privileges (Super Admin role). ### Method POST (implied by SDK usage) ### Endpoint Not explicitly defined, SDK method. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **device** (object) - Required - The Protect device object to update. - **config** (object) - Required - An object containing the configuration settings to apply. ### Request Example ```typescript // Example for updating a camera await protect.updateDevice(camera, { name: "Front Door Camera", recordingSettings: { mode: "always", postPaddingSecs: 3, prePaddingSecs: 3, retentionDurationMs: 7 * 24 * 60 * 60 * 1000 } }); // Example for updating a light await protect.updateDevice(light, { lightDeviceSettings: { ledLevel: 6, pirDuration: 15000, pirSensitivity: 50 }, lightModeSettings: { mode: "motion" } }); // Example for updating a chime await protect.updateDevice(chime, { volume: 75 }); ``` ### Response #### Success Response (200) - **updatedDeviceConfig** (object) - The complete updated device configuration. #### Response Example ```json { "id": "device-id", "name": "Updated Device Name", "type": "camera", "recordingSettings": { ... }, "smartDetectSettings": { ... } } ``` ``` -------------------------------- ### ProtectApi.login Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Logs into the UniFi Protect controller using provided credentials. This is a necessary step before interacting with other API endpoints. ```APIDOC ## ProtectApi.login ### Description Logs into the UniFi Protect controller using provided credentials. This is a necessary step before interacting with other API endpoints. ### Method POST ### Endpoint /api/login ### Parameters #### Query Parameters - **ip** (string) - Required - The IP address of the Protect controller. - **username** (string) - Required - The username for authentication. - **password** (string) - Required - The password for authentication. ### Request Example ```json { "ip": "192.168.1.1", "username": "username", "password": "password" } ``` ### Response #### Success Response (200) - **success** (boolean) - Indicates if the login was successful. - **message** (string) - A message indicating the result of the login attempt. #### Response Example ```json { "success": true, "message": "Login successful." } ``` ``` -------------------------------- ### enableRtsp Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Enables RTSP streams for a given camera device and returns the updated camera information with RTSP URLs if successful. ```APIDOC ## enableRtsp ### Description Enables RTSP streams for a given camera device and returns the updated camera information with RTSP URLs if successful. ### Method POST (assumed based on enabling a feature) ### Endpoint /api/v1/camera/{cameraId}/rtsp/enable (assumed based on context) ### Parameters #### Path Parameters - **cameraId** (string) - Required - The unique identifier of the camera. #### Request Body (Implicitly the camera object is passed, but not explicitly defined in the source) ### Request Example ```typescript // Example usage within the provided context const updatedCamera = await protect.enableRtsp(camera); ``` ### Response #### Success Response (200) - **channels** (array) - An array of channel objects, each containing RTSP stream information if enabled. #### Response Example ```json { "channels": [ { "id": "channel-id-1", "isRtspEnabled": true, "rtspAlias": "stream-alias-1" } // ... other channels ] } ``` ``` -------------------------------- ### ProtectCameraTalkbackConfigInterface Properties Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectTypes.md Defines the properties for UniFi Protect camera talkback settings, including network addresses, audio parameters, and quality. ```typescript interface ProtectCameraTalkbackConfigInterface { bindAddr?: string; bindPort?: number; bitsPerSample?: number; channels?: number; filterAddr?: string; filterPort?: number; quality?: number; samplingRate?: number; typeFmt?: string; typeIn?: string; url?: string; } ``` -------------------------------- ### Capture Camera Snapshots Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Retrieves snapshots from Protect cameras, including full resolution, thumbnail, and package camera views. Requires prior login and bootstrap retrieval. ```typescript import { ProtectApi } from "unifi-protect"; import { writeFile } from "fs/promises"; const protect = new ProtectApi(); async function captureSnapshots() { await protect.login("192.168.1.1", "admin", "password"); await protect.getBootstrap(); const cameras = protect.bootstrap?.cameras ?? []; for(const camera of cameras) { // Full resolution snapshot. const fullRes = await protect.getSnapshot(camera); // Thumbnail snapshot. const thumbnail = await protect.getSnapshot(camera, { height: 360, width: 640 }); // Package camera snapshot (if available). if(camera.featureFlags.hasPackageCamera) { const packageSnap = await protect.getSnapshot(camera, { usePackageCamera: true }); if(packageSnap) { await writeFile(camera.name + "-package.jpg", packageSnap); } } if(fullRes && thumbnail) { await writeFile(camera.name + "-full.jpg", fullRes); await writeFile(camera.name + "-thumb.jpg", thumbnail); console.log("Saved snapshots for " + camera.name + "."); } } } ``` -------------------------------- ### Enable RTSP Streams for Cameras Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Enables RTSP streams for all cameras found in the Unifi Protect bootstrap data. Displays the RTSP URLs for each enabled channel. ```typescript import { ProtectApi } from "unifi-protect"; const protect = new ProtectApi(); async function setupRtspStreams() { await protect.login("192.168.1.1", "admin", "password"); await protect.getBootstrap(); const cameras = protect.bootstrap?.cameras ?? []; for(const camera of cameras) { const updated = await protect.enableRtsp(camera); if(updated) { console.log("RTSP enabled for " + camera.name + "."); // Display RTSP URLs. for(const [index, channel] of updated.channels.entries()) { if(channel.isRtspEnabled) { const rtspUrl = "rtsp://192.168.1.1:7447/" + channel.rtspAlias; console.log(" Channel " + index.toString() + ": " + rtspUrl); } } } else { console.log("Failed to enable RTSP for " + camera.name + "."); } } } ``` -------------------------------- ### Login Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Authenticates with the Protect controller. This method is crucial for establishing a connection and should be called before other API operations. ```APIDOC ## login ### Description Authenticates with the Protect controller. This event fires whether the login succeeds or fails, allowing applications to respond appropriately to authentication state changes. ### Method POST ### Endpoint `/api/login` ### Parameters #### Query Parameters - **host** (string) - Required - The hostname or IP address of the Protect controller. - **username** (string) - Required - The username for authentication. - **password** (string) - Required - The password for authentication. ### Request Example ```typescript await api.login("protect.local", "admin", "password"); ``` ### Response #### Success Response (200) - **success** (boolean) - Indicates if the login attempt was successful. #### Response Example ```json { "success": true } ``` ``` -------------------------------- ### ProtectCameraChannelConfigInterface Properties Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectTypes.md Details the configuration properties for a UniFi Protect camera channel, such as bitrate, FPS, resolution, and RTSP settings. Includes properties for auto-bitrate and auto-FPS. ```typescript autoBitrate: boolean autoFps: boolean bitrate: number enabled: boolean fps: number fpsValues: number[] height: number id: number idrInterval: number internalRtspAlias: Nullable isInternalRtspEnabled: boolean isRtspEnabled: boolean maxBitrate: number minBitrate: number minClientAdaptiveBitRate: number minMotionAdaptiveBitRate: number name: string rtspAlias: string validBitrateRangeMargin: Nullable videoId: string width: number ``` -------------------------------- ### ProtectLivestream.getInitSegment() Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectLivestream.md Asynchronously retrieves the initialization segment for the fMP4 stream. It resolves immediately if the segment has already been received. ```APIDOC ## Method: getInitSegment() ```ts getInitSegment(): Promise>; ``` ### Description Retrieve the initialization segment that must be at the start of every fMP4 stream. ### Returns - `Promise>` - A promise that resolves once the initialization segment has been seen, or returning it immediately if it already has been. ### Remarks If the stream is stopped or fails before the initialization segment is received, the returned promise will never settle. Callers should race this against the `close` event or an external timeout to avoid waiting indefinitely. ``` -------------------------------- ### Login to UniFi Protect API Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Authenticates with the UniFi Protect controller. This method handles session establishment and CSRF token acquisition. It can be used with async/await or event listeners. ```typescript login( nvrAddress, username, password): Promise; ``` ```typescript import { ProtectApi } from "unifi-protect"; const protect = new ProtectApi(); // Pattern 1: Using async/await. async function connectWithAwait() { const success = await protect.login("192.168.1.1", "admin", "password"); if(success) { console.log("Connected successfully."); } } // Pattern 2: Using event listeners. function connectWithEvents() { protect.once("login", (success: boolean) => { if(success) { console.log("Connected successfully."); // Continue with bootstrap. protect.getBootstrap(); } }); protect.login("192.168.1.1", "admin", "password"); } // Pattern 3: With retry logic. async function connectWithRetry(maxAttempts = 3) { for(let i = 0; i < maxAttempts; i++) { if(await protect.login("192.168.1.1", "admin", "password")) { return true; } console.log("Login attempt " + (i + 1).toString() + " failed, retrying..."); await new Promise(resolve => setTimeout(resolve, 2000)); } return false; } ``` -------------------------------- ### getWsEndpoint Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Provides access to real-time WebSocket endpoints for livestream or talkback. For livestreams, it's recommended to use createLivestream instead. ```APIDOC ## getWsEndpoint ### Description Provides access to real-time WebSocket endpoints for livestream or talkback. For livestreams, it's recommended to use createLivestream instead. ### Method Not specified (likely internal or SDK method) ### Parameters #### Path Parameters - `endpoint` (string) - Required - Endpoint type (`livestream` or `talkback`) #### Query Parameters - `params` (URLSearchParams) - Optional - URL parameters for the endpoint ### Response #### Success Response - `Promise>` - Promise resolving to the WebSocket URL, or `null` on failure. ### Remarks - Livestream Endpoint: Returns a WebSocket URL for H.264 fMP4 video streams. Do not use directly - use [createLivestream](#createlivestream) instead for proper stream handling. - Talkback Endpoint: Creates a two-way audio connection to cameras with speakers. The WebSocket accepts AAC-encoded ADTS audio streams. Requires a `camera` parameter. ### Example ```typescript import { ProtectApi } from "unifi-protect"; import { WebSocket } from "ws"; const protect = new ProtectApi(); async function setupTalkback(cameraId: string) { await protect.login("192.168.1.1", "admin", "password"); const params = new URLSearchParams({ camera: cameraId }); const wsUrl = await protect.getWsEndpoint("talkback", params); if(!wsUrl) { console.error("Failed to get talkback endpoint."); return; } const ws = new WebSocket(wsUrl); ws.on("open", () => { console.log("Talkback connection established."); }); ws.on("error", (error) => { console.error("Talkback error:", error); }); } ``` ``` -------------------------------- ### ProtectLivestream.initSegment Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectLivestream.md Retrieves the initialization segment required at the beginning of every fMP4 stream. ```APIDOC ## Accessor: initSegment ### Get Signature ```ts get initSegment(): Nullable>; ``` ### Description The initialization segment that must be at the start of every fMP4 stream. ### Returns - `Nullable>` - The initialization segment if it exists, or `null` otherwise. ``` -------------------------------- ### getDeviceName Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Generates a formatted device information string, optionally including network details. ```APIDOC ## getDeviceName ### Description Utility method that generates a nicely formatted device information string. It can optionally include IP and MAC address information. ### Method GET (assumed for retrieving information) ### Endpoint (Internal method, not a direct API endpoint) ### Parameters #### Path Parameters (Not applicable) #### Query Parameters (Not applicable) #### Request Body (Not applicable) #### Parameters - **device** ([`ProtectKnownDeviceTypes`](#protectknowndevicetypes)) - Required - Protect device object. - **name** (string | undefined) - Optional - Custom name to use. Defaults to `device.name`. - **deviceInfo** (boolean) - Optional - Include IP and MAC address information. Defaults to `false`. ### Request Example ```typescript console.log(protect.getDeviceName(device)); console.log(protect.getDeviceName(device, device.name, true)); console.log(protect.getDeviceName(device, "Custom Name")); ``` ### Response #### Success Response (200) - **string** - Formatted device string. ### Remarks Returns device information in a consistent, readable format: - Basic: `Device Name [Device Type]` - With info: `Device Name [Device Type] (address: IP mac: MAC)` ``` -------------------------------- ### Enable RTSP on Protect Camera Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Enables all RTSP channels for a given Protect camera, allowing third-party applications to access camera feeds. Requires Super Admin privileges. ```typescript enableRtsp(device): Promise>; ``` -------------------------------- ### Open Updates Websocket Source: https://github.com/hjdhjd/unifi-protect/blob/main/README.md Establish a websocket connection to the updates URL using the lastUpdateId obtained from the bootstrap JSON. This enables receiving realtime events. ```bash wss://protect-nvr-ip/proxy/protect/ws/updates?lastUpdateId=X ``` -------------------------------- ### createLivestream() Source: https://github.com/hjdhjd/unifi-protect/blob/main/docs/ProtectApi.md Return a new instance of the Protect livestream API. The livestream API provides direct access to camera H.264 fMP4 streams, enabling real-time video streaming, stream recording and processing, integration with video processing pipelines, and low-latency video access. Unlike RTSP streams, livestreams are delivered over WebSockets with minimal latency and don't require additional authentication. ```APIDOC ## createLivestream() ### Description Return a new instance of the Protect livestream API. The livestream API provides direct access to camera H.264 fMP4 streams, enabling real-time video streaming, stream recording and processing, integration with video processing pipelines, and low-latency video access. ### Remarks Unlike RTSP streams, livestreams are delivered over WebSockets with minimal latency and don't require additional authentication. ### Returns [`ProtectLivestream`](ProtectLivestream.md#protectlivestream) New livestream API instance. ### Example ```typescript import { ProtectApi } from "unifi-protect"; import { createWriteStream } from "fs"; const protect = new ProtectApi(); async function recordLivestream(cameraId: string, durationMs: number) { await protect.login("192.168.1.1", "admin", "password"); await protect.getBootstrap(); const camera = protect.bootstrap?.cameras.find((c) => c.id === cameraId); if(!camera) return; // Create a livestream instance and start streaming on channel 0 (highest quality) with the Readable stream interface enabled. const livestream = protect.createLivestream(); if(!await livestream.start(camera.id, 0, { useStream: true })) { console.error("Failed to start livestream."); return; } // Pipe the fMP4 stream to a file. const output = createWriteStream("recording-" + Date.now().toString() + ".mp4"); livestream.stream?.pipe(output); // Stop after the requested duration. setTimeout(() => { livestream.stop(); output.end(); console.log("Recording complete."); }, durationMs); } ``` ```