OBS is one of the staples of live streaming videos now. It is the preferred software for streaming to Twitch, one of the most popular live video sites around. There are some really nice add-ons to allow a streamer to control things from their phone or another screen without disrupting the running video. It turns out, it is really easy to build your own control panel using Node-RED and the obs-websockets plugin.
I know what many of you are thinking—"He said WebSockets and easy in the same sentence?" Many people have had difficulty setting up and using WebSockets, which allow for bi-directional communication over a single connection via a web server. Node-RED has built-in support for WebSockets and is the part that makes this easy, at least compared to writing your own client/server.
Before starting, make sure you have OBS installed and configured. Start by downloading and installing the latest stable release of the obs-websockets plugin. For this article, the default settings are fine, but I strongly recommend following the instructions for securing obs-websockets in the future.
Next, download and install Node-RED, either on the same system or on a different one (like a Raspberry Pi). Again, the default installation is fine for our purposes, but it would be wise to secure the installation following the directions on their site.
Now for the fun parts. Start Node-RED and open up the web interface (by default at http://localhost:1880), and you have a blank canvas. Open up the "hamburger" menu on the right and select "Manage Palate." Then click on the "Install" tab and search for the "node-red-contrib-dashboard" and "node-red-contrib-rbe" modules.
Once those are installed, click on the right-hand list and drag-and-drop the following blocks to the canvas:
- 1 Websocket Out
- 1 Websocket In
- 1 Debug
- 1 Inject
- 1 Switch
- 1 Change
- 2 JSON
- 1 Catch
Connect them in the following orders:
When the button is pushed (or the Inject node sends a timestamp), a payload is sent through the change node, converted from a JSON object to a string, then sent to the WebSocket Out node. When a message is received by the WebSocket In node, it is converted to a JSON object, and if it is not a duplicate, sent to the Debug node for output. And the Catch node will catch any errors and put them into the debug panel.
What is in that payload? Let's set everything up and find out.
First, double click the
button to open the settings dialog. Start by changing the payload to "JSON" using the drop-down menu. In the field, add the following:
Enable the checkbox for "If msg arrives on input, emulate a button click" and click Done to close the button config. When a message comes from the Inject node, or if the button is pressed in the UI, it will send the JSON payload to the next node.
Now open up the Change node. We want to set
msg._msgid by changing the first field from
payload.message-id and then using the drop-down on the second field to change the type from
msg., then we will put
_msgid in the field. This copies the unique message ID to the JSON object payload so that each request has a unique ID for tracking.
This is then sent to the JSON node to convert from a JSON object to a string, and then passed to the Websocket Out node. Open up the Websocket Out node to configure the connection to OBS. First, change the
Connect to and then click the pencil icon to create a new connection URL. Set that to
ws://OBSMachine:4444/ and close the dialog to save.
OBSMachine is the name of the machine OBS and obs-websocket are running on. For example, if Node-RED is running on the same machine, this would be
ws://localhost:4444, and if it is on a machine named "luxuria.local" then it would be
ws://luxuria.local:4444. Close and update the Websocket Out node. This sends the payload text string to the WebSocket in OBS.
On to the WebSocket In flow! Open the WebSocket In node, and set it to a
Connect to and the URL to the connection we defined before (it should auto-fill). Next in line is the second JSON node, which we can leave alone. This accepts output from OBS and converts it into a payload object.
Next, we will filter the regular heartbeat and status updates from everything else. Open up the switch and set the "Property" value to
payload["update-type"]. Now select
Is Not Null from the drop-down below it. Click
+ to add a second option and select
otherwise from the drop-down.
Connect the new output on the switch directly to the Debug node input.
The RBE node, which will filter out duplicates, needs to be told what field to watch for. Since it should be connected to the output from the switch that sends nothing but status updates, this is important, as obs-websocket is sending updates every few seconds. By default, the RBE compares the entire payload object, which will constantly be changing. Open up the RBE Node, and change the
payload.streaming. If the
streaming value of the payload changes, then pass the message through; otherwise, discard it.
The final step is to change the Debug node output from
msg.payload to the complete msg object. This allows us to see the entire object, which sometimes has useful information outside the
Deploy to activate the changes. Hopefully, the WebSocket nodes will have a green "Connected" message underneath them. If they are red or yellow, the connection URL is likely incorrect and needs to be updated, or the connection is being blocked. Make sure that port 4444 on the remote machine is open and available, and that OBS is running!
Without the RBE node filtering on the
streaming value, the debug panel (the bug icon on the right of the canvas) would be filling with Heartbeat messages about now. Click the button to the left of the Inject node to send a signal that will simulate a button click. If all is well, you should see an object arrive that has a listing of all the things
obs-websocket can do.
Now open up
http://localhost:1880/ui in another tab or window. It should show a single button. Press it! The debug panel should show the same information as before.
Congrats! You have sent your first (and hopefully not last) WebSocket message to OBS!
This is just the beginning of what can be done with
obs-websockets and Node-RED. The complete documentation of what is supported is documented in the protocol.md file in the GitHub repository for obs-websockets. With a little experimentation, you can create a full-featured control panel to start and stop streaming, change scenes, and a whole lot more. If you are like me, you'll have all kinds of controls set up before you know it.