Sending rtsp camera streaming over internet

Fantastic!!!! It works!!

Yeah, she is good!

This is pretty cool, the video is on my ssd disk here in Stockholm, Sweden, I publish it to a mqtt broker I have no idea where it is, and you view from somewhere in US, that's cool

1 Like

If you modify your flow like the picture below, you can restart the server stream yourself if needed

1 Like

Now you can host a private viewing party with your friends and watch a movie together!

But, seriously, the only issue i can foresee is storing the initialization fragment (ftyp atom) on the receiving side, so that it can be used later when connecting to a live feed that is already in progress.

Cool, perfect during pandemic situations with an isolated social lifestyle :wink:

Yeah, maybe that could be one of the properties that always should be included in the "constructed message" we discussed above. If it is relativly small, it would not cause too much overhead

I was considering the exact same idea. But still, some have metered bandwidth and that little bit might add up. Is there a way to detect when a new subscriber is attached so that we can ensure that the ftyp is sent first?

Or the alternative, use 2 topics, 1 for the initialization, 1 for the live segments. If the initialization piece is set to retain, that would be ok since it can be old and does not receive updates after it is created.

2 Likes

Regarding QOS as 2, that will be applied to all messages, so to all the video streaming, und it could be an overload if it is not important losing some streaming. Maybe it could be used only for the start messages with a dedicated topic. I'm not that expert as you so honestly it's hard for me to be sure to completely understand your points, but I tryed several times and I didn't have problem with the configuration I signed as solution.
Instead, what you think about a counter for start and stop the streaming? Do you have a better idea?

Yep, that would work fine I think!

Yes, @kevinGodell using retained flag for the init is the solution

Somehow I think I remember that there is a way to find out how many clients that are subscribing to a specific topic but needs to be investigated "how to". However, nothing prevents you from sending a notification/client id to the server (on a dedicated topic) when a client connects and subscribes. In this way the server could keep a list of connected clients and would know when it would be ok to stop the server from streaming

I suddenly thought I saw the light in the tunnel, what if the ffmpeg-spawn node had a dedicated output with the needed message structure fitted for mqtt communication??

(Well, realizing, obviously the mp4frag node would have to able to decode it but it could eventually also be solved by using some nodes like the switch and json nodes)

I would say you are onto a good (more extensible) solution myself.

If the mp4frag node was modified first to handle the payload being a buffer (Buffer.isBuffer(...)) or an object with a buffer property you could then later adjust the output of ffmpeg-spawn to be an object with a buffer property (plus others props as required) negating the need for any function/json/switch nodes etc

If there is concern about backwards compatibility, have a legacy mode check box to revert to old output style (not ideal but doable)

Hi Walter,
I didn't realise you live in Sweden. I visited Stockholm and Gothenburg many times (years ago) to run EDA courses at various Ericsson sites. Used to stay at the Globe Hotel in Stockholm. Great times, great people.

Hello Dave!! That must have been great & interesting!! I don't know where you are living in UK but I spent many, many hours during the eighties in Tewkesbury. Lovely area, green hills, love thos houses built with yellow limbstones, nice views towards Wales with the mountains in the background. I used to stay at a golf club, that was very luxury. Nice memories!!

From the mqtt protocol there is no way to know how many clients that currently subscribes to a specific topic. So you may end up having to design a kind of counter in NR keeping track for you if you want a multi-user solution where each user independently can decide if he wants the video or not. That being said, to make a client disconnect from receiving video would require you to unsubscribe from the topic. Just disabling the view would not help preventing video data sent to the clients mqtt in node as long as the server is still streaming. There is no command to send to the mqtt in node to unsubscribe

For myself I instead decided to make a solution where any client is able to turn on/off the video server. So what one client does affects all the others. I'm happy with that, I won't forget to leave a client "hangin in" viewing video nobody is looking at. When I turn it off I know it's off for all

So here is my latest:


