ip cam feed

1,680 views
Skip to first unread message

Toshi Bass

unread,
Jan 11, 2018, 11:19:31 AM1/11/18
to Node-RED
I have a ip camera feed that works fine on the dashboard using the following code, in a template node.

<table width="310" cellpadding="3" cellspacing="0" align="center" style="background-color:#313131;">
    <tr>
        <td>
            <img width="300" height="200" src="http://xxx.xxx.x.xxx:xxxxx/videostream.cgi?loginuse=xxxx;loginpas=xxxx" >
        </td>
    </tr>
</table>

But I would like to send the http:// part from a function node into the template node, say as a payload or something but all my attempts have failed, can anyone give me some help in understanding how I can do this.

steve rickus

unread,
Jan 11, 2018, 12:15:21 PM1/11/18
to Node-RED
I have not tried it, but you may be able to "substitute" the msg.payload into the img src attribute using some angular syntax, like:

<img width="300" height="200" ng-src="{{msg.payload}}">

The other way I've see this work is by passing the entire html source (with embedded url), and binding the html using the default template:

<div ng-bind-html="msg.payload"></div>

Dave C-J

unread,
Jan 11, 2018, 1:05:11 PM1/11/18
to node...@googlegroups.com
As per Steve's reply, if you go for option 2 then preceeding it with a "normal" template node is the way to go...
so   ---> template --> ui_template

Toshi Bass

unread,
Jan 11, 2018, 2:26:17 PM1/11/18
to Node-RED
Yeh Option 2 worked great thank you very much .....

Bart Butenaers

unread,
Jan 11, 2018, 2:43:59 PM1/11/18
to Node-RED
Hi Toshi,

Glad that the problem is solved.  
But keep in mind that the different approaches can have a big impact on performance.
Don't know if that is important for you, but below some detailed explanation from which other users might learn ...

Similar to Steve his approach, I use a template node to get the image from the msg.payload :

<img width="16" height="16" src="data:image/jpg;base64,{{msg.payload}}" />

So you just get every x seconds an image from an IP cam with a httprequest node (output should be type Buffer!), then encode the image as base64 (to avoid problems with special characters) and send it into the template node:

[{"id":"1c60ecf2.a26cf3","type":"base64","z":"47b91ceb.38a754","name":"Encode","x":1214,"y":205,"wires":[["8d1aa3c.19ce66"]]},{"id":"2216d2e0.8bbd0e","type":"http request","z":"47b91ceb.38a754","name":"","method":"GET","ret":"bin","url":"http://192.168.1.200/SnapshotJPEG?Resolution=320x240&Quality=High","tls":"","x":1031.6354484558105,"y":204.3958396911621,"wires":[["1c60ecf2.a26cf3"]]},{"id":"4dd2a66a.face28","type":"interval","z":"47b91ceb.38a754","name":"interval","interval":"1","onstart":false,"msg":"ping","showstatus":false,"unit":"seconds","statusformat":"YYYY-MM-D HH:mm:ss","x":876.5902976989746,"y":203.82205200195312,"wires":[["2216d2e0.8bbd0e"]]},{"id":"8d1aa3c.19ce66","type":"ui_template","z":"47b91ceb.38a754","group":"4f44306b.c5a07","name":"Display image","order":1,"width":"6","height":"6","format":"<img width=\"16\" height=\"16\" alt=\"mjpeg test...\" src=\"data:image/jpg;base64,{{msg.payload}}\" />\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":1391.256923675537,"y":205.4166660308838,"wires":[[]]},{"id":"4f44306b.c5a07","type":"ui_group","z":"47b91ceb.38a754","name":"Keuken","tab":"72e36c60.254134","order":1,"disp":true,"width":"6"},{"id":"72e36c60.254134","type":"ui_tab","z":"47b91ceb.38a754","name":"Cameras","icon":"camera_alt","order":2}]


That is a very simple approach, which is sufficient in a lot of use cases.

But it is not usable when you require good performance:

  • When you send the image to the template node, it is being pushed from the Node-Red flow (i.e. from the server) towards the browser (i.e; to the client).  So the image data is being send (along the websocket channel) that is also being used by Node-Red to send all other changes (node status changes, graph data, ...) to the browser.  When you increase the frame rate (e.g. 10 images per second) or you want to view multiple cameras simulatenously, the browser window will freeze (which means it will start hanging).  Seems the browser has a single thread to handle 'all' the data from a websocket channel.
  • When you have multiple tab sheets, and only one of those displays camera images:

