# How to build a video surveillance system from scratch?

**URL:** <https://discourse.nodered.org/t/how-to-build-a-video-surveillance-system-from-scratch/51077>\
**Category:** General\
**Created:** [15 September 2021 20:43 UTC](https://discourse.nodered.org/t/how-to-build-a-video-surveillance-system-from-scratch/51077 "2021-09-15T20:43:10Z")\
**Posts on this page:** 1\
**Showing post:** 33

<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 October 2021 19:44 UTC](https://discourse.nodered.org/t/how-to-build-a-video-surveillance-system-from-scratch/51077/33 "2021-10-03T19:44:23Z")

</div>

> [@kevinGodell](#):
>
> That is why **pipe2jpeg** was created, and years later **node-red-contrib-pipe2jpeg**. It can handle all sizes of jpegs. Just plug that node after the ffmpeg's jpeg buffer output.

Awesome! That indeed works fine even at the highest resolution:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/0/90d4c5af829ae1131d0dbd86b1ca04d594be210f.png)

```auto
[
    {
        "id": "1c9e5395db440d48",
        "type": "inject",
        "z": "09a003ecac576bb5",
        "name": "start default",
        "props": [
            {
                "p": "action",
                "v": "{\"command\":\"start\"}",
                "vt": "json"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": "1",
        "topic": "",
        "x": 370,
        "y": 1580,
        "wires": [
            [
                "3533dab8e87d80f0"
            ]
        ]
    },
    {
        "id": "3533dab8e87d80f0",
        "type": "ffmpeg-spawn",
        "z": "09a003ecac576bb5",
        "name": "Rtsp stream cam hikvision",
        "outputs": 2,
        "cmdPath": "ffmpeg",
        "cmdArgs": "[\"-loglevel\",\"quiet\",\"-rtsp_transport\",\"tcp\",\"-i\",\"<your_rtsp_url>\",\"-f\",\"image2pipe\",\"-c\",\"mjpeg\",\"-vf\",\"fps=fps=4\",\"pipe:1\"]",
        "cmdOutputs": 1,
        "killSignal": "SIGTERM",
        "x": 620,
        "y": 1600,
        "wires": [
            [],
            [
                "f5d45781ec2de11f"
            ]
        ],
        "info": "ORIGINAL Kevin ffmpeg:\n------------------------\n[\n \"-loglevel\",\n \"error\",\n \"-nostats\",\n \"-f\",\n \"hls\",\n \"-http_multiple\",\n \"1\",\n \"-re\",\n \"-i\",\n \"https://weather-lh.akamaihd.net/i/twc_1@92006/index_1200_av-p.m3u8?sd=10&rebase=on\",\n \"-c:v\",\n \"copy\",\n \"-c:a\",\n \"aac\",\n \"-f\",\n \"mp4\",\n \"-movflags\",\n \"+frag_keyframe+empty_moov+default_base_moof\",\n \"pipe:1\",\n \"-progress\",\n \"pipe:3\",\n \"-f\",\n \"image2pipe\",\n \"-vf\",\n \"select='eq(pict_type,PICT_TYPE_I)',scale=trunc(iw/4):-2\",\n \"-vsync\",\n \"vfr\",\n \"pipe:4\"\n]"
    },
    {
        "id": "dc99fd8dde2910c4",
        "type": "inject",
        "z": "09a003ecac576bb5",
        "name": "stop default",
        "props": [
            {
                "p": "action",
                "v": "{\"command\":\"stop\"}",
                "vt": "json"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payloadType": "str",
        "x": 370,
        "y": 1640,
        "wires": [
            [
                "3533dab8e87d80f0"
            ]
        ]
    },
    {
        "id": "8c77927894271e70",
        "type": "image",
        "z": "09a003ecac576bb5",
        "name": "",
        "width": "320",
        "data": "payload",
        "dataType": "msg",
        "thumbnail": false,
        "active": true,
        "pass": false,
        "outputs": 0,
        "x": 1060,
        "y": 1600,
        "wires": []
    },
    {
        "id": "f5d45781ec2de11f",
        "type": "pipe2jpeg",
        "z": "09a003ecac576bb5",
        "name": "",
        "x": 860,
        "y": 1600,
        "wires": [
            [
                "8c77927894271e70"
            ]
        ]
    }
]

```

> [@kevinGodell](#):
>
> try this flow to create a jpeg once per 30 seconds using mp4frag and a 2nd ffmpeg-spawn:

I have some questions about this flow:

1. The first ffmpeg command contains "-f mp4": is that because the camera uses H264? I think I'm mixing up things now ...

2. The first ffmpeg command also contains "pipe:1" and "pipe:3" but not "pipe:2". Is "pipe:2" stderr or why isn't that used?

3. Would be nice if you could explain a bit more in detail what the parameters in the mp4frag (playlist, prebuffer and timeout) are used for. To get the (technical) picture. And if there are best practises for those values.

4. So this flow creates a jpeg once every 30 seconds. I assume the "-vframes 1" does the magic, by specifying that we want a single output image per segment? But does this mean that the segments have a length of 30 seconds?  
[EDIT] Now I see that the Inject node sends an input message every 30 seconds, and that input message contains a time limit of 3000. Will have to wait for your answer on question 3, and then I hopfully can understand why the value of 3000 is specified...

5. In the second ffmpeg node there is a "-c mjpeg", which means an MJPEG code. Is that required to get separate images?

I'm feeling bad having to ask you all those questions...  
But others might have similar doubts, and can learn from this discussion.

---

_[View the full topic](https://discourse.nodered.org/t/how-to-build-a-video-surveillance-system-from-scratch/51077)._
