Here is what I came up with after reading zigzackattack answer. I use the "datauri" package for simplicity but for more fine grained control over the final image I also successfully tested the "node-canvas" package instead.
var mjpeg2jpegs = require('mjpeg2jpegs')
const Datauri = require('datauri')
var camURL = '/videostream.cgi?user=admin&pwd=password'
var camPort = 81
var camTimeout = 10000
var FPS_DIVIDER = 1
var options = {
hostname: '192.168.1.241',
port: camPort,
path: camURL,
timeout: camTimeout
}
function startCamStream (camName, options) {
var http = require('http')
var req = http.request(options, mjpeg2jpegs(function (res) {
var data
var pos = 0
var count = 0
res.on('imageHeader', function (header) {
// console.log('Image header: ', header)
data = new Buffer(parseInt(header['content-length'], 10))
pos = 0
})
res.on('imageData', function (chunk) {
// console.log('Image data: ', data.length)
chunk.copy(data, pos)
pos += chunk.length
})
res.on('imageEnd', function () {
// console.log('Image end')
if (count++ % FPS_DIVIDER === 0) {
const datauri = new Datauri()
datauri.format('.jpeg', data)
socket.emit(camName, datauri.content) // Send the image uri via websockets.
}
})
})).on('timeout', function () {
console.log('timeout')
startCamStream(camName, options)
}).end()
}
startCamStream('ipcam1', options)
Using vue.js (optional) I simply embed the image uri with an img tag.
<img :src="ipcam1" alt="ipcam1" />
Increasing the FPS_DIVIDER variable will reduce the fps output. If you want to change the image when there is a timeout then you can send an "offline" image when it reach the "timeout" callback.