Keep in mind that the images keep being pushed to the dashboard, even if the 'cameras' tab is not active!  This is very inconvenient when you open your dashboard e.g. on a smartphone, because you might be paying for lots of useles data that is being transmitted.  I have already raised an issue for this in the past, but you need to solve this yourself in your flow. 

If you want to solve this kind of issues, using a 'src' attribute (like you did) is better.
The advantage is now that the browser requests the images from the Node-Red flow, and the Node-Red flow replies by sending the image.  
  • The browser only gets data when needed!  So no useless data is being send.
  • Seems that the browser has now multiple threads available, because you can run multiple cameras simultaneously without the browser freezing.
And if you need higher frame rates, please have a look at my node-red-contrib-multipart-stream-encoder and node-red-contrib-multipart-stream-decoder nodes ...

Summarized, it all depends on what kind of application you want to build ...

Bart

Toshi Bass

unread,
Jan 12, 2018, 8:40:42 AM1/12/18
to Node-RED
Hi Bart, I read and reread your post several times, do you have a way to visualize "the load on the websocket channel" I ask because I have 3 ip cameras and 2 pi cameras all being displayed at the same time, I know the pi cameras are set at 15fps (no idea about the ip cameras) but they are all smooth. I have no browser window freeze even though I have huge amount of other stuff going on as well.

It appears from your post that you are perhaps getting each frame from the camara and processing, were as all I am doing is displaying the streams from the cameras, maybe that's why I don't appear to have a problem.

You guessed the reason I wanted to be able to send the ip cameras html source as a payload to the template node was to be able to turn it On and Off because I was more concerned about the load on my network considering that I have several dashboards on different pis with the ability to display these streams + iphone / ipad etc     

Bart Butenaers

unread,
Jan 12, 2018, 12:07:12 PM1/12/18
to Node-RED
Hi Toshi,

it was not my intention to overwhelm you with technical details ...
Will try to explain it better, because I'm very surprised that you don't have the same problems as me.

Setup 1 - Push images via websocket

About I year ago I did a test do show a grid of NxM cameras, for homemade video surveillance.
Something like this:

Following steps are executed for each IP camera:

  1. The interval node triggers the httprequest node every second to get a snapshot image from the IP camera
  2. The httprequest node outputs the image as a buffer
  3. Then the image is base64 encoded, because otherwise my images became corrupt (due to some characters in the buffers)
  4. The base64 encoded images are then send to a template node, which pushes the images to the dashboard via websocket:

<img width="16" height="16" src="data:image/jpg;base64,{{msg.payload}}" />


However when I enlarged the framerate or used more cameras, the browser completely freezed.
It didn't respond anymore.  Tested it in Chrome and Internet Explorer (11 I believe ...).
When you search for freezing Websockets on Google, you will see I'm not the only one with problems ...

It even gets worse if you replace the 'interval' and 'httprequest' node by my node-red-contrib-multipart-stream-decoder node, because that gets an infinite MJPEG stream from the camera at full speed (when you don't activate the node's throttling option).  The framerate became even higher ...

So my theorie was: all images are being send through a single websocket to the browser, and the browser cannot handle all the data.  So it starts choking ...

Setup 2 - dashboard gets images from camera

You can also setup something it like in your original question above:

Now indeed the browser doesn't seem to freeze: all camera's run at full speed.

So my theory was that the browser seems to have a separate thread for each source (src) ...


However now your dashboard gets the images directly from the camera's: nothing passes via the Node-Red flow.

You can have two options:

  • Send a http request to the IP camera for a single snapshot image, and the camera will reply in the http request with a single image.  
  • Send a http request to the IP camera for an infinite MJPEG stream, and the camera will reply with an endless http response (it keeps sending image at higher rates).  The img tag will decode the stream automatically and show the images...
I didn't like this setup in my case at home, because it had two disadvantages to me:
  • I don't want to expose the IP camera's through my firewall.  But there might be options to avoid this ...
  • I want the images in my node-red flow, because I want to store them, do motion detection, do license plate recognition, ...

Setup 3 - dashboard gets images from Node-Red flow

To solve this, I have created last year the node-red-contrib-multipart-stream-encoder and node-red-contrib-multipart-stream-decoder nodes.  Those nodes allow me to get at high speed all images in my Node-Red flow, and display them all at once in the dashboard (without the browser choking):

