bartbutenaers / node-red-contrib-multipart-stream-encoder

Node Red node for encoding multipart streams over http
Apache License 2.0
9 stars 1 forks source link

Q: can we know if there is a connection or not? #1

Closed btsimonh closed 6 years ago

btsimonh commented 7 years ago

I'd like to ONLY encode to jpg if there is a connection? any thoughts? s

bartbutenaers commented 7 years ago

Hi Simon,

I assume you mean 'mjpeg'? Could you give me a little more information of what your flow need to do? From your question it is e.g. not clear to me if you are using the ALL CLIENTS mode (e.g. an IP camera where all clients hook in on the same stream), or the SINGLE CLIENT mode (e.g. show video footage from a disc, where every client wants to see the entire stream from the start).

The encoder node has output messages, which let you know which client has been disconnected. Thought that would be enough for this kind of applications. But that mechanism is perhaps not useful enough in your case (or even worse in general) ...

Kind regards, Bart

btsimonh commented 7 years ago

So, in my opencv flow, I flow matrix down the wires. These can be converted to jpg with img.toBuffer(), but this is something I would rather NOT do if there was nobody listening to save on cpu. If this was fairly easy, then I'd setup a number of 'video' (mjpeg) endpoints, one for each of the interesting feeds from the flow (average image, difference image, detected motion, continuous feed with squares applied, etc. and to play with viewing output of various transforms like laplace), but I don't have the cpu power to code all of these streams to jpg on the off-chance that they may have a client attached.

So; I'm thinking I could catch the http request msg, and count that as 'stream opened', set a flow variable to the number of opened connections counted, which enables the jpeg encoding (for that channel) if >0. Then watch for the output of encoder and decrement each time I see the closed msg, so that jpeg encoding would stop when no clients are left? Seems like a plan to test once I've rebooted my (unreliable) pi.

bartbutenaers commented 7 years ago

Hi Simon, due to unexpected medical issues, I will have to reduce also my Node-Red activity.
But to get you started already, can't you use the following settings in the config screen:

image

The encoder node keeps internally a list of all http requests. As soon as a client disconnects, I will remove the original http request from my list. As soon as the list is empty, you can get an output message indicating that no clients are connected anymore. I added that a couple of weeks ago to prevent that everybody has to count connections in their flows.

Couldn't you do it like this: image

[{"id":"7f2b6b5c.691b64","type":"http in","z":"15244fe6.9ae87","name":"","url":"/infinite","method":"get","upload":false,"swaggerDoc":"","x":618.0000038146973,"y":41.00000190734863,"wires":[["5295bfea.f6bb5"]]},{"id":"5b3e4039.df33b","type":"multipart-encoder","z":"15244fe6.9ae87","name":"","statusCode":"","ignoreMessages":true,"outputIfSingle":false,"outputIfAll":true,"globalHeaders":{"Content-Type":"multipart/x-mixed-replace;boundary=--myboundary","Connection":"keep-alive","Expires":"Fri, 01 Jan 1990 00:00:00 GMT","Cache-Control":"no-cache, no-store, max-age=0, must-revalidate","Pragma":"no-cache"},"partHeaders":{"Content-Type":"image/jpeg"},"destination":"all","x":1049.0000114440918,"y":41.00000190734863,"wires":[["110f23b9.aa0fbc"]]},{"id":"fb72a642.df0eb8","type":"http request","z":"15244fe6.9ae87","name":"Get image by url","method":"GET","ret":"bin","url":"","tls":"","x":828.0000114440918,"y":101.00000190734863,"wires":[["5b3e4039.df33b"]]},{"id":"59a9f54a.322d2c","type":"function","z":"15244fe6.9ae87","name":"Next image url","func":"var counter = global.get(\"image_counter\") || 0; \ncounter++;\nglobal.set(\"image_counter\",counter);\n\nmsg.url = 'https://dummyimage.com/400x200/fff/000&text=PNG+' + counter;\n\nreturn msg;","outputs":1,"noerr":0,"x":634.0000114440918,"y":101.00000190734863,"wires":[["fb72a642.df0eb8"]]},{"id":"82554055.ab38d","type":"inject","z":"15244fe6.9ae87","name":"Every second","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":false,"x":171.52344131469727,"y":100.4062557220459,"wires":[["dc848d6.599127"]]},{"id":"dc848d6.599127","type":"switch","z":"15244fe6.9ae87","name":"if stream_active == true","property":"stream_active","propertyType":"flow","rules":[{"t":"true"}],"checkall":"true","outputs":1,"x":396.5117492675781,"y":100.8398494720459,"wires":[["59a9f54a.322d2c"]]},{"id":"110f23b9.aa0fbc","type":"change","z":"15244fe6.9ae87","name":"stream_active = false","rules":[{"t":"set","p":"stream_active","pt":"flow","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":1242.5078086853027,"y":40.843753814697266,"wires":[[]]},{"id":"5295bfea.f6bb5","type":"change","z":"15244fe6.9ae87","name":"stream_active = true","rules":[{"t":"set","p":"stream_active","pt":"flow","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":824.0195693969727,"y":41.003910064697266,"wires":[["5b3e4039.df33b"]]}]

Basically like this:

I haven't tested this flow yet! What could go wrong is the order at which Node-Red is calling the nodes, when a new client connects at the same moment the last previous client disconnects. You will have to test that I'm afraid.

I won't be able to answer you on a short term now, but please keep me posted about the results!!! If you get it working, it might be usefull that I add this example on the README.MD page for other users.

Until soon, Bart

bartbutenaers commented 6 years ago

Hi Simon,

I have added a lot of info (and example flows) on the readme, and published version 0.0.2.

Kind regards, Bart