I want to stream a video from Zoneminder app using NodeJS. ZoneMinder stores video from ip cameras and can stream it into HTML . I have issues when access external zoneminder server with self-signed certificate because my web-app requires https. So I decided to use nodeJS as a medium. I managed to find a solution: Request.pipe() JPEG streams.
My code is below. HTML:
<!DOCTYPE html>
<html>
<body>
<img id="zmvideo" src="/videostream?monitor=3" alt="no video">
</body>
</html>
nodeJS server:
const request = require('request');
var http = require('http');
const express = require('express');
const app = express();
app.get("/", function(request, response){
response.sendFile(__dirname + "/index.html");
});
app.get('/videostream', async (req, res) => {
let url1=`http://192.168.22.127/zm/cgi-bin/nph-zms?mode=jpeg&scale=100&user="watchinguser"&pass="somepassword"`;
req.pipe( request({
url: url1,
qs: req.query,
method: "stream"
},function(error, response, body){console.error(`Error ${error}`); console.log(req.query);}
)).pipe( res );
})
var httpServer = http.createServer(app);
httpServer.listen(3000);
It works as expected, but there are a problem with memory leaks. After a while nodeJS server eats all RAM, kills himself and restarts.
I decided to replace pipe with pipeline. As a result my nodeJS server looks like this:
const { pipeline } = require('stream');
const request = require('request');
var http = require('http');
const express = require('express');
const app = express();
app.get("/", function(request, response){
response.sendFile(__dirname + "/index.html");
});
app.get('/videostream', async (req, res) => {
let url1=`http://192.168.22.127/zm/cgi-bin/nph-zms?mode=jpeg&scale=100&user="watchinguser"&pass="somepassword"`;
pipeline(req,
request({url: url1,qs: req.query,method: "stream"},function(error, response, body){console.error(`Video Stream Request Error ${error}`); console.log(req.query);}),
(err) => {
if (err)
{
console.log('Video Stream Pipeline error');
console.log(err);
res.end(err.message);
}
else
{
console.log('pipeline successfull')
}
}
);
})
var httpServer = http.createServer(app);
httpServer.listen(3000);
There are no errors, also I see "pipeline successfull" message when open index.html. But there are no video from Zoneminder.
I need help with it. My best option is to find a solution with request package and stream.pipeline() method (actually to find an error in my implementation) Also I'm considering switching from request package to axios.
Update: I found a solution with pipe here: https://stackoverflow.com/a/40393615/2088128
It works for now (memory leaks eleminated or extremely reduced), but still need a solution with pipeline method.