Skip to content

Commit b34499a

Browse files
committedAug 26, 2018
Added recorders
0 parents  commit b34499a

14 files changed

+2128
-0
lines changed
 

‎.eslintrc.json

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"extends": "airbnb-base",
3+
"parser": "babel-eslint",
4+
"parserOptions": {
5+
"ecmaVersion": 8
6+
},
7+
"rules": {
8+
"semi": 0,
9+
"prefer-const": 0,
10+
"object-curly-newline": 0,
11+
"no-var": 0,
12+
"padded-blocks": 0,
13+
"object-shorthand": 0,
14+
"prefer-destructuring": 0,
15+
"guard-for-in": 0,
16+
"no-restricted-syntax": 0,
17+
"vars-on-top": 0,
18+
"arrow-body-style": 0,
19+
"class-methods-use-this": 0,
20+
"prefer-template": 0,
21+
"no-useless-constructor": 0,
22+
"func-names": 0,
23+
"max-len": 0,
24+
"new-cap": 0,
25+
"consistent-return": 0,
26+
"no-console": 0
27+
}
28+
}

‎.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
videos/cam1/

‎.npmignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
videos/cam1/

‎README.md

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# node-rtsp-recorder
2+
3+
[![NPM](https://nodei.co/npm/node-rtsp-recorder.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/node-rtsp-recorder/)
4+
5+
[![npm](https://img.shields.io/npm/dm/node-rtsp-recorder.svg)](https://www.npmjs.com/package/node-rtsp-recorder)
6+
[![npm](https://img.shields.io/npm/v/node-rtsp-recorder.svg)](https://www.npmjs.com/package/node-rtsp-recorder)
7+
8+
Records RTSP Audio/Visual Streams to local disk using ffmpeg
9+
10+
## Installation
11+
12+
```shell
13+
$ npm install --save node-rtsp-recorder
14+
```
15+
16+
## Recording Video
17+
18+
```js
19+
const Recorder = require('node-rtsp-recorder').Recorder
20+
21+
var rec = new Recorder({
22+
url: 'rtsp://192.168.1.12:8554/unicast',
23+
timeLimit: 60, // time in seconds for each segmented video file
24+
folder: '/Users/sahilchaddha/Sahil/Projects/Github/node-rtsp-recorder/videos',
25+
name: 'cam1',
26+
})
27+
// Starts Recording
28+
rec.startRecording();
29+
30+
setTimeout(() => {
31+
console.log('Stopping Recording')
32+
rec.stopRecording()
33+
rec = null
34+
}, 300000)
35+
```
36+
37+
## Recording Audio
38+
39+
```js
40+
const Recorder = require('node-rtsp-recorder').Recorder
41+
42+
var rec = new Recorder({
43+
url: 'rtsp://192.168.1.12:8554/unicast',
44+
timeLimit: 60, // time in seconds for each segmented video file
45+
folder: '/Users/sahilchaddha/Sahil/Projects/Github/node-rtsp-recorder/videos',
46+
name: 'cam1',
47+
type: 'audio',
48+
})
49+
50+
rec.startRecording();
51+
52+
setTimeout(() => {
53+
console.log('Stopping Recording')
54+
rec.stopRecording()
55+
rec = null
56+
}, 125000)
57+
```
58+
59+
## Capturing Image
60+
61+
```js
62+
const Recorder = require('node-rtsp-recorder').Recorder
63+
64+
var rec = new Recorder({
65+
url: 'rtsp://192.168.1.12:8554/unicast',
66+
folder: '/Users/sahilchaddha/Sahil/Projects/Github/node-rtsp-recorder/videos',
67+
name: 'cam1',
68+
type: 'image',
69+
})
70+
71+
rec.captureImage(() => {
72+
console.log('Image Captured')
73+
})
74+
```
75+
76+
## Managing Media Directory
77+
78+
```js
79+
const FileHandler = require('../src/helpers/fileHandler')
80+
const fh = new FileHandler()
81+
// RETURNS DIRECTORY SIZE
82+
fh.getDirectorySize('/Users/sahilchaddha/Sahil/Projects/Github/node-rtsp-recorder/videos/', (err, value) => {
83+
if (err) {
84+
console.log('Error Occured')
85+
console.log(err)
86+
return true
87+
}
88+
console.log('Folder Size is ' + value)
89+
})
90+
// REMOVES ALL MEDIA FILES
91+
fh.removeDirectory('/Users/sahilchaddha/Sahil/Projects/Github/node-rtsp-recorder/videos/*', () => {
92+
console.log('Done')
93+
})
94+
```

‎examples/audioRecorder.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// audioRecorder.js
3+
// node-rtsp-recorder
4+
//
5+
// Created by Sahil Chaddha on 24/08/2018.
6+
//
7+
8+
const Recorder = require('../src/helpers/recorder')
9+
10+
var rec = new Recorder({
11+
url: 'rtsp://192.168.1.12:8554/unicast',
12+
timeLimit: 60,
13+
folder: '/Users/sahilchaddha/Sahil/Projects/Github/node-rtsp-recorder/videos',
14+
name: 'cam1',
15+
type: 'audio',
16+
})
17+
rec.startRecording();
18+
19+
setTimeout(() => {
20+
console.log('Stopping Recording')
21+
rec.stopRecording()
22+
rec = null
23+
}, 125000)

‎examples/captureImage.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// captureImage.js
3+
// node-rtsp-recorder
4+
//
5+
// Created by Sahil Chaddha on 24/08/2018.
6+
//
7+
8+
const Recorder = require('../src/helpers/recorder')
9+
10+
var rec = new Recorder({
11+
url: 'rtsp://192.168.1.12:8554/unicast',
12+
folder: '/Users/sahilchaddha/Sahil/Projects/Github/node-rtsp-recorder/videos',
13+
name: 'cam1',
14+
type: 'image',
15+
})
16+
rec.captureImage(() => {
17+
console.log('Image Captured')
18+
})

‎examples/fileHandlerExample.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// fileHandlerExample.js
3+
// node-rtsp-recorder
4+
//
5+
// Created by Sahil Chaddha on 24/08/2018.
6+
//
7+
8+
const FileHandler = require('../src/helpers/fileHandler')
9+
10+
const fh = new FileHandler()
11+
12+
fh.getDirectorySize('/Users/sahilchaddha/Sahil/Projects/Github/node-rtsp-recorder/videos/', (err, value) => {
13+
if (err) {
14+
console.log('Error Occured')
15+
console.log(err)
16+
return true
17+
}
18+
console.log('Folder Size is ' + value)
19+
})
20+
21+
fh.removeDirectory('/Users/sahilchaddha/Sahil/Projects/Github/node-rtsp-recorder/videos/*', () => {
22+
console.log('Done')
23+
})

‎examples/recordExample.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// recordExample.js
3+
// node-rtsp-recorder
4+
//
5+
// Created by Sahil Chaddha on 24/08/2018.
6+
//
7+
8+
const Recorder = require('../src/helpers/recorder')
9+
10+
var rec = new Recorder({
11+
url: 'rtsp://192.168.1.12:8554/unicast',
12+
timeLimit: 60,
13+
folder: '/Users/sahilchaddha/Sahil/Projects/Github/node-rtsp-recorder/videos',
14+
name: 'cam1',
15+
})
16+
rec.startRecording();
17+
18+
setTimeout(() => {
19+
console.log('Stopping Recording')
20+
rec.stopRecording()
21+
rec = null
22+
}, 300000)

‎package-lock.json

+1,690
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "rtsp-recorder",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "src/index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1",
8+
"lint": "./node_modules/.bin/eslint .",
9+
"ci": "npm install && npm run lint"
10+
},
11+
"repository": {
12+
"type": "git",
13+
"url": "git+https://github.com/sahilchaddha/node-rtsp-recorder.git"
14+
},
15+
"author": "Sahil Chaddha",
16+
"license": "ISC",
17+
"bugs": {
18+
"url": "https://github.com/sahilchaddha/node-rtsp-recorder/issues"
19+
},
20+
"homepage": "https://github.com/sahilchaddha/node-rtsp-recorder#readme",
21+
"devDependencies": {
22+
"eslint": "^5.3.0",
23+
"eslint-config-airbnb-base": "^13.0.0",
24+
"eslint-plugin-import": "^2.13.0"
25+
},
26+
"dependencies": {
27+
"babel-eslint": "^8.2.6",
28+
"du": "^0.1.0",
29+
"moment": "^2.22.2",
30+
"rimraf": "^2.6.2"
31+
}
32+
}

‎src/helpers/fileHandler.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const fs = require('fs')
2+
const rimraf = require('rimraf')
3+
const du = require('du')
4+
5+
const FileHandler = class {
6+
createDirIfNotExists(folderPath) {
7+
try {
8+
if (!fs.lstatSync(folderPath).isDirectory()) {
9+
fs.mkdirSync(folderPath)
10+
}
11+
} catch (e) {
12+
fs.mkdirSync(folderPath)
13+
}
14+
}
15+
16+
removeDirectory(folderPath, callback) {
17+
rimraf(folderPath, callback)
18+
}
19+
20+
getDirectorySize(folderPath, callback) {
21+
du(folderPath, (err, size) => {
22+
callback(err, size)
23+
})
24+
}
25+
}
26+
27+
module.exports = FileHandler

‎src/helpers/recorder.js

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
//
2+
// recorder.js
3+
// node-rtsp-recorder
4+
//
5+
// Created by Sahil Chaddha on 24/08/2018.
6+
//
7+
8+
const moment = require('moment')
9+
const childProcess = require('child_process')
10+
const path = require('path')
11+
const FileHandler = require('./fileHandler')
12+
13+
const fh = new FileHandler()
14+
15+
const RTSPRecorder = class {
16+
constructor(config = {}) {
17+
this.config = config
18+
this.name = config.name
19+
this.url = config.url
20+
this.timeLimit = config.timeLimit || 60
21+
this.folder = config.folder || 'media/'
22+
this.categoryType = config.type || 'video'
23+
fh.createDirIfNotExists(this.getDirectoryPath())
24+
fh.createDirIfNotExists(this.getTodayPath())
25+
}
26+
27+
getDirectoryPath() {
28+
return path.join(this.folder, (this.name ? this.name : ''))
29+
}
30+
31+
getTodayPath() {
32+
return path.join(this.getDirectoryPath(), moment().format('MMM-Do-YY'))
33+
}
34+
35+
getMediaTypePath() {
36+
return path.join(this.getTodayPath(), this.categoryType)
37+
}
38+
39+
getFilename(folderPath) {
40+
return path.join(folderPath, moment().format() + this.getExtenstion())
41+
}
42+
43+
getExtenstion() {
44+
if (this.categoryType === 'audio') {
45+
return '.avi'
46+
}
47+
if (this.categoryType === 'image') {
48+
return '.jpg'
49+
}
50+
51+
return '.mp4'
52+
}
53+
54+
getArguments() {
55+
if (this.categoryType === 'audio') {
56+
return ['-vn', '-acodec', 'copy']
57+
}
58+
if (this.categoryType === 'image') {
59+
return ['-vframes', '1']
60+
}
61+
return ['-acodec', 'copy', '-vcodec', 'copy']
62+
}
63+
64+
getChildProcess(fileName) {
65+
var args = ['-i', this.url]
66+
const mediaArgs = this.getArguments()
67+
mediaArgs.forEach((item) => {
68+
args.push(item)
69+
})
70+
args.push(fileName)
71+
return childProcess.spawn('ffmpeg',
72+
args,
73+
{ detached: false, stdio: 'ignore' })
74+
}
75+
76+
stopRecording() {
77+
this.disableStreaming = true
78+
if (this.timer) {
79+
clearTimeout(this.timer)
80+
this.timer = null
81+
}
82+
if (this.writeStream) {
83+
this.killStream()
84+
}
85+
}
86+
87+
startRecording() {
88+
if (!this.url) {
89+
console.log('URL Not Found.')
90+
return true
91+
}
92+
this.recordStream()
93+
}
94+
95+
captureImage(cb) {
96+
this.writeStream = null
97+
const folderPath = this.getMediaTypePath()
98+
fh.createDirIfNotExists(folderPath)
99+
const fileName = this.getFilename(folderPath)
100+
this.writeStream = this.getChildProcess(fileName)
101+
this.writeStream.once('exit', () => {
102+
if (cb) {
103+
cb()
104+
}
105+
})
106+
}
107+
108+
killStream() {
109+
this.writeStream.kill()
110+
}
111+
112+
recordStream() {
113+
if (this.categoryType === 'image') {
114+
return
115+
}
116+
const self = this
117+
if (this.timer) {
118+
clearTimeout(this.timer)
119+
}
120+
121+
if (this.writeStream && this.writeStream.binded) {
122+
return false
123+
}
124+
125+
if (this.writeStream && this.writeStream.connected) {
126+
this.writeStream.binded = true
127+
this.writeStream.once('exit', () => {
128+
self.recordStream()
129+
})
130+
this.killStream()
131+
return false
132+
}
133+
134+
this.writeStream = null
135+
const folderPath = this.getMediaTypePath()
136+
fh.createDirIfNotExists(folderPath)
137+
const fileName = this.getFilename(folderPath)
138+
this.writeStream = this.getChildProcess(fileName)
139+
140+
this.writeStream.once('exit', () => {
141+
if (self.disableStreaming) {
142+
return true
143+
}
144+
self.recordStream()
145+
})
146+
this.timer = setTimeout(self.killStream.bind(this), this.timeLimit * 1000)
147+
148+
console.log('Start record ' + fileName)
149+
}
150+
}
151+
152+
module.exports = RTSPRecorder

‎src/index.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// index.js
3+
// node-rtsp-recorder
4+
//
5+
// Created by Sahil Chaddha on 24/08/2018.
6+
//
7+
8+
const Recorder = require('./helpers/recorder')
9+
const FileHandler = require('./helpers/fileHandler')
10+
11+
module.exports = {
12+
Recorder: Recorder,
13+
FileHandler: FileHandler,
14+
}

‎videos/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sample videos

0 commit comments

Comments
 (0)
Please sign in to comment.