# Display camera ip in dashboard and store video in raspberry

**URL:** <https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349>\
**Category:** General\
**Created:** [3 January 2019 14:37 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349 "2019-01-03T14:37:07Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![gaara7271](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gaara7271/32/7474_2.png) [@gaara7271](https://discourse.nodered.org/u/gaara7271)\
**Post date:** [3 January 2019 14:37 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/1 "2019-01-03T14:37:07Z")

</div>

Hi everyone  
i have camera ip support protocols such as http, tcp, rtsp, ftp,...  
i want store video and display video in dashboard, review history.  
what is easy way? what should i do? can you help me?  
my english is not very good. thank you.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [3 January 2019 17:18 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/2 "2019-01-03T17:18:03Z")

</div>

Hi Kientrung,

- In case you want to connect to camera via http (snapshot JPEG images or MJPEG streams), see my explanation [here](https://discourse.nodered.org/t/how-to-stream-with-ip-camera-on-ubuntu/3135/6?u=bartbutenaers).
- For RTSP streams we had recently an interesting discussion, and the result was that you can have multiple options (ffmpeg, avconv, vlc media player, motion software). In case you are interested in the ffmpeg solution, see my post [here](https://discourse.nodered.org/t/how-to-display-cctv-camera-in-dashboard-rtsp/5860/47?u=bartbutenaers).
- In case you want to store video and review the history, you will need to store the camera images somewhere from your flow (again with ffmpeg, motion, ...) into a directory. Afterwards you have to show somehow the directory listing into you dashboard. That is on my large todo list, but I have not done something like that yet ...

Bart

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [3 January 2019 20:58 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/3 "2019-01-03T20:58:54Z")

</div>

Hi everybody,

My good intention for 2019 was to keep focussed, and not being distracted by new posts on this forum.  
I have persisted for more than 2 days now, which is a personal record...

I'm wondering **_how we can store separate images as a video_** (e.g. an mp4 file), so we are able to view it afterwards. Most probably (??) it can be done with tools like Motion, ... but I would like to try it with ffmpeg (in combination with the Exec-node).

- **FFMEG OUTPUT STREAM**  
As mentioned above, there was a nice discussion recently to decode an RTSP stream to seperate images (which were send across the Node-RED wires). To accomplish that, I had used an Exec-node to execute an Ffmpeg command:

- **FFMPEG INPUT STREAM**  
Ok so far so good. Now I want to do something similar: pass images via a wire to the input of the exec node, and let Ffmpeg encode N images into an mp4 file.

Thanks !!  
Bart

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [3 January 2019 23:06 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/4 "2019-01-03T23:06:40Z")

</div>

Look at the node-red-node-daemon instead. That runs a long running process and accepts stdin (and creates stdout,stderr)

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [4 January 2019 23:20 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/5 "2019-01-04T23:20:26Z")

</div>

Hey Dave (@dceejay),  
When looking at the code of the code of [node-red-node-daemon](https://github.com/node-red/node-red-nodes/blob/master/utility/daemon/daemon.js), that seems to be indeed exactly what I was looking for. So thanks for the tip !!!

I would like to use that node for **ALL** my Ffmpeg commands, instead of the [Exec](https://github.com/node-red/node-red/blob/master/nodes/core/core/75-exec.js?pr=%2Fmetc%2Fnode-red%2Fpull%2F1#L74) node (since I can use that only for a limited set of ffmpeg commands). However my RTSP command works fine for the Exec node, but _ **I get an error for the SAME command using the daemon node** _:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/b/b8160271dac5996e674751cb9320bbbb728cdcda.png)

I don't see any major difference between both nodes, in the way they spawn my command (based on the **same** `require('child_process').spawn`):

- The exec node:  

- The daemon node calls it with 100% the same input:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/3/394ae9862c63eb8b4c62b7739aa08031e0243f06.png)

Do you have any idea in which direction I could start searching ?

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [4 January 2019 23:42 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/6 "2019-01-04T23:42:12Z")

</div>

Completely overlooked it, but it appears that the daemon node doesn't expect me specifying my own quotes:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/0/0d6e7c4fcf67ee76bdbaf62b752dcc35d729027f.png)

When I remove the quotes in my ffmpeg command, it works fine!

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [6 January 2019 22:31 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/7 "2019-01-06T22:31:15Z")

</div>

> [@dceejay](#):
>
> That runs a long running process and accepts stdin (and creates stdout,stderr)

Hey Dave (@dceejay),  
Have been trying _over-and-over again_ to create a single mp4 file from a series of images (arriving on the stdin stream). But unfortunately **no** mp4 file was generated 🥴. Now I finally figured out that I have to **flush** the data (i.e. the images) in the stdin stream, to have Ffmpeg to generate the mp4 file.

There 'should' be two solutions:

- Force Ffmpeg to process new data automatically as soon as it arrives. Would be the best solution, because I assume that otherwise memory could be filled rapidely. However I only found a _-flush\_packets_ parameter, but that doesn't change anything in my test ...
- Flush the stdin stream from the node-red-node-daemon node. But it seems that a Writable stream in NodeJs cannot be flushed. So I need to call **end()** on the stdin stream, and then it works fine ...

Question: can I create a pull request to e.g. add a checkbox '_flush input stream before killing_' which calls `node.child.stdin.end()` before `node.child.kill(...)` is executed ? Or does anybody have a better solution?

Bart

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [6 January 2019 23:17 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/8 "2019-01-06T23:17:27Z")

</div>

I'm missing something. Why does it need to call kill ? The idea of daemon is to keep running.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [7 January 2019 19:17 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/9 "2019-01-07T19:17:55Z")

</div>

Dave (@dceejay) ,  
you have a good point! But now I'm not sure anymore if I need to use the Exec node, the Daemon node, or whatever other node ... I just want to execute Ffmpeg with following functionalities:

- I need **stdout** and **stderr** for example to inject images into my flow.
- I need **stdin** for example to receive images from my flow.
- I need to be able to send signals to a running process, to be able to pause/resume/stop a running process. Indeed a process might run for a long time, e.g. an RTSP stream that capture live video from an ip camera.

And I would like to do everything with a **single** node (so not Exec node for ffmpeg command A and Daemon node for ffmpeg command B), to avoid confusing our users...

Do you know any node that supports all of this? Or which node I'm allowed to upgrade (via a pull request) to accomplish this?

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [7 January 2019 22:21 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/10 "2019-01-07T22:21:01Z")

</div>

Probably neither 🙂 or both :-)...

daemon is meant to run a fixed command (with parameters) for a long time (ie continuously in the background) - and accepts stdin and provides stdout and stderr - so fine for handling conversions as long as you aren't going to be changing parameters. - You can kill a process and restart it - but it will restart the same - You can use stdin for control if the program you are running allows you to.

exec is better for single calls as you can pass in different parameters each time - but it won't accept stdin (so ok for pointing at a file or url to convert etc - but not for images via a previous node)

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [10 January 2019 20:16 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/11 "2019-01-10T20:16:42Z")

</div>

Hi folks,

I'm completely stuck, so could use some help!!!!

The **node-red-node-daemon** node allows me to spawn FFmpeg in a separate process. Moreover I can send data to that process via a **stdin** stream, and receive results from it via a **stdout** stream (and error information via a **stderr** stream):

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/9/985c2cadc0d8ed84b115b6b0022402225dbb2a18.png)

So far so good. Everything is going through memory, and no slow disc I/O is required (to read/write temporary files).

Let's create a simple example node to **resize images** (to size 320x240). The input messages contain an image, and the output messages will contain a resized image:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/f/f0f77b694c9bb36d8da4560fb9cbfa90fb2be95b.png)

These are the FFmpeg command parameters, that I entered originally in the daemon node:

```auto
-f image2pipe -i pipe:0 -vf scale=320:240 -f image2pipe pipe:1

```

- The `-f image2pipe` format allows me to read images from a stream.
- The `-i pipe:0` defines that that input stream will be **stdin**.
- The `-vf scale=320:240` specifies that the image needs to be resized to 320x240.
- The `-f image2pipe` format specifies that the output needs to be written to a stream.
- The `pipe:1` at the end defines that that output stream will be **stdout**.

However when I inject an image on the node's input, **nothing appears on the its output** (i.e. no output message is send). _The only solution I found is by ending the input stream, to force the input data to be **flushed** _:

```auto
node.child.stdin.write(msg.payload); // Existing statement
node.child.stdin.end(); // New extra statement added

```

Then the resized image appears nicely on the output, as you can seen on the above flow screenshot. However the FFmpeg process will be ended also, and needs to be spawned again. Since this will occur for every image that arrives on the input, it will result in a lot of **overhead**. 😟

I don't want that. _The FFmpeg process needs to keep running, and infinitely needs to keep processing images that arrive on the stdin input stream_. Have travelled across the whole globe, but cannot accomplish this. Here are some experiments that I have done:

- Had a tip from one of my partners (@btsimonh) to play with the [drain](https://groups.google.com/forum/#!topic/nodejs/BxsJTU-XuWQ) events. Have debugged the writable stdin stream in NodeJs, but it looks to me that the HighWaterMark hasn't been exceeded. So I don't think this is a data overflow problem, since I haven't exceeded any data limit.
- FFmpeg can loop all images in a directory and process them all (you can find plenty of examples to accomplish that). So FFmpeg needs to have something inside to **loop** its processing, without quitting after the first image. Have tried the below option (see [documentation](https://ffmpeg.org/ffmpeg.html)) but it doesn't help:

```auto
-stream_loop number (input)
Set number of times input stream shall be looped. Loop 0 means no loop, loop -1 means infinite loop.

```

In older FFmpeg versions this parameter was called `-loop`, but that also doesn't work.
- [Seems](https://stackoverflow.com/questions/34264688/how-to-flush-nodejs-child-process-stdin-write) there is another way to flush the stdin stream by writing "\n" to it, but nothing happens:

```auto
node.child.stdin.write(msg.payload); // Existing statement
node.child.stdin.write("\n"); // New extra statement added

```

- And today during the afternoon tea, our friend @dceejay had a [tip](https://stackoverflow.com/questions/50574086/ffmpeg-flushing-output-file-every-chunk) to flush the stdout stream using the `-blocksize 2048 -flush_packets 1` options but again nothing happens.

Have tried to get some extra information by adding the `-loglevel debug` parameter, but I didn't learned anything from it 🥴

**Any other tips ????????????????????????????????**

Bart

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [10 January 2019 21:18 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/12 "2019-01-10T21:18:44Z")

</div>

Have never doubted about Dave's skills, but it seems he is right again...

1. I ask FFmpeg to log as much as possible:

2. Then I add a debug node to the second output (which represents stderr), because FFmpeg will write all log data there:

3. As soon as I inject an input image, a debug message is **immediately** created (although **nothing** appears on the first output, i.e. no resized image on stdout):

4. So FFmpeg **immediately** receives 14211 bytes of data, which is the **entire image** as you can see in my debugger:

_So the question has become: how can I force FFmpeg to process the image as soon as he received it (without stopping processing other images)._

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [10 January 2019 21:38 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/13 "2019-01-10T21:38:20Z")

</div>

I suspect it may not be ffmpeg which is buffering, but stdio and the pipe. Instead of using the command `ffmpeg ....` try `unbuffer ffmpeg ....`.  
You may have to

```bash
apt install expect

```

to get the unbuffer command. No guarantees but worth trying.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [10 January 2019 21:55 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/14 "2019-01-10T21:55:10Z")

</div>

Hi Colin (@Colin),  
indeed in this [NodeJs](https://github.com/nodejs/node/issues/2985) issue they use the **unbuffer** mechanism. When I try this:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/c/c155a6e234a1992e88755b906af88d892af8392a.png)

Then I think the other (FFmpeg related) input parameters get lost somewhere, because this is my output now:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/6/670a4fb5cb9b1f7aefeba6baccf932c4c724b8ee.png)

But as I see above, FFmpeg receives the entire file. He just needs to process it, output it and wait for another input image. I had expected `-stream_loop -1` would have allowed that ...

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [10 January 2019 21:56 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/15 "2019-01-10T21:56:21Z")

</div>

Did you try the `-flush_packets` option (of ffmpeg) ?

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [10 January 2019 22:04 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/16 "2019-01-10T22:04:04Z")

</div>

Did you try unbuffer without the -p option?

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [10 January 2019 22:21 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/17 "2019-01-10T22:21:37Z")

</div>

> [@Colin](#):
>
> Did you try unbuffer without the -p option?

When I only remove the '-p'

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/3/33d4b7f275056fdfa5e19a99fb3f6211531a452f.png)

Then I get the same error ...

> [@dceejay](#):
>
> Did you try the `-flush_packets` option (of ffmpeg) ?

Yes it use it in all my experiments now:

```auto
-f image2pipe -i pipe:0 -vf scale=320:240 -f image2pipe -blocksize 2048 -flush_packets 1 pipe:1

```

I did not dare to remove it anymore, from the moment you have advised that parameter to me 🤔

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [10 January 2019 23:32 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/18 "2019-01-10T23:32:46Z")

</div>

This is truly maddening - the ffmpeg doc imply that -flush\_packets will act as soon as a packet arrives - but the spawn stdin says it won't close the packet unless the application tells it to - so they both seem to waiting for each other...

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [11 January 2019 07:42 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/19 "2019-01-11T07:42:57Z")

</div>

@BartButenaers I have lost track slightly as to what the purpose of what you are doing is. I think earlier you said you wanted to combine the pictures into an mp4 file or similar. If that is the case then you can tell ffmpeg to output directly to that file. Perhaps that is not what you are trying to do now though.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [11 January 2019 08:54 UTC](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/20 "2019-01-11T08:54:29Z")

</div>

Morning Colin (@Colin),

Indeed I should have explained that. The question in this discussion was to save video footage from a camera. That is perhaps very easy with external tools (like Motion, ...), but you know me: I want to integrate this entirely inside Node-RED, which is possible by using FFmpeg.

So I did an experiment:

1. Getting images from a camera (using an mpjeg stream or an rtsp stream): both work fine.
2. Inject those images into a **daemon** node, and let FFmpeg create an mp4 file from those images.

However the mp4 file is only created when I end the stdin stream. This is not what I want since all images are being queued in memory, which might blow up my system. And I want FFmpeg to keep running. First I thought that FFmpeg was queueing the images, because mp4 does a compression between **multiple** images (and he perhaps does need N images before he could start creating an mp4 file). But afterwards I thought: perhaps FFmpeg doesn't start compressing until **_ALL_** (whathever that means) images have arrived.

But then I realised that _ **even a simple use case doesn't work** _: if I try to resize a single image, I only get a resized image as output when I end the stdin stream. And that is not normal, so I'm doing something wrong!

Have been experimenting and guessing for 3 evenings, and now I have enough of it. I have build a debug version of FFmpeg and attached a Visual Studio Code debbuger to it. Hopefully I can now **debug the C code** what is going wrong, if I can find some time this weekend ...

Will keep you guys informed.  
Bart

[Next page](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349.md?page=2)