It is perhaps to complex for your case, but for completeness I will explain here how it works:
  1. The multipart decoder gets an infinite MJPEG stream from the camera, and outputs images at full speed.
  2. Then I do some processing (e.g. license plate recognition) on those images in my flow
  3. Then the processed images are send to the encoder node, which creates an MJPEG stream from those separate images
  4. The dashboard sends a single http request to the httpin node of my Node-Red flow (via the ip address of my raspberry where node-red is running)
  5. The encoder node responds by sending in the http response an MJPEG stream to the browser.
So my question to you is: did you manage to use setup 1 without the browser choking, or do you simply use setup 2 ??

It is a rather technical topic, so couldn't manage to explain it more simply ;-(
Hopefully your brain hasn't exploded ...

Bart


Toshi Bass

unread,
Jan 12, 2018, 1:16:24 PM1/12/18
to Node-RED
OK I understand, and I can see you've been very busy,, so I guess am using option 2, simply just to get each camera stream onto the node-red dashboard.

I can control the raspberry pi streams by stooping and starting mjpg streamer but having the ability to control the input url feeding into the template nodes that enable the streams from the pi and ip cameras to be displayed on several raspberry pi / node-red instances was my goal, so for me this problem is solved.

On the dashboard for my 2 raspberry pi cameras I can also set up a time lapse video when a pir motion detector is triggered however the actual mp4 construction is done in python, when the process is complete node-red emails me a copy, that's as far as I have got, in reality it would be pointless for me to have number-plate recognition I live on a very quite cul de sac and the only time I could see a number plate would be when a vehicle comes up the drive, but it sound like you have a realty nice setup.







Bart Butenaers

unread,
Jan 12, 2018, 4:11:03 PM1/12/18
to Node-RED
Toshi,

I'm very convinced that most Node-Red users won't need license plate recognition at their home...
But that was only an example, and small free advertisement for my node-red-contrib-openalpr-cloud node ;-)
Indeed there are better image processing examples, like storing images on a disc, motion detection, or something else ...

Anyway, now other users can read here our discussion and learn from it.

It is a bit off-topic, but I would appreciate if you could explain me a last thing: how do you use your dashboard when you are not at home?   I mean access the dashboard via the internet
Because your dashboard accesses camera's directly: do you have to setup port forwarding on your router for all cameras?
  • Setup 1 : the browser connects to the Node-Red flow, and from then on the Node-Red flow pushes images to the browser => Only the IP address of the device (that runs Node-Red) needs to be accessible from the internet.
  • Setup 2 :  the browser connects to the Node-Red flow and to ALL the cameras => The  IP address of the device (that runs Node-Red) AND the IP addresses of all the cameras need to be accessible from the internet.  Or am I completely confused???

  • Setup 3 : the browser connects to the Node-Red flow, and from then on the browser requests all images from that Node-Red flow => Only the IP address of the device (that runs Node-Red) needs to be accessible from the internet.
Or perhaps your camera's are accessible from the internet, since they have automatically requested your router to be accessible (using UpNp)...
Or don't you use port forwarding, but perhaps you use a VPN connection?  And then everything from your LAN is accessible, or not ?
I'm not a network expert ...

Kind regards,
Bart

Walter

unread,
Jan 12, 2018, 4:49:09 PM1/12/18
to Node-RED
I think its not a good idea to expose node-red or any other program to the internet except of an ssh or vpn server.

It's not difficult to setup an ssh server on a lede / openwrt router, and for Android you could use Connectbot to open a tunnel 
to your network and access your dashboard as well as any other network device.

This method only works, if your home network has a public ip address.

Bart Butenaers

unread,
Jan 12, 2018, 5:11:24 PM1/12/18
to Node-RED
Hi Walter,

Suppose I replace my port forwarding by VPN or a SSH server.
And suppose I would have a setup like Toshi, i.e. the Node-Red dashboard accesses the camera's IP addresses directly.
Is that possible, i.e. are all those IP addresses then accessible from the dashboard?

Thanks !
Bart

Walter

unread,
Jan 12, 2018, 5:33:01 PM1/12/18
to Node-RED
Because the ip cams are included directly with their private ip's in the dashboard, you should use a vpn.
BR

Toshi Bass

