How to display CCTV camera in dashboard (RTSP)

Hello Mat,

Instead of writing yet-another-ffmpeg-node, I have compared the existing Node-RED contributions:

  1. node-red-ffmpeg has some disadvantages:

    • It keeps only track of 1 (spawned) proces. So if you start a second one in parallel, you cannot close the first one decently.
    • The readme page shows that the functionality is limited
    • The ffmpeg_process.stdout.on will append data (to the previous data) until the response is complete. However I 'think' this might be a problem when you have an infinite RTSP stream (where we want an output message for each image).
  2. node-red-contrib-dynamorse-ffmpeg are rather specific nodes (e.g. AACencoder …), which I 'think' are a bit too specific for our purpose.

  3. node-red-contrib-princip-ffmpeg is experimental.

  4. node-red-contrib-media-utils contains a.o. ffmpeg nodes. The disadvantages:

    • The nodes have rather specific functionality (e.g. only for specific audio formats)
    • I 'think' these nodes create a input file --> let ffmpeg process that input file --> read the output file that ffmpeg has created. If I'm right, a lot of disc IO is involved. That is not what we want, since we only want to pass data via memory...
  5. node-red-contrib-viseo-ffmpeg seem to be the right choice for our purpose, since it has a lot of advantages:

    • It keeps track of all (spawned) processes, so they can all be handled correctly (e.g. close all the streams automatically when the flow is redeployed).
    • As soon as data has arrived, it will send an output message (which is exactly what we need for every image in an infinite RTSP stream).
    • All data between ffmpeg and Node-RED is passed via memory (so no disc IO). Indeed the ffmpeg process passes data to Node-RED via the stdout stream/pipe, and errors via the stderr stream/pipe.

    But this node also has a disadvantage: two other nodes (that the node depends on), have to be installed manually. I have logged an issue about this, and hopefully we get a solution. In the issue you can find a temporary workaround...

Another disadvantage (in all 5 cases) is that ffmpeg needs to be installed manually, which is a rather slow process. I found that ffmpeg-binaries could be used to install pre-build binaries of ffmpeg on a series of known platforms. However it failed on my Raspberry Pi 3, which I 'think' might be related to this issue. Summarized currently you will have to install ffmpeg manually...

Here is my test flow:
image

[{"id":"86ab3e95.61eb5","type":"ffmpeg-command","z":"18e47039.88483","name":"RTSP via FFMPEG","output":"payload","outputType":"msg","cmd":"-i \"rtsp://184.72.239.149/vod/mp4:BigBuckBunny_175k.mov\" -f image2pipe -hls_time 3 -hls_wrap 10 pipe:1","cmdType":"str","spawn":"true","x":1390,"y":200,"wires":[["377fe881.b68d18"]]},{"id":"f89dff57.9f288","type":"inject","z":"18e47039.88483","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1200,"y":200,"wires":[["86ab3e95.61eb5"]]},{"id":"377fe881.b68d18","type":"function","z":"18e47039.88483","name":"Move output","func":"if (msg.payload.stdout) {\n    msg.payload = msg.payload.stdout;\n    return msg;\n}\n","outputs":1,"noerr":0,"x":1590,"y":200,"wires":[["5186e7cf.8be3e8"]]},{"id":"5186e7cf.8be3e8","type":"image","z":"18e47039.88483","name":"","width":200,"x":1771,"y":200,"wires":[]}]

The core of the solution is the list of arguments that I pass to the ffmpeg executable:

-i "rtsp://184.72.239.149/vod/mp4:BigBuckBunny_175k.mov" -f image2pipe -hls_time 3 -hls_wrap 10 pipe:1

Some explanation of that argument list:

  • The input '-i' will be the rtsp link
  • Since we have no output file, ffmpeg cannot 'guess' the output format from the file extension (e.g. jpeg). Therefore we will have to specify that the format '-f' will be an image to a pipe (image2pipe).
  • Then there are some parameters about the rtsp stream (hls_time, hls_wrap).
  • At the end we will have specify where the output (i.e. the images) will need to go to. In this case the output will need to go to the first pipe (pipe:1), which means stdout.

The argument list is very complex to create, but it is very powerful. We could create a dedicated node-red-contrib-rtsp node, that hides this complex line to the user. However there are an enourmous amount of different argument combinations possible (to do all kind of great audio/video conversions), so - in my humble opinion - it becomes unmaintainable to create a dedicated node for every purpose. Therefore I think such a generic reusable ffmpeg node is a better solution.

Although it should be nice if we had some kind of central place where people could share there argument lists for the ffmpeg node? Don't know if this forum is the best place ??

Have fun with it!!
Bart

2 Likes