Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

rtsp-relay

k-yle4kMIT1.9.0TypeScript support: included

📽 Relay an RTSP stream through an existing express.js server

rtsp, rtsp-stream, stream, websocket, ws, express, ffmpeg, jsmpeg

readme

📽 RTSP Relay

Build Status Coverage Status npm version npm bundle size

This module allows you to view an RTSP stream in your web browser using an existing express.js server.

Internally, this module uses websockets to create an endpoint in your web server (e.g. /api/stream) which relays the RTSP stream using ffmpeg. On the client side, JS-MPEG is used to decode the websocket stream.

The module handles all the complications that unreliable connections introduce:

  • if the connection between server <=> RTSP stream is disconnected, it will automatically be reconnected when available
  • if the connection between client <=> server is disconnected, the client will keep trying to reconnect
  • if multiple clients connect, only one instance of the RTSP stream is consumed to improve performance (one-to-many)

Install

npm install -S rtsp-relay express

You don't need to install ffmpeg!

Example

const express = require('express');
const app = express();

const { proxy, scriptUrl } = require('rtsp-relay')(app);

const handler = proxy({
  url: `rtsp://admin:admin@10.0.1.2:554/feed`,
  // if your RTSP stream need credentials, include them in the URL as above
  verbose: false,
});

// the endpoint our RTSP uses
app.ws('/api/stream', handler);

// this is an example html page to view the stream
app.get('/', (req, res) =>
  res.send(`
  <canvas id='canvas'></canvas>

  <script src='${scriptUrl}'></script>
  <script>
    loadPlayer({
      url: 'ws://' + location.host + '/api/stream',
      canvas: document.getElementById('canvas')
    });
  </script>
`),
);

app.listen(2000);

Open http://localhost:2000 in your web browser.

Example using ES6 Imports (e.g. React, Vue)

If you have babel/webpack set up, you can import the loadPlayer instead of using a <script> tag.

Example code is available for react and for angular.

// 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!'),
});

Usage with many cameras

If you have hundreds of cameras and don't want to define a seperate route for each one, you can use a dynamic URL:

app.ws('/api/stream/:cameraIP', (ws, req) =>
  proxy({
    url: `rtsp://${req.params.cameraIP}:554/feed`,
  })(ws),
);

Usage with many clients

You may see a MaxListenersExceededWarning if the relay is re-transmitting 10+ streams at once, or if 10+ clients are watching.

This is expected, and you can silence the warning by adding process.setMaxListeners(0); to your code.

Improving the video quality

Depending on your network configuration, you can try the following options to improve the stream quality:

// try this:
app.ws('/api/stream', proxy({ additionalFlags: ['-q', '1'] }));

// or this:
app.ws('/api/stream', proxy({ transport: 'tcp' }));

Note that both these methods will use more bandwidth.

SSL

If you want to use HTTPS, you will need to change the stream URL to wss://, like the following example:

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(`
  <canvas id='canvas'></canvas>

  <script src='${scriptUrl}'></script>
  <script>
    loadPlayer({
      url: 'wss://' + location.host + '/api/stream',
      canvas: document.getElementById('canvas')
    });
  </script>
`),
);

server.listen(443);

Contributing

We have end-to-end tests to ensure that the module actually works. These tests spin up a RTSP server using aler9/rtsp-simple-server and create several different streams for testing. These tests are far from complete.

To make developing easier, run node test/setupTests. This creates two RTSP streams that can be used instead of real IP cameras (rtsp://localhost:8554/sync-test-1 and rtsp://localhost:8554/sync-test-2).

changelog

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

1.9.0 (2024-06-01)

  • feat: added new option called useNativeFFmpeg to bypass the bundled version of ffmpeg (#262)
  • fix: issue where the video was invisible (#202)

1.8.0 (2023-10-31)

  • feat: update ffmpeg from v4.1 (2018) to v6.0 (2023) to support HEVC streams (#52, #81, #171, #235)
  • chore: run tests on node21, stop testing on node14

1.7.0 (2023-03-04)

  • feat: pass the player object to the onDisconnect callback

1.6.1 (2021-11-04)

  • fix: incorrect statuses logged in verbose mode (#111)

1.6.0 (2021-10-27)

  • feat: make the windowsHide property configurable (defaults to true) - #108
  • chore: run tests on node17, stop testing on node10

1.5.1 (2021-07-27)

  • fix: fix bug with RTSP transport option (#89)

1.5.0 (2021-07-14)

  • feat: add option to specify RTSP transport protocol (#85)

1.4.1 (2021-06-18)

  • fix: fix streams not being killed when there are multiple users and multiple streams (#74)

1.4.0 (2021-03-04)

  • feat: add onDisconnect option to loadPlayer

1.3.0 (2021-02-21)

  • feat: create a new loadPlayer method for creating the canvas on the client-side

1.2.0 (2021-02-13)

  • feat: support HTTPS on the server

1.1.3 (2021-02-13)

  • feat: generate & publish .d.ts files in addition to the existing JSDoc types

1.1.2 (2021-02-06)

  • perf: performance improvements
  • chore: set up automated dependency updates

1.1.1 (2021-02-02)

  • fix: fix bug on windows

1.1.0 (2021-01-20)

  • feat: support multiple different simultaneous streams
  • chore: add end-to-end tests
  • chore: don't run CI tests on node v8 anymore
  • chore: add tests for JSDoc types

1.0.6 (2020-08-16)

  • chore: typecheck the JS code with TypeScript's checkJs mode

1.0.5 (2020-07-20)

  • chore: dependabot security update for devDependencies

1.0.4 (2020-07-20)

  • feat: bundle ffmpeg

1.0.3 (2020-03-16)

  • perf: performance improvements

1.0.2 (2020-01-27)

  • perf: performance improvements

1.0.1 (2020-01-26)

  • fix: bug fixes

1.0.0 (2020-01-26)

  • Initial release