MQTT won't send stop command to ffmpeg spawn node

Hey @kevinGodell could you please help me again sir? I'm using a function node with an MQTT IN node attached. I can send an MQTT messgae to "start" the ffmpeg spawn node of yours, but when I try to stop the ffmpeg spawn node, it essentially ignores it. Even when the flow is idle or has been redeployed, and I send the stop message through MQTT, it actually starts the stream. I've tried to analyze your code in the node itself to see if there's something to give me a clue, but honestly I'm not experienced enough to know how your kill process is executed.

Here is a couple of different examples of the coding I've attempted with the function node:

#1

var payload = msg.payload; //get payload

if (msg.payload == "on") {
    msg.action = {
        "command": "start"
    };
    return msg;
}
 else if (msg.payload == "off") {
    msg.action = {
        "command": "stop"
    };
    return msg;
}
return null;

#2

var payload = msg.payload; //get payload

if (msg.payload == "on") {
    msg.action = {
        "command": "start"
    };
    return msg;
}
 else if (msg.payload == "off") {
    msg.SIGKILL = {
        "command": "stop"
    };
    return msg;
}
return null;

Here is what my flow looks like. I have the function node notionally acting like PiR sensor to trigger the camera when motion is detected. The debug output shows when the spawn node was started with the mqtt, but it shows how it was ignored when I tried to stop it. The kill process was done via the direct inject.

That block of code worked for me in a function node to detect on/off and then send the correct message to start/stop ffmpeg.

I think that on windows, you may need a different kill code because sometimes ffmpeg does not want to exit normally. If you could include more details about the ffmpeg command and your operating system and even the version of ffmpeg that could help to diagnose the issue. Maybe a screenshot of the ffmpeg node settings window, too.

Thank you for testing on your end. I'm running my node-red on the latest Ubuntu release, Ubuntu 22.04.1 LTS with ffmpeg version 4.4.2 running.

Here is a screen shot of the ffmpeg node config window.

I've attempted again this morning to get ffmpeg to stop streaming, but it keeps ignoring my command. As you can see from the debug output, it sees the command and processes it, but nothing happens as far as the process stopping.

I can't really see the flaw. Maybe there is a typo somewhere in your code. Try this function node. It checks payload for on or off and then passes the action command to my ffmpeg node and promptly starts and stops it.

[{"id":"4475d1eeed5ddc6d","type":"inject","z":"0528fb314ac39109","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"on","payloadType":"str","x":410,"y":520,"wires":[["3b3f823455d5f232"]]},{"id":"3b3f823455d5f232","type":"function","z":"0528fb314ac39109","name":"","func":"const { payload } = msg;\n\nif (payload === 'on') {\n    return { action: { command: 'start'} };\n}\n\nif (payload === 'off') {\n    return { action: { command: 'stop' } };\n}\n\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":580,"wires":[["b0bbbcc64e2253d3"]]},{"id":"06f068924b6aee93","type":"inject","z":"0528fb314ac39109","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"off","payloadType":"str","x":410,"y":580,"wires":[["3b3f823455d5f232"]]},{"id":"3893a0d24ca73e02","type":"inject","z":"0528fb314ac39109","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"junk","payloadType":"str","x":410,"y":640,"wires":[["3b3f823455d5f232"]]},{"id":"b0bbbcc64e2253d3","type":"debug","z":"0528fb314ac39109","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":770,"y":580,"wires":[]}]

I think my problem is in the MQTT messaging. I can get the direct injects to work just fine, it's just when I put the MQTT node in place of the direct inject nodes, is where my issues stem.

In that case there must be a difference between the messages that work and those that don't. Send them to debug nodes set to output the complete message and check them carefully.

1 Like

I added a debug node to each output of the function node to see exactly what is going on.

Here is the output from debug when I send the "on" message from MQTT

Here is the code that I have set in my function node, as well as the debug output when I attempt to send the "off" message via MQTT to stop the video, which isn't working. I am seeing "undefined" in the debug 6 node, which is what I'm assuming is my hiccup.

Thank you for your willingness to assist!

In future please copy/paste code rather then screenshot, then I could have editted it.
It should be
const payload = msg.payload

1 Like

Thank you for the quick reply Colin, I'll set that and see what she turns out.

Holy cow, I just figured out my issue and fixed it!

Previous code used:

var payload = msg.payload; //get payload

if (msg.payload == "on") {
    msg.action = {
        "command": "start"
    };
    return msg;
}
 else if (msg.payload == "off") {
    msg.action = {
        "command": "stop"
    };
    return msg;
}
return null;

Code that Works:


const payload = msg.payload

if (msg.payload == "on") {
    msg.action = {
        "command": "start"
    };
    return [msg,null];
}
else if (msg.payload == "off") {
    msg.action = {
        "command": "stop"
    };
    return [null,msg];
}
return null;

nice. So you had 2 outputs on the function node?

1 Like

Yes sir, and that was where my hang up was kicking me in the teeth. I looked on one of the pages that Steve Cope has:

and studied his example for using two outputs and saw that my return statements were wrong. I went back to my code of my function node and added them the way he has them and low and behold it worked like magic!!!

Sorry if I seem overly excited but I've been struggling with this for a good while now. Nearly 2 months of trying to get this work, and now it does!!!

2 Likes

It is better to use triple = as you originally had.
if (msg.payload === "on") {

The more node-red way to do this would be to use a Switch node to split the messages down two paths dependent on on the value in msg.payload and then a Change node in each leg to set the action, both then feeding the next node.

I used a switch node in my initial design that I posted in a previous post, but I couldn't get the MQTT messages at that time to start the video streams. That's why I went with the function node in this instance of testing.