[{"id":"17d3345a.8e43fc","type":"comment","z":"e193914.078e67","name":"Server side (machine one)","info":"","x":160,"y":50,"wires":[]},{"id":"d353460.3cd53b8","type":"mqtt in","z":"e193914.078e67","name":"","topic":"mp4_345_test","qos":"2","datatype":"auto","broker":"ed237c6b.40d1b","nl":false,"rap":true,"rh":0,"x":120,"y":690,"wires":[["d8444f28.0523"]]},{"id":"96a55dd1.544a7","type":"ui_mp4frag","z":"e193914.078e67","name":"","group":"9c7f211e.e2d06","order":1,"width":6,"height":4,"readyPoster":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAJYCAMAAACtqHJCAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMzgwMTE3NDA3MjA2ODExODIyQUIzREQ3RTA0MDAyNCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpGRkU5MkM4RDJCNTkxMUVCQjJCOTg0MEQ0QThCQ0YyQyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpGRkU5MkM4QzJCNTkxMUVCQjJCOTg0MEQ0QThCQ0YyQyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6Rjc3RjExNzQwNzIwNjgxMTgyMkFDQTkzQjdGQkY1MzAiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDM4MDExNzQwNzIwNjgxMTgyMkFCM0REN0UwNDAwMjQiLz4gPC9yZGY6RGVzY3Jp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","errorPoster":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAJYCAMAAACtqHJCAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMzgwMTE3NDA3MjA2ODExODIyQUIzREQ3RTA0MDAyNCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpGRkU5MkM5MTJCNTkxMUVCQjJCOTg0MEQ0QThCQ0YyQyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpGRkU5MkM5MDJCNTkxMUVCQjJCOTg0MEQ0QThCQ0YyQyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6Rjc3RjExNzQwNzIwNjgxMTgyMkFDQTkzQjdGQkY1MzAiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDM4MDExNzQwNzIwNjgxMTgyMkFCM0REN0UwNDAwMjQiLz4gPC9yZGY6RGVzY3Jp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","hlsJsConfig":"{\"liveDurationInfinity\":true,\"liveBackBufferLength\":5,\"maxBufferLength\":10,\"manifestLoadingTimeOut\":1000,\"manifestLoadingMaxRetry\":10,\"manifestLoadingRetryDelay\":500}","retry":true,"play":true,"unload":true,"threshold":0.5,"players":["socket.io","hls.js","hls","mp4"],"x":730,"y":720,"wires":[[]]},{"id":"5c03658f.ca806c","type":"mp4frag","z":"e193914.078e67","name":"","migrate":2e-9,"hlsPlaylistSize":4,"hlsPlaylistExtra":0,"basePath":"123client","repeated":"false","timeLimit":"10000","preBuffer":"1","x":510,"y":720,"wires":[["96a55dd1.544a7","61205bd6.757aa4"],[]]},{"id":"d8444f28.0523","type":"switch","z":"e193914.078e67","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"close","vt":"str"},{"t":"istype","v":"buffer","vt":"buffer"}],"checkall":"true","repair":false,"outputs":2,"x":310,"y":690,"wires":[["f64b8385.04e23"],["5c03658f.ca806c"]]},{"id":"f64b8385.04e23","type":"json","z":"e193914.078e67","name":"","property":"payload","action":"","pretty":false,"x":470,"y":660,"wires":[["5c03658f.ca806c"]]},{"id":"e5574b65.3a9308","type":"mqtt in","z":"e193914.078e67","name":"","topic":"mp4_345_server_on_off","qos":"2","datatype":"auto","broker":"ed237c6b.40d1b","nl":false,"rap":true,"rh":0,"x":170,"y":520,"wires":[["ac466242.598ef"]]},{"id":"ac466242.598ef","type":"json","z":"e193914.078e67","name":"","property":"payload","action":"","pretty":false,"x":180,"y":460,"wires":[["9ca7c9c3.171a78","d46a1000.7ed04"]]},{"id":"ccb74ab3.5b1278","type":"mqtt out","z":"e193914.078e67","name":"","topic":"mp4_345_server_on_off","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"ed237c6b.40d1b","x":530,"y":790,"wires":[]},{"id":"371dc912.1723b6","type":"ui_button","z":"e193914.078e67","name":"","group":"9c7f211e.e2d06","order":2,"width":"6","height":"1","passthru":false,"label":"{{msg.txt}}","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"true","payloadType":"bool","topic":"","topicType":"str","x":100,"y":790,"wires":[["84b6c29d.4f7d1"]]},{"id":"84b6c29d.4f7d1","type":"function","z":"e193914.078e67","name":"","func":"var state = context.get('state_buffer')||'off';\n//node.warn(state);\n\nswitch (state) {\n    case 'off':\n        msg.payload = {\"subject\":\"write\",\"command\":\"start\",\"timeLimit\":-1};\n        context.set('state_buffer', 'on');\n        break;\n    case 'on':\n        msg.payload = {\"subject\":\"write\",\"command\":\"stop\"};\n        context.set('state_buffer', 'off');\n        break;\n    default:\n        msg.payload = {\"subject\":\"write\",\"command\":\"start\",\"timeLimit\":-1};\n        context.set('state_buffer', 'on');\n        break;\n}\n\nnode.send(msg);","outputs":"1","noerr":0,"initialize":"","finalize":"","libs":[],"x":270,"y":790,"wires":[["ccb74ab3.5b1278","12ae2d42.f85043"]]},{"id":"12ae2d42.f85043","type":"change","z":"e193914.078e67","name":"","rules":[{"t":"set","p":"background","pt":"msg","to":"orange","tot":"str"},{"t":"set","p":"txt","pt":"msg","to":"Please wait...","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":840,"wires":[["371dc912.1723b6"]]},{"id":"ea0f87a0.a9a9c8","type":"change","z":"e193914.078e67","name":"","rules":[{"t":"set","p":"background","pt":"msg","to":"red","tot":"str"},{"t":"set","p":"txt","pt":"msg","to":"Streaming OFF","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":940,"wires":[["371dc912.1723b6"]]},{"id":"9ca7c9c3.171a78","type":"change","z":"e193914.078e67","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"action","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":180,"y":400,"wires":[["9cc6812c.92bde"]]},{"id":"9cc6812c.92bde","type":"switch","z":"e193914.078e67","name":"","property":"action.command","propertyType":"msg","rules":[{"t":"cont","v":"start","vt":"str"},{"t":"cont","v":"stop","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":180,"y":310,"wires":[["f1b369f9.af9dd8"],["ac1c1ece.98579"]]},{"id":"1d252606.19165a","type":"ffmpeg-spawn","z":"e193914.078e67","name":"","outputs":5,"migrate":1e-9,"cmdPath":"ffmpeg","cmdArgs":"[\"-re\",\"-stream_loop\",\"-1\",\"-i\",\"/home/pi/Qvideos/AMA_by_Julie_Gautier.mp4\",\"-bsf:a\",\"aac_adtstoasc\",\"-c:v\",\"copy\",\"-f\",\"mp4\",\"-movflags\",\"+frag_keyframe+empty_moov+default_base_moof\",\"pipe:1\"]","cmdOutputs":4,"killSignal":"SIGTERM","x":340,"y":180,"wires":[["6fa778b2.984748"],["6fa778b2.984748"],[],[],[]]},{"id":"fefa83f.91c2e8","type":"inject","z":"e193914.078e67","name":"start default","props":[{"p":"action","v":"{\"command\":\"start\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":"1","topic":"","payloadType":"str","x":120,"y":140,"wires":[["1d252606.19165a"]]},{"id":"dd4ea19f.2afee","type":"inject","z":"e193914.078e67","name":"stop default","props":[{"p":"action","v":"{\"command\":\"stop\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"str","x":120,"y":220,"wires":[["1d252606.19165a"]]},{"id":"a40b3aed.b0a918","type":"comment","z":"e193914.078e67","name":"start ffmpeg","info":"","x":120,"y":104,"wires":[]},{"id":"6e73c22e.fe57dc","type":"comment","z":"e193914.078e67","name":"stop ffmpeg","info":"","x":120,"y":180,"wires":[]},{"id":"6fa778b2.984748","type":"mqtt out","z":"e193914.078e67","name":"","topic":"mp4_345_test","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"ed237c6b.40d1b","x":570,"y":160,"wires":[]},{"id":"4617d743.771aa8","type":"comment","z":"e193914.078e67","name":"Client side (machine xy)","info":"","x":150,"y":640,"wires":[]},{"id":"5d4a1672.e90538","type":"change","z":"e193914.078e67","name":"","rules":[{"t":"set","p":"background","pt":"msg","to":"green","tot":"str"},{"t":"set","p":"txt","pt":"msg","to":"Streaming ON","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":890,"wires":[["371dc912.1723b6"]]},{"id":"61205bd6.757aa4","type":"switch","z":"e193914.078e67","name":"","property":"payload","propertyType":"msg","rules":[{"t":"nempty"},{"t":"empty"}],"checkall":"true","repair":false,"outputs":2,"x":750,"y":790,"wires":[["5d4a1672.e90538"],["ea0f87a0.a9a9c8"]]},{"id":"f1b369f9.af9dd8","type":"change","z":"e193914.078e67","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"command\":\"start\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":290,"wires":[["1d252606.19165a"]]},{"id":"ac1c1ece.98579","type":"change","z":"e193914.078e67","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"command\":\"stop\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":330,"wires":[["1d252606.19165a"]]},{"id":"d46a1000.7ed04","type":"debug","z":"e193914.078e67","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":440,"y":460,"wires":[]},{"id":"ed237c6b.40d1b","type":"mqtt-broker","name":"test.mosquitto.org","broker":"test.mosquitto.org","port":"1883","tls":"ce0f0716.0b63b8","clientid":"","usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"sessionExpiry":""},{"id":"9c7f211e.e2d06","type":"ui_group","name":"Video over MQTT","tab":"4ea63eac.dccaf","order":1,"disp":false,"width":"6","collapse":false},{"id":"ce0f0716.0b63b8","type":"tls-config","name":"","cert":"","key":"","ca":"","certname":"","keyname":"","caname":"","servername":"","verifyservercert":true},{"id":"4ea63eac.dccaf","type":"ui_tab","name":"Video over MQTT","icon":"dashboard","disabled":false,"hidden":false}]
2 Likes

Yes, good alternative.
I'm still thinking on something else, in my particular case, and making test.
Since I have a server, which is the only place where user login, I'm trying to use this configuration, even because a node-red instance is running on the server as well keeping contact with the others local instances:
When a user login, a msg is sent every x time via mqtt that is read by the local instance. Locally, with this message is easy enough to implement the counter I posted here Sending rtsp camera streaming over internet - #30 by Lupin_III , substituting the ui_control with a function node with some kind of filters code

Depends what & why you want to achieve. I thought you wanted to save costs or bandwith to each client and what I wrote was that nothing will help unless the client unsubscribes from the topic. As long as the cllient is subscribed, buffer data will flow to him and consume bandwith both from the server and to the client

The wanting of saving unused bandwidth is mainly for the server (that can have several cameras streaming) and for the instance running locally, which send the streaming. For this I would like to avoid manually to turn on/off the video.

Not really sure about your use case. I have understood you would like to

  • stream to external clients and automatically shutoff streaming to them when no external client is watching anymore
  • stream to local clients as well
    Is this correct?

If so, you could build further on your (external) client connected counter idea. If you got that part working I could imagine to use gate nodes to turn video distribution on/off

First of all you could publish the video to two mqtt topics; one for local usage in a local machine running a local mqtt broker and the second topic in the remote mqtt broker. Then publish the video to the external mqtt topic via a gate node (video out channel). Then as long as you have at least one external client connected, keep the gate open, when no external client is connected, close the gate and no video will be published to the topic. Repeat the same typ of setup for each camera. This would close all channels automatically that are not currently used for viewing. You also have to have a mechanism so that a client can notify interest in watching a specific camera, i.e. being able to send a message via mqtt to tell the server to open the specific gate/gates

Yes, thanks a lot Krambriw.
For local clients (I mean the ones within the IP camera Lan) the client can see the straming directly with the ui_mp4frag, without needing of a local mqtt brocker.

Yes correct, that is true if you want. I don't know what would be most efficient though. Take the rtsp once and create video buffers distributed via mqtt locally or each client having to grab the rtsp stream by itself

Another thing I thought of when you are counting number of connected external clients. I think you actually have to count per camera how many are watching it to be able to know when you can turn the stream for the specific camera off or on. So when a client connects or is connected it will have to update the server for each camera it is viewing

Yes, some test is needed

You're right, correct

I did some playing around with this a bit over a year ago. Short answer is its going to depend on now many active camera streams, the camera resolution, and the power of the clients.

For example, the Pi4B is not particularly good at decoding 4K UHD RTSP streams, one is about it (can do 4-6 1080p depending on how low a frame rate you can accept, I consider ~3 fps per camera about right to feed into my AI sub-system).

I expected feeding it MQTT image buffers instead would help, but turns out the Pi4B network layer is not up to the task. Feeding an i3 class machine with real Gbit Ethernet using MQTT buffers could handle more cameras.

Feeding mp4fragments via MQTT I would guess would maybe be somewhere between sending jpeg image buffers (network limitations) and rtsp stream decoding (CPU/GPU limitations), on the assumption that the mp4fragments somewhat split the RTSP workload between server and client, but I could be mistaken here -- I've been following these threads but haven't had any time to actually try the nodes.

My bias for security cameras is that resolution is far more important than frame rate. There have been a fair number of high profile US court cases where "standard" D1 type resolution was not of good enough quality for the "beyond a reasonable doubt" legal standard, which is not helped by the fact the perps generally get a shave, haircut, and new suit for their court appearances.