unread,
Jan 12, 2018, 5:37:08 PM1/12/18
to Node-RED
You should not use port forwarding, search google for pivpn and see video tutorial on that site, it makes it very easy to set up openvpn to connect to which ever pi’s that you have your dashboards on, going this way allows me to view all of my controls and streams on the dashboard from outside of my local network safely.

Walter Kraembring

unread,
Jan 13, 2018, 2:44:04 AM1/13/18
to Node-RED
I use VPN to access my dashboard from internet and yes, all my cameras are visible to me, no need for port forwarding of anything

I think my solution is similar to option 2) discussed above but I'm using a different platform providing the actual video streams (Motion) so there is no direct access to my (USB) cameras but with Motion it is similar to having ip cameras. Plus the possible processing capabilities provided by Motion.

@Bart

Do you think image processing is efficient enough to be handled by javascript??? Would it not be better to leave that part to another process better suited for the task. Like OpenCV or Motion. The result of the image processing could then very well be presented in NR. I do this in my solution where it looks like this schematically (everything running on Pi's)

USB Camera -> Motion (analyze, detect movement) -> Movement detected -> OpenCV people detection -> If people detected -> NR -> Telegram -> Message on my phone (currently only text but could very well include a picture with the person detected)

Very interesting topic I think

Walter Kraembring

unread,
Jan 13, 2018, 7:28:53 AM1/13/18
to Node-RED
And this is a real capture, some unexpected visitor checking our front door in the middle of the night, detected & captured with the above mentioned setup

Luckily our front door was locked...


Bart Butenaers

unread,
Jan 13, 2018, 8:31:03 AM1/13/18
to Node-RED
Hey Walter,

indeed I also learned a lot again from this discussion.  

Yep like you say, it seems that Javascript isn't the best option for image processing: I have been experimenting some time ago with OpenCv.js, which is an official Javascript port of OpenCv.  Well it works fine, and you don't need to install anything: it is automatically installed as a dependency.  However it was muuuuch slower compared to the original native C++ OpenCv library.  So some smart people have been creating asm.js and wasm.js versions of OpenCv.js, which are similar libraries, but they have already been interpreted (i.e. some kind of byte code): so those run much faster as the original Javascript variant.  But those technologies are at the moment rather experimental: the NodeJs API for those technologies are changing frequently, and it was a pain in the ...  to get them working.  Here you can find a performance comparison of those technologies.

At the end, we decided that it is better to just install the OpenCv original C++ libraries.
Simon Hailes has already started a new node suite where we can work on a solution, but it is not simple: there are problems with garbage collection, multithreading ...
And I have been very ill the last couple of months, so it is not really progressing.  I will contact Simon soon to work on this together again ...

Bart

Julian Knight

unread,
Jan 13, 2018, 9:59:35 AM1/13/18
to Node-RED
You should even be able to send a video snippet to Telegram actually. :)

Toshi Bass

unread,
Jan 14, 2018, 2:02:07 PM1/14/18
to Node-RED
I setup my first raspberry pi camera sometime in 2014 at that time I did try motion, but I found it to be very cpu incentive like almost 100% cpu when I was running it was quite unstable, of coarse this was on an original pi, I then tried  jacksonliam/mjpg-streamer which runs very smoothly with negotiable cpu usage typically 15-20% and I have been using that ever since even to the point of not upgrading to the latest releases.

So my question is what is motion like now does it still use high cpu usage (like i said I have 2 raspberry pis with a camera attached 1 is a pi3 but the other is still an original pi running the original raspbmc os with a camera /servos attached which just keeps on working, never needs restarting so I don't and will not update it, but if motion is less cpu intensive I may try motion once again ...

Colin Law

unread,
Jan 14, 2018, 3:12:48 PM1/14/18
to node...@googlegroups.com
The cpu consumption of motion depends hugely on the resolution of the
images (more or less proportional to the number of pixels I think) and
the frame rate that you tell motion to operate at. It also depends on
the format of the incoming data. If this is mpjpeg then it reduces the
processing compared to rtsp for example.

Colin
> --
> http://nodered.org
>
> Join us on Slack to continue the conversation: http://nodered.org/slack
> ---
> You received this message because you are subscribed to the Google Groups
> "Node-RED" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to node-red+u...@googlegroups.com.
> To post to this group, send email to node...@googlegroups.com.
> Visit this group at https://groups.google.com/group/node-red.
> To view this discussion on the web, visit
> https://groups.google.com/d/msgid/node-red/49060e67-8ade-4a1f-981a-2359c486eeea%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages