Using Code to Send OSC
This guide will walk you through some examples on how to use python or javascript to send OSC. We at sndwrks obviously like code a bit and we wanted to share some simple examples.
By then end of the guide, you’ll have two working scripts in python and node.js that will allow you to send osc via the terminal anywhere you want. We find scripts like this extremely helpful for testing devices when we don’t want to use a full tool like QLab or ETC EOS.
What will I be able to do: make Confetti with Python!
# pip3 install python-oscfrom pythonosc import udp_client
server_ip = "10.0.10.100" # adjust to the server ipserver_udp_port = 52000 # adjust to the network server udp listen port
client = udp_client.SimpleUDPClient(server_ip, server_udp_port)client.send_message("/sndwrks/server/v1/confetti", [])
# run it in terminal# python3 confetti.pyTo complete this guide, you’ll need python 3.12 and node.js 24. If you already know how to set those up, skip ahead. These instructions are for macOS with Terminal.
Install Python with pyenv
Section titled “Install Python with pyenv”pyenv lets you install and switch between Python versions without touching the system Python.
-
Install pyenv with Homebrew:
Terminal window brew install pyenv -
Add pyenv to your shell. Add these lines to
~/.zshrc:Terminal window export PYENV_ROOT="$HOME/.pyenv"[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"eval "$(pyenv init -)" -
Restart your terminal, then install Python 3.12:
Terminal window pyenv install 3.12pyenv global 3.12 -
Verify it worked:
Terminal window python --version# Python 3.12.x
Install Node.js with nvm
Section titled “Install Node.js with nvm”nvm does the same thing as pyenv but for Node.js.
-
Install nvm with Homebrew:
Terminal window brew install nvm -
Add nvm to your shell. Add these lines to
~/.zshrc:Terminal window export NVM_DIR="$HOME/.nvm"[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh" -
Restart your terminal, then install Node 24:
Terminal window nvm install 24nvm use 24 -
Verify it worked:
Terminal window node --version# v24.x.x
Send with Python
Section titled “Send with Python”This script lets you send any OSC message from the command line. You pass in the server IP, port, OSC address, and any arguments.
First, install the python-osc library:
pip install python-oscThen create this script:
# the sys package allows us to read values when the file is ranimport sys# this is the library that will actually format and send our oscfrom pythonosc import udp_client
# if the file is executed without the proper arguments we should# let the user know and show them how to fix it.if len(sys.argv) < 4: print("Usage: python send_osc.py <ip> <port> <address> [args...]") print("Example: python send_osc.py 10.0.10.100 52000 /sndwrks/server/v1/confetti") sys.exit(1)
# read the arguments inputted at runtimeip = sys.argv[1]port = int(sys.argv[2])address = sys.argv[3]args = sys.argv[4:]
# initialize the clientclient = udp_client.SimpleUDPClient(ip, port)
# now send our messageclient.send_message(address, args)
# and lets show some feedback that we did that for the userprint(f"Sent {address} {' '.join(args)} -> {ip}:{port}")Usage
Send confetti with no args:
python send_osc.py 10.0.10.100 52000 /sndwrks/server/v1/confettiLog a custom event with args:
python send_osc.py 10.0.10.100 52000 /sndwrks/server/v1/event/custom "Pyro fired" "Stage left mortar"Send with Node.js
Section titled “Send with Node.js”Same idea, but in JavaScript using the osc.js library.
Set up a small project:
mkdir osc-sender && cd osc-sendernpm init -ynpm install oscThen add "type": "module" to your package.json so you can use import syntax in .js files. It should look something like this:
{ "name": "osc-sender", "type": "module", "dependencies": { "osc": "^2.4.5" }}Now create the script:
// this is the library that will actually format and send our oscimport osc from "osc";
// process.argv contains the command line arguments// the first two are the node path and script path, so we skip themconst args = process.argv.slice(2);
// if the script is executed without the proper arguments we should// let the user know and show them how to fix it.if (args.length < 3) { console.log("Usage: node sendOsc.js <ip> <port> <address> [args...]"); console.log("Example: node sendOsc.js 10.0.10.100 52000 /sndwrks/server/v1/confetti"); process.exit(1);}
// read the arguments inputted at runtimeconst [ip, port, address, ...oscArgs] = args;
// initialize a udp port pointed at our target serverconst udpPort = new osc.UDPPort({ localAddress: "0.0.0.0", localPort: 0, remoteAddress: ip, remotePort: parseInt(port),});
// once the port is ready, send our message and close itudpPort.on("ready", () => { udpPort.send({ address: address, args: oscArgs.map((a) => ({ type: "s", value: a })), });
// and lets show some feedback that we did that for the user console.log(`Sent ${address} ${oscArgs.join(" ")} -> ${ip}:${port}`); udpPort.close();});
// open the port which will trigger the "ready" event aboveudpPort.open();Usage
Send confetti with no args:
node sendOsc.js 10.0.10.100 52000 /sndwrks/server/v1/confettiBroadcast a chat message:
node sendOsc.js 10.0.10.100 52000 /sndwrks/server/v1/chat/broadcast/send "Stage Manager" "Places please" "info"Practical Example
Section titled “Practical Example”Let’s put one of these scripts to use. Say you want the sndwrks server to know when a Mac on your network has finished booting. We can create a .command file that runs on login and sends an OSC message automatically.
A .command file is just a bash script that macOS knows how execute. This is pretty neat because you can add it to your Login Items so it runs every time you log in.
Create the script
Section titled “Create the script”Create a file called startup-completed.command wherever you like. We’ll use the Desktop for this example:
#!/bin/bash
# wait a bit for the network to come upsleep 10
# send a custom event to the sndwrks serverpython ~/scripts/send_osc.py 10.0.10.100 52000 /sndwrks/server/v1/event/custom "Mac Online" "Booth Mac finished booting"Adjust the IP, port, and message to match your setup. This assumes you saved send_osc.py to ~/scripts/. Update the path to wherever yours lives. You could use the Node.js script here too, just swap the command.
Make it executable
Section titled “Make it executable”macOS won’t run it unless you mark it as executable:
chmod +x ~/Desktop/startup-completed.commandYou can double-click it now to test. Terminal should open, wait 10 seconds, send the message.
Add to Login Items
Section titled “Add to Login Items”- Open System Settings → General → Login Items & Extensions.
- Under Open at Login, click the + button.
- Navigate to your
startup-completed.commandfile and add it. You can also just drag and drop your.commandfile into the startup items window if you want.
Now every time this Mac logs in, it will send that OSC message to your server. Handy for knowing when all your machines are up and ready before a show.
#!/bin/bash
# wait a bit for the network to come upsleep 10
# send a custom event to the sndwrks serverpython ~/scripts/send_osc.py 10.0.10.100 52000 /sndwrks/server/v1/event/custom "Mac Online" "Booth Mac finished booting"osascript -e 'tell application "Terminal" to close front window' &