### Proxy Configuration Example Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/types.md Example of how to configure and use the proxy function with specific options. Ensure the URL includes credentials if required. ```javascript const options = { url: 'rtsp://admin:pass@192.168.1.50:554/stream1', transport: 'tcp', additionalFlags: ['-q', '1'], verbose: true, windowsHide: true }; const handler = proxy(options); ``` -------------------------------- ### Concurrent WebSocket Connections Example Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/architecture.md Illustrates how multiple clients can call handlers concurrently. Each 'get()' call increments a counter before spawning, ensuring clients do not race. ```text Client 1 → handler(ws1) → get() → clients++ (1) Client 2 → handler(ws2) → get() → clients++ (2) Client 3 → handler(ws3) → get() → clients++ (3) ``` -------------------------------- ### InboundStreamWrapper start() Method Options Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/architecture.md This object defines the options for starting an InboundStreamWrapper. Ensure the 'url' property is provided. 'additionalFlags' can be used to pass custom FFmpeg arguments. ```typescript start({ url, additionalFlags = [], transport, windowsHide = true, useNativeFFmpeg, }) ``` -------------------------------- ### Main Module Initialization Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/README.md Initialize the main server-side module to get access to proxy and killAll functions. This is typically done once when your Express server starts. ```javascript const rtspRelay = require('rtsp-relay'); const { proxy, scriptUrl, killAll } = rtspRelay(app, server); ``` -------------------------------- ### RelayAPI Example Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/types.md Initialize the rtsp-relay server and configure stream proxying using the RelayAPI. This example demonstrates setting up an Express.js server to handle RTSP streams and serve the relay script. ```javascript const rtspRelay = require('rtsp-relay'); const express = require('express'); const app = express(); const { proxy, scriptUrl, killAll } = rtspRelay(app); // Use proxy function app.ws('/api/stream', proxy({ url: 'rtsp://camera.local:554/feed' })); // Use scriptUrl in HTML app.get('/', (req, res) => { res.send(``); }); // Cleanup on shutdown process.on('SIGTERM', killAll); ``` -------------------------------- ### HTML Canvas Setup and Player Initialization Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/types.md Shows how to set up an HTML canvas element and initialize the browser-side player using the loadPlayer function. ```html ``` -------------------------------- ### Start and Get Stream Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/architecture.md Increments client count and starts the FFmpeg stream if it doesn't exist. Returns the stream's stdout for piping. ```typescript get(options) { this.verbose = options.verbose; this.clients += 1; if (!this.stream) this.start(options); return this.stream; } ``` -------------------------------- ### Server-Side Setup with Express.js Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/README.md Initializes the rtsp-relay library, creates a WebSocket endpoint for an RTSP stream, and serves basic HTML with a client-side player. ```javascript const express = require('express'); const rtspRelay = require('rtsp-relay'); const app = express(); const { proxy, scriptUrl } = rtspRelay(app); // Create WebSocket endpoint for RTSP stream app.ws('/api/stream', proxy({ url: 'rtsp://camera.local:554/stream', transport: 'tcp', verbose: false })); // Serve player HTML app.get('/', (req, res) => { res.send( '' + `` + ' `, ), ); app.listen(2000); ``` -------------------------------- ### Basic Stream Display Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/configuration.md Loads a player with the essential URL and canvas element. This is the most common way to start displaying a stream. ```javascript const player = await loadPlayer({ url: 'ws://' + location.host + '/api/stream', canvas: document.getElementById('canvas') }); ``` -------------------------------- ### Node.js Server for HTTPS/WSS with Self-Signed Certs Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/integration-examples.md Set up a Node.js server using Express to handle RTSP streams over WSS with HTTPS. This example requires self-signed SSL certificates for secure connections and assumes the 'rtsp-relay' package is installed. ```javascript const express = require('express'); const https = require('https'); const fs = require('fs'); const rtspRelay = require('rtsp-relay'); const app = express(); // Load SSL certificates const key = fs.readFileSync('/etc/ssl/private/server.key'); const cert = fs.readFileSync('/etc/ssl/certs/server.crt'); const httpsServer = https.createServer({ key, cert }, app); // Initialize with https server for WSS support const { proxy, scriptUrl } = rtspRelay(app, httpsServer); // Register camera streams app.ws('/api/stream', proxy({ url: 'rtsp://camera.local:554/feed', verbose: false })); // Serve UI app.get('/', (req, res) => { res.send(` Secure Camera Stream `); }); httpsServer.listen(443, () => { console.log('Secure rtsp-relay server running on https://localhost:443'); }); ``` ```bash openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes ``` -------------------------------- ### Camera Configuration JSON Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/integration-examples.md Example JSON file for configuring camera streams. It specifies the RTSP URL, transport protocol, and optional additional flags for each camera. ```json { "front": { "rtsp_url": "rtsp://admin:password@192.168.1.50:554/stream", "transport": "tcp" }, "back": { "rtsp_url": "rtsp://admin:password@192.168.1.51:554/stream", "transport": "tcp" }, "parking": { "rtsp_url": "rtsp://admin:password@192.168.1.52:554/stream", "transport": "tcp", "additionalFlags": ["-q", "2"] } } ``` -------------------------------- ### Vue Usage Example for StreamPlayer Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/integration-examples.md An example of how to use the StreamPlayer component in a parent Vue component. It demonstrates dynamic camera selection and quality control. ```vue ``` -------------------------------- ### Configure RTSP Relay with Environment Variables Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/configuration.md Map environment variables to rtsp-relay configuration options programmatically. This example shows how to set the stream URL, verbosity, and transport protocol. ```javascript const rtspRelay = require('rtsp-relay'); const express = require('express'); const app = express(); const { proxy } = rtspRelay(app); const streamUrl = process.env.RTSP_URL || 'rtsp://192.168.1.50:554/stream'; const verbose = process.env.VERBOSE === 'true'; const transport = process.env.RTSP_TRANSPORT || 'tcp'; app.ws('/api/stream', proxy({ url: streamUrl, verbose: verbose, transport: transport })); ``` -------------------------------- ### Load Player with High Quality and TCP Transport Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/api-reference/browser-player.md Configures a player for high-quality streaming using specific options for bandwidth and performance. This example disables audio to reduce bandwidth, enables WebAssembly for efficient decoding, and sets a larger video buffer for higher bitrates. It also includes a simple destroy callback on disconnect. ```javascript const player = await loadPlayer({ url: 'wss://secure.example.com/api/stream', canvas: document.getElementById('canvas'), audio: false, // Reduce bandwidth for video-only disableWebAssembly: false, // Use WebAssembly for performance videoBufferSize: 1048576, // 1MB buffer for higher bitrates onDisconnect: (p) => p.destroy() }); ``` -------------------------------- ### Player Class Properties Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/api-reference/browser-player.md The `Player` class exposes properties to get or set the audio volume and the current playback position. ```APIDOC ### Properties #### volume Get or set the audio volume. ```typescript get volume(): number set volume(value: number): void ``` **Type**: number **Valid Range**: 0 (silent) to 1 (full volume) ### Example ```js player.volume = 0.5; // 50% volume console.log(player.volume); // 0.5 ``` --- #### currentTime Get or set the current playback position in seconds. ```typescript get currentTime(): number set currentTime(seconds: number): void ``` **Type**: number ### Notes - Only applies to static/static-file sources. - On live RTSP streams, seeking has no effect. ### Example ```js player.currentTime = 10; // Seek to 10 seconds console.log(`Playing at ${player.currentTime}s`); ``` --- #### paused Get whether playback is currently paused. ```typescript get paused(): boolean ``` **Type**: boolean (read-only) ### Example ```js if (player.paused) { console.log('Playback is paused'); player.play(); } ``` ``` -------------------------------- ### Using System FFmpeg Configuration Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/configuration.md Configure rtsp-relay to use the system's FFmpeg installation instead of the bundled version. Set 'useNativeFFmpeg' to true and ensure FFmpeg is in your system's PATH. ```javascript const { proxy } = rtspRelay(app); app.ws('/api/stream', proxy({ url: 'rtsp://192.168.1.50:554/stream', useNativeFFmpeg: true, // Use your system's ffmpeg verbose: true })); ``` -------------------------------- ### FFmpeg Tuning: Control Bitrate Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/configuration.md Configure FFmpeg to control video bitrate for performance tuning. This example sets both the base video bitrate and the maximum allowed bitrate. ```javascript proxy({ url: 'rtsp://camera:554/stream', additionalFlags: [ '-b:v', '2M', // Video bitrate '-maxrate', '2.5M' // Maximum bitrate ] }) ``` -------------------------------- ### Add FFmpeg Scaling Flag for Resizing Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/architecture.md To resize video, add an FFmpeg scaling flag to the additionalFlags. This example scales the video to 640x480. ```javascript additionalFlags: ['-vf', 'scale=640:480'] ``` -------------------------------- ### Express Server with Script Tag Integration Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/integration-examples.md This example demonstrates setting up an Express.js server to proxy RTSP streams and serve them to a web page using a CDN script tag. It's suitable for projects that do not require a build process. ```javascript const express = require('express'); const rtspRelay = require('rtsp-relay'); const app = express(); const { proxy, scriptUrl } = rtspRelay(app); // Serve static files app.use(express.static('public')); // Create stream endpoints for multiple cameras const cameras = { 'front': 'rtsp://admin:pass@192.168.1.50:554/stream', 'back': 'rtsp://admin:pass@192.168.1.51:554/stream', 'parking': 'rtsp://admin:pass@192.168.1.52:554/stream' }; Object.entries(cameras).forEach(([name, url]) => { app.ws(`/stream/${name}`, proxy({ url, verbose: false })); }); // Serve camera list page app.get('/', (req, res) => { const cameraList = Object.keys(cameras).map(name => `

