- Does not depend on any other third-party packages at a production environment.
- Small bundle size
- Fluent Interface
- Event Emitter
- Very customizable
This library spawns ffmpeg
as a child process, so it won't work with no ffmpeg
installed.
To do so just type:
sudo apt update
sudo apt install -y ffmpeg
If you prefer different package manager or work on different linux distr use appropriate to your system command.
Installation process of this lib as simple as it can be. Just run
npm i --save rtsp-video-recorder
After that you can use it like on example below
import Recorder, { RecorderEvents } from 'rtsp-video-recorder';
const recorder = new Recorder('rtsp://username:password@host/path', '/media/Recorder', {
title: 'Test Camera',
});
if you application is a CommonJs module you should be able do the same this way:
const {Recorder, RecorderEvents} = require('rtsp-video-recorder');
const recorder = new Recorder('rtsp://username:password@host/path', '/media/Recorder', {
title: 'Test Camera',
});
recorder.start();
recorder.stop();
You can execute isRecording
method on recorder instance which returns boolean value
recorder.isRecording();
It also supports Fluent Interface
import Recorder, { RecorderEvents } from 'rtsp-video-recorder';
new Recorder('rtsp://username:password@host/path', '/media/Recorder')
.on(RecorderEvents.STARTED, onStarted)
.on(RecorderEvents.STOPPED, onStopped)
.on(RecorderEvents.FILE_CREATED, onFileCreated)
.start();
RTSP stream URI.
e.g. rtsp://username:password@host/path
Path to the directory for video records. It may be relative but better to define it in absolute manner.
Title of video file. Used as metadata of video file.
The name you want your playlist file to have.
By default the name is going to be a datetime string in a format Y.m.d-H.M.S
(e.g. 2020.01.03-03.19.15
) which represents the time playlist have been created.
File path pattern. By default it is %Y.%m.%d/%H.%M.%S
which will be translated to e.g. 2020.01.03/03.19.15
Accepts C++ strftime specifiers:
Duration of one video file (in seconds).
600 seconds or 10 minutes by default if not defined.
It can be a number of seconds or string xs
, xm
or xh
what means amount of seconds, minutes or hours respectively.
By default the process is going to record audio stream into a file but in case you don't want to, you can pass true
to this option. Note that audio stream is encoded using ACC.
In case you have this option specified you will have ability to catch SPACE_FULL
event when threshold is reached. It can be a number of bytes or string xM
, xG
or xT
what means amount of Megabytes, Gigabytes or Terabytes respectively.
NOTE that option does not make sense if dirSizeThreshold
option is not specified.
In case you need to specify a path to ffmpeg binary you can do it using this argument.
recorder.on(RecorderEvents.START, (payload) => {
assert.equal(payload, 'programmatically');
});
Normal stop
recorder.on(RecorderEvents.STOP, (payload) => {
assert.equal(payload, 'programmatically');
});
If space full
recorder.on(RecorderEvents.STOP, (payload) => {
assert.equal(payload, 'space_full');
});
In case of other errors
recorder.on(RecorderEvents.STOP, (payload) => {
assert.equal(payload, 'error', Error);
});
Handler receives an object that contains options applied to the current process
- Default values if no options passed.
- Converted values in case of some options if passed.
recorder.on(RecorderEvents.STARTED, (payload) => {
assert.equal(payload, {
uri: 'rtsp://username:password@host/path',
destination: '/media/Recorder',
playlist: 'playlist.m3u8',
title: 'Test Camera',
filePattern: '%Y.%m.%d/%H.%M.%S',
segmentTime: 600,
noAudio: false,
ffmpegBinary: 'ffmpeg',
});
});
If stopped because of space full handler receives 0 exit code & reason message 'space_full'.
recorder.on(RecorderEvents.STOPPED, (payload) => {
assert.equal(payload, 0, 'space_full');
});
Or if stop reason is FFMPEG process exited, handler receives an exit code of ffmpeg process and a message that FFMPEG exited.
recorder.on(RecorderEvents.STOPPED, (payload) => {
assert.equal(payload, 255, 'ffmpeg_exited');
});
New file should be created when new segment started or in case of recording stopped.
recorder.on(RecorderEvents.FILE_CREATED, (payload) => {
assert.equal(payload, `2020.06.25/10.18.04.mp4`);
});
If no space left an event should be emitted and payload raised.
There is approximation percentage which is set to 1, so when you reach out 496 you'll have space_full
event emitted if you set your threshold e.g. 500.
In other words it works based on formula Math.ceil(used + used * APPROXIMATION_PERCENTAGE / 100) > threshold
where threshold
is you threshold valid and used
is amount of space used.
recorder.on(RecorderEvents.SPACE_FULL, (payload) => {
assert.equal(payload, {
threshold: 500,
used: 496,
});
});
recorder.on(RecorderEvents.ERROR, () => {
/** Do what you need in case of recording error */
});