${name}

`).join(''); res.send(` Camera Streams

Live Cameras

${cameraList} `); }); app.listen(2000, () => console.log('Server running on http://localhost:2000')); ``` ```bash node server.js ``` -------------------------------- ### Basic Single Stream WebSocket Endpoint Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/endpoints.md Sets up a basic WebSocket endpoint to relay a single RTSP stream. This is the foundational example for exposing a camera feed. ```javascript const { proxy } = rtspRelay(app); app.ws('/api/stream', proxy({ url: 'rtsp://camera.local:554/feed' })); ``` -------------------------------- ### Fix FFmpeg Not Found Error Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/errors.md Ensure FFmpeg is accessible. Install 'ffmpeg-static' for bundled usage or verify system FFmpeg is in PATH when 'useNativeFFmpeg' is true. ```javascript // If using ffmpeg-static (default): npm install ffmpeg-static // If using system ffmpeg: // Make sure ffmpeg is in PATH, or proxy({ url: 'rtsp://camera:554/stream', useNativeFFmpeg: false // Use bundled ffmpeg-static instead }) ``` -------------------------------- ### HTTPS RTSP Relay Server Setup Source: https://github.com/k-yle/rtsp-relay/blob/main/README.md Sets up an Express.js server with HTTPS to proxy RTSP streams. Requires SSL certificates and uses `wss://` for the client-side connection URL. The `scriptUrl` is also provided for client-side integration. ```javascript const rtspRelay = require('rtsp-relay'); const express = require('express'); const https = require('https'); const fs = require('fs'); const key = fs.readFileSync('./privatekey.pem', 'utf8'); const cert = fs.readFileSync('./fullchain.pem', 'utf8'); const ca = fs.readFileSync('./chain.pem', 'utf8'); // required for iOS 15+ const app = express(); const server = https.createServer({ key, cert, ca }, app); const { proxy, scriptUrl } = rtspRelay(app, server); app.ws('/api/stream', proxy({ url: 'rtsp://1.2.3.4:554' })); app.get('/', (req, res) => res.send( ` `, ), ); server.listen(443); ``` -------------------------------- ### Dockerfile for RTSP Relay Application Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/integration-examples.md A Dockerfile to build an image for the RTSP Relay application. It installs production dependencies and copies the application code. ```dockerfile FROM node:18-alpine WORKDIR /app # Copy package files COPY package*.json ./ # Install dependencies RUN npm ci --only=production # Copy application code COPY . . # Expose port EXPOSE 2000 ``` -------------------------------- ### FFmpeg Tuning: Set Audio Codec Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/configuration.md Specify the audio codec for FFmpeg processing using the `-c:a` flag in `additionalFlags`. This example sets the audio codec to AAC. ```javascript proxy({ url: 'rtsp://camera:554/stream', additionalFlags: [ '-c:a', 'aac' // Use AAC audio codec ] }) ``` -------------------------------- ### loadPlayer Function Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/api-reference/browser-player.md The `loadPlayer` function is the primary interface for initializing and loading a video player in the browser. It handles the underlying library setup and returns a `Player` instance. ```APIDOC ## Function: loadPlayer ### Description Initializes and loads a video player in the browser. This is the main entry point for using the player. ### Parameters #### Options Object - **url** (string) - Required - The URL of the RTSP stream or video source. - **canvas** (HTMLCanvasElement) - Required - The canvas element to render the video on. - **onDisconnect** (function) - Optional - A callback function to execute when the stream disconnects. It receives the player instance as an argument. - **disconnectThreshold** (number) - Optional - The time in milliseconds to wait before considering the stream disconnected. - **audio** (boolean) - Optional - Whether to enable audio playback. Defaults to true. - **disableWebAssembly** (boolean) - Optional - Whether to disable WebAssembly for decoding. Defaults to false. - **videoBufferSize** (number) - Optional - The size of the video buffer in bytes. Useful for higher bitrates. ### Returns A Promise that resolves with a `Player` instance. ### Example: Basic Usage ```js import { loadPlayer } from 'rtsp-relay/browser'; const canvas = document.getElementById('myCanvas'); const player = await loadPlayer({ url: 'ws://' + location.host + '/api/stream', canvas: canvas }); ``` ### Example: With Disconnect Detection ```js import { loadPlayer } from 'rtsp-relay/browser'; const canvas = document.getElementById('myCanvas'); const player = await loadPlayer({ url: 'ws://' + location.host + '/api/stream', canvas: canvas, onDisconnect: (playerInstance) => { console.log('Stream disconnected'); }, disconnectThreshold: 5000 // 5 seconds }); ``` ``` -------------------------------- ### Set and Get Player Volume Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/api-reference/browser-player.md Allows getting or setting the audio volume for the player. The volume is represented as a number between 0 (silent) and 1 (full volume). ```typescript player.volume = 0.5; // 50% volume console.log(player.volume); // 0.5 ``` -------------------------------- ### loadPlayer Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/api-reference/browser-player.md Asynchronously creates and initializes a video player for stream playback. It takes an options object to configure the player and returns a Promise that resolves to a Player instance. ```APIDOC ## Function: loadPlayer Asynchronously creates and initializes a video player for stream playback. ### Signature ```typescript async function loadPlayer(options: PlayerOptions): Promise ``` ### Parameters #### Request Body - **url** (string) - Required - WebSocket URL pointing to the relay endpoint. Must start with `ws://` or `wss://`. - **canvas** (HTMLCanvasElement) - Required - HTML canvas element where the video will be rendered. - **audio** (boolean) - Optional - Whether to decode and play audio. Set to false for audio-less playback (saves bandwidth). Defaults to `true`. - **video** (boolean) - Optional - Whether to decode and display video frames. Set to false for audio-only playback. Defaults to `true`. - **autoplay** (boolean) - Optional - Automatically start playback when the source is established. Only applies to static sources, not streams. Defaults to `false`. - **loop** (boolean) - Optional - Loop video playback. Only applies to static sources, not live RTSP streams. Defaults to `true`. - **poster** (string) - Optional - URL to an image displayed before playback starts. - **pauseWhenHidden** (boolean) - Optional - Pause playback when the browser tab is inactive. Resumes when tab becomes active. Defaults to `true`. - **disableGl** (boolean) - Optional - Disable WebGL rendering and always use Canvas2D. Use if WebGL causes compatibility issues. Defaults to `false`. - **disableWebAssembly** (boolean) - Optional - Disable WebAssembly decoders and use pure JavaScript decoders. Slower but more compatible. Defaults to `false`. - **preserveDrawingBuffer** (boolean) - Optional - Preserve WebGL drawing buffer. Required for taking screenshots via `canvas.toDataURL()`. Increases memory usage. Defaults to `false`. - **progressive** (boolean) - Optional - Load data in chunks rather than all at once. Only applies to static sources. Defaults to `true`. - **throttled** (boolean) - Optional - Defer loading chunks when not needed for playback. Only applies to progressive static sources. Defaults to `true`. - **chunkSize** (number) - Optional - Size in bytes of each chunk to load (1MB default). Only applies to progressive static sources. Defaults to `1048576`. - **decodeFirstFrame** (boolean) - Optional - Decode and display the first video frame before playback starts. Sets up canvas size and provides a poster. Defaults to `true`. - **maxAudioLag** (number) - Optional - Maximum enqueued audio length in seconds for streaming sources. - **videoBufferSize** (number) - Optional - Video decode buffer size in bytes (512KB default). Increase for very high bitrates. Defaults to `524288`. - **audioBufferSize** (number) - Optional - Audio decode buffer size in bytes (128KB default). Increase for very high bitrates. Defaults to `131072`. - **onVideoDecode** (function) - Optional - Callback invoked after each decoded and rendered video frame. Signature: `(decoder: unknown, time: unknown) => void`. - **onAudioDecode** (function) - Optional - Callback invoked after each decoded audio frame. Signature: `(decoder: unknown, time: unknown) => void`. - **onPlay** (function) - Optional - Callback when playback starts. Signature: `(player: Player) => void`. - **onPause** (function) - Optional - Callback when playback pauses. Signature: `(player: Player) => void`. - **onEnded** (function) - Optional - Callback when playback reaches the end (static sources only). Signature: `(player: Player) => void`. - **onStalled** (function) - Optional - Deprecated. Callback when there's insufficient data for playback. - **onSourceEstablished** (function) - Optional - Callback when the source receives initial data. Signature: `(source: unknown) => void`. - **onSourceCompleted** (function) - Optional - Callback when the source receives all data. Signature: `(source: unknown) => void`. - **onDisconnect** (function) - Optional - Callback when the stream disconnects (no data received for `disconnectThreshold` ms). Signature: `(player: Player) => void`. Cannot be used with `onVideoDecode`. - **disconnectThreshold** (number) - Optional - Time in milliseconds before considering the stream disconnected. Default 3 seconds. Only used when `onDisconnect` is provided. Defaults to `3000`. ### Returns A Promise that resolves to a [`Player`](#class-player) instance when the stream is ready for display. **Important**: You must await the Promise before using the Player, or before creating multiple players. ### Throws - Rejects with `Error('You cannot specify both onDisconnect and onVideoDecode')` if both callbacks are provided. ### Example ```js import { loadPlayer } from 'rtsp-relay/browser'; const canvas = document.getElementById('myCanvas'); const player = await loadPlayer({ url: 'ws://' + location.host + '/api/stream', canvas: canvas }); // Player is ready, video is rendering ``` ``` -------------------------------- ### Load Player for Screenshot Capture Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/configuration.md Set up the player to enable screenshot functionality by preserving the drawing buffer. This is necessary before calling `toDataURL()` on the canvas. ```javascript const player = await loadPlayer({ url: 'ws://' + location.host + '/api/stream', canvas: document.getElementById('canvas'), preserveDrawingBuffer: true // Required for toDataURL() }); // Later, take a screenshot const imageData = canvas.toDataURL('image/jpeg'); ``` -------------------------------- ### Set and Get Current Playback Time Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/api-reference/browser-player.md Enables getting or setting the current playback position in seconds. Note that seeking is only effective for static or file-based sources; it has no effect on live RTSP streams. ```typescript player.currentTime = 10; // Seek to 10 seconds console.log(`Playing at ${player.currentTime}s`); ``` -------------------------------- ### Load JSMpeg Player and Initialize Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/architecture.md This function loads the JSMpeg library, creates a Player instance, and handles disconnect detection. It resolves when the player is ready. ```javascript async function loadPlayer(options) { // 1. Load JSMpeg library if not already loaded await importJSMpeg(); // 2. Create Player instance const player = new window.JSMpeg.Player(url, { canvas: options.canvas, audio: options.audio, // ... other options }); // 3. Handle disconnect detection if (options.onDisconnect) { const interval = setInterval(() => { if (Date.now() - lastRx > disconnectThreshold) { options.onDisconnect(player); } }, disconnectThreshold / 2); } // 4. Resolve when ready return Promise that resolves when player is ready } ``` -------------------------------- ### Load RTSP Stream Player Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/api-reference/browser-player.md Asynchronously creates and initializes a video player for stream playback. Requires a WebSocket URL and a canvas element. Await the returned Promise before using the player. ```typescript async function loadPlayer(options: PlayerOptions): Promise ``` ```javascript import { loadPlayer } from 'rtsp-relay/browser'; const canvas = document.getElementById('myCanvas'); const player = await loadPlayer({ url: 'ws://' + location.host + '/api/stream', canvas: canvas }); // Player is ready, video is rendering ``` -------------------------------- ### WebSocketHandler Type Definition Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/types.md Defines the signature for a WebSocket handler function. This handler is synchronous and starts streaming immediately upon receiving a WebSocket connection. ```typescript type WebSocketHandler = (ws: WebSocket) => void ``` -------------------------------- ### Browser Player Options Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/types.md Configuration options for initializing the browser player using `loadPlayer()`. These options control video rendering, playback behavior, and event handling. ```APIDOC ## Browser Player Options ### Description Configuration options for initializing the browser player using `loadPlayer()`. These options control video rendering, playback behavior, and event handling. ### Parameters #### Request Body - **url** (string) - Yes - WebSocket URL of the relay endpoint. Must start with `ws://` or `wss://`. - **canvas** (HTMLCanvasElement) - Yes - HTML canvas element for video rendering. - **loop** (boolean) - No - Auto-replay when video ends. Only applies to static files. Defaults to true. - **autoplay** (boolean) - No - Start playing immediately when source loads. Only applies to static files. Defaults to false. - **audio** (boolean) - No - Decode and play audio track. Defaults to true. Set false to reduce bandwidth. - **video** (boolean) - No - Decode and render video frames. Defaults to true. - **poster** (string) - No - Image URL to display before playback starts. - **pauseWhenHidden** (boolean) - No - Pause when tab is inactive. Browsers throttle inactive tabs anyway. Defaults to true. - **disableGl** (boolean) - No - Disable WebGL and use Canvas2D rendering instead. Use for compatibility. Defaults to false. - **disableWebAssembly** (boolean) - No - Disable WebAssembly decoders, use JavaScript instead. Slower but more compatible. Defaults to false. - **preserveDrawingBuffer** (boolean) - No - Preserve WebGL drawing buffer for screenshots via canvas.toDataURL(). Increases memory. Defaults to false. - **progressive** (boolean) - No - Load data progressively in chunks rather than all at once. Only for static sources. Defaults to true. - **throttled** (boolean) - No - Defer chunk loading when not immediately needed. Only for progressive static sources. Defaults to true. - **chunkSize** (number) - No - Bytes per chunk when loading progressively. Only for static sources. Defaults to 1048576 (1MB). - **decodeFirstFrame** (boolean) - No - Display first frame before playback (sets canvas size, provides poster). Defaults to true. - **maxAudioLag** (number) - No - Maximum queued audio in seconds for streaming. Prevents audio lag on slow connections. - **videoBufferSize** (number) - No - Video decoder buffer in bytes. Increase for high bitrate streams. Defaults to 524288 (512KB). - **audioBufferSize** (number) - No - Audio decoder buffer in bytes. Increase for high bitrate streams. Defaults to 131072 (128KB). - **onVideoDecode** (function) - No - Called after each video frame decodes and renders. Signature: `(decoder, time) => void`. - **onAudioDecode** (function) - No - Called after each audio frame decodes. Signature: `(decoder, time) => void`. - **onPlay** (function) - No - Called when playback starts. Signature: `(player) => void`. - **onPause** (function) - No - Called when playback pauses. Signature: `(player) => void`. - **onEnded** (function) - No - Called when static video finishes. Signature: `(player) => void`. - **onStalled** (function) - No - Deprecated. Called when data is insufficient. Signature: `(player) => void`. - **onSourceEstablished** (function) - No - Called when source receives initial data. Signature: `(source) => void`. - **onSourceCompleted** (function) - No - Called when all data is received. Signature: `(source) => void`. - **onDisconnect** (function) - No - Called when stream disconnects (no data for `disconnectThreshold` ms). Signature: `(player) => void`. Cannot be used with `onVideoDecode`. - **disconnectThreshold** (number) - No - Milliseconds of no data before triggering disconnect callback. Defaults to 3000 (3 seconds). ### Request Example ```js const options = { url: 'ws://localhost:2000/api/stream', canvas: document.getElementById('video'), audio: false, // Video only onDisconnect: (player) => { console.log('Stream lost'); player.destroy(); }, disconnectThreshold: 5000 }; const player = await loadPlayer(options); ``` ``` -------------------------------- ### Multiple Cameras with Named Routes Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/endpoints.md Sets up WebSocket endpoints using named routes for different cameras, mapping names to their respective RTSP stream URLs. ```javascript const { proxy } = rtspRelay(app); const cameras = { 'front': 'rtsp://192.168.1.50:554/stream', 'back': 'rtsp://192.168.1.51:554/stream', 'parking': 'rtsp://192.168.1.52:554/stream' }; app.ws('/api/stream/:cameraName', (ws, req) => { const url = cameras[req.params.cameraName]; if (!url) { ws.close(4004, 'Camera not found'); return; } proxy({ url })(ws); }); ``` -------------------------------- ### Client Usage for Named Routes Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/endpoints.md Demonstrates client connections to named camera streams via WebSocket, using the defined route names in the URL. ```javascript const frontCamera = await loadPlayer({ url: 'ws://localhost:2000/api/stream/front', canvas: document.getElementById('front-camera') }); const backCamera = await loadPlayer({ url: 'ws://localhost:2000/api/stream/back', canvas: document.getElementById('back-camera') }); ``` -------------------------------- ### Client-Side Player with ES6 Imports Source: https://github.com/k-yle/rtsp-relay/blob/main/README.md Demonstrates how to use the `loadPlayer` function directly in client-side JavaScript, suitable for modern frameworks like React or Vue. Includes optional callbacks for connection events. ```javascript // client side code import { loadPlayer } from 'rtsp-relay/browser'; loadPlayer({ url: `ws://${location.host}/stream`, canvas: document.getElementById('canvas'), // optional onDisconnect: () => console.log('Connection lost!'), }); ``` -------------------------------- ### Client Usage for Dynamic URL Parameter Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/endpoints.md Illustrates how clients can connect to dynamically specified camera streams by including the camera's IP address in the WebSocket URL. ```javascript // Connect to camera at 192.168.1.50 const player = await loadPlayer({ url: 'ws://localhost:2000/api/stream/192.168.1.50', canvas: document.getElementById('canvas') }); // Connect to camera at 192.168.1.51 const player2 = await loadPlayer({ url: 'ws://localhost:2000/api/stream/192.168.1.51', canvas: document.getElementById('canvas2') }); ``` -------------------------------- ### Override Frame Rate with FFmpeg Flag Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/architecture.md Users can override the default 30 fps frame rate by providing additional FFmpeg flags. This example sets the frame rate to 15 fps. ```javascript additionalFlags: ['-r', '15'] ``` -------------------------------- ### Load Multiple Simultaneous Players Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/api-reference/browser-player.md Demonstrates how to load and manage multiple player instances concurrently. Players are created sequentially by awaiting each loadPlayer call, ensuring proper initialization before proceeding. This is useful for displaying multiple video streams on the same page. ```javascript import { loadPlayer } from 'rtsp-relay/browser'; // Create players sequentially, awaiting each one const canvas1 = document.getElementById('canvas1'); const canvas2 = document.getElementById('canvas2'); const player1 = await loadPlayer({ url: 'ws://' + location.host + '/api/stream/camera1', canvas: canvas1 }); const player2 = await loadPlayer({ url: 'ws://' + location.host + '/api/stream/camera2', canvas: canvas2 }); // Both players are now rendering ``` -------------------------------- ### Endpoint with Query Parameters for Quality and Transport Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/endpoints.md Sets up a WebSocket endpoint that accepts query parameters to control stream quality and transport protocol (TCP/UDP). ```javascript const { proxy } = rtspRelay(app); app.ws('/api/stream/:cameraIP', (ws, req) => { const { quality, transport } = req.query; const flags = []; if (quality === 'high') { flags.push('-q', '1'); } else if (quality === 'low') { flags.push('-q', '2'); } proxy({ url: `rtsp://${req.params.cameraIP}:554/stream`, transport: transport || 'tcp', additionalFlags: flags, verbose: process.env.DEBUG === 'true' })(ws); }); ``` -------------------------------- ### Vue.js Component for RTSP Stream Playback Source: https://github.com/k-yle/rtsp-relay/blob/main/examples/vue.md This Vue.js component uses the rtsp-relay library to load and display an RTSP stream on a canvas element. Ensure the 'rtsp-relay/browser' module is installed and the WebSocket server is running. ```vue ``` -------------------------------- ### React Component for RTSP Stream Source: https://github.com/k-yle/rtsp-relay/blob/main/test/static/react.html This snippet shows a React functional component that uses `useRef` to get a canvas element and `useEffect` to initialize the rtsp-relay player. It connects to a local RTSP stream and renders it onto the canvas. ```javascript /* global React, ReactDOM, loadPlayer */ const App = () => { const canvas = React.useRef(null); React.useEffect(() => { if (!canvas.current) throw new Error('Ref is null'); loadPlayer({ url: 'ws://localhost:2000/api/stream/2', canvas: canvas.current, }); }, []); return ; }; ReactDOM.createRoot(document.querySelector('main')).render(); ``` -------------------------------- ### Load and Control Browser Player Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/INDEX.md Demonstrates how to load the player in a browser, control playback, and access playback state. Ensure the canvas element exists before calling loadPlayer. ```typescript // Load player const player = await loadPlayer({ url: string, // WebSocket URL (required) canvas: HTMLCanvasElement, // Video canvas (required) audio?: boolean, // Decode audio video?: boolean, // Decode video onDisconnect?: (player) => void, // Disconnect callback disconnectThreshold?: number, // Silence timeout (ms) videoBufferSize?: number, // Video buffer (bytes) audioBufferSize?: number, // Audio buffer (bytes) // ... other options }); // Playback control player.play(); player.pause(); player.stop(); player.destroy(); // Clean up when done // Playback state player.volume = 0.5; player.currentTime = 10; if (player.paused) { /* ... */ } ``` -------------------------------- ### Initialize RTSP Relay and Create Handler Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/INDEX.md Initializes the rtsp-relay server and creates a stream handler with various configuration options. Use this to set up a new RTSP stream endpoint. ```typescript const { proxy, scriptUrl, killAll } = rtspRelay(app, server?); // Create handler const handler = proxy({ url: string, // RTSP source URL (required) transport?: 'tcp' | 'udp' | ... // RTSP transport protocol verbose?: boolean, // Enable logging additionalFlags?: string[], // Extra ffmpeg arguments windowsHide?: boolean, // Hide ffmpeg window (Windows) useNativeFFmpeg?: boolean // Use system ffmpeg }); // Register endpoint app.ws('/api/stream', handler); // Cleanup all processes killAll(); ``` -------------------------------- ### Initialize RTSP Relay with HTTP Server Source: https://github.com/k-yle/rtsp-relay/blob/main/_autodocs/api-reference/main-module.md Sets up the rtsp-relay module with an Express application and an HTTP server. It then defines a WebSocket handler for an RTSP stream and serves an HTML page with a player that connects to this stream. ```javascript const express = require('express'); const rtspRelay = require('rtsp-relay'); const app = express(); const { proxy, scriptUrl } = rtspRelay(app); const handler = proxy({ url: 'rtsp://admin:admin@192.168.1.100:554/stream' }); app.ws('/api/stream', handler); app.get('/', (req, res) => { res.send( ` ` ); }); app.listen(2000); ```