XY OSC Control @ vrch.ai
XY OSC Control explained
- X_INT
- Y_INT
- X_FLOAT
- Y_FLOAT
- X_RAW
- Y_RAW
Open Sound Control (OSC) is the musician's UDP-based protocol for throwing faders and XY pads around a network, and this node is how your ComfyUI workflow joins that party. XY OSC Control @ vrch.ai listens for OSC messages and turns them into numbers you wire straight into your graph - drag a virtual fader on your phone in TouchOSC and watch it become your cfg, your seed, your denoise strength.
This node is the pack's input side, the sibling of its keyboard and gamepad controls. It's the same shape of idea, just for people who already live in the OSC world. If you've never touched OSC, don't write it off: the pack ships a ready-made TouchOSC panel (comfyui_osc_control.tosc), so the whole OSC side of the pack actually started when vrch.ai's t_hou built it to drive ComfyUI from inside an Apple Vision Pro back in late 2024. The demo is still the clearest picture of what this node is for - near-real-time parameter control from an arbitrary device, no browser plugin, no polling.
How it works
The node binds a UDP listener on server_ip + port (default 8000) and watches a specific OSC path (default /xy). It accepts a message to /xy carrying two float arguments, or separate /xy/x and /xy/y messages with one argument each. Each incoming value gets remapped from the input range (default 0.0–1.0) to the output range (default 0–100), optionally inverted, and if no data has arrived yet the node falls back to the output_default value (50). That remap is the whole trick - you don't want your phone's 0-to-1 fader stuck on a KSampler that wants 1–60 steps.
The inputs and outputs that matter
For a beginner, three things to set and then leave the rest alone:
server_ipandport- where the node listens. The defaultserver_ipis172.17.0.2, which is a Docker bridge address baked in from the author's dev environment; it's only right if your setup resolves to the same thing. For phone control set your machine's LAN IP;127.0.0.1is fine when the OSC client is the same computer.path- must match what your OSC client sends. Default/xy; change it if you've got several control nodes on one port.- The remap fields - input min/max, output min/max, invert, default, per axis. Defaults are sane; the one you'll actually adjust is
x_output_max/y_output_maxto match the parameter you're driving.
Outputs come in threes per axis: X_INT / Y_INT (remapped integers - wire these into INT inputs like seed, cfg, or steps), X_FLOAT / Y_FLOAT (remapped floats, for things like denoise), and X_RAW / Y_RAW (the untouched values as received, handy for checking what your fader is actually sending). The standard pattern is to wire the int outputs into a sampler's inputs and re-run; for live performance you pair it with the pack's instant-queue/auto-run workflows so the graph keeps executing with fresh values.
How to install it
Nothing special for OSC. In ComfyUI Manager search "ComfyUI Web Viewer", or:
cd ComfyUI/custom_nodes
git clone https://github.com/VrchStudio/comfyui-web-viewer
cd comfyui-web-viewer
pip install -r requirements.txt
(Windows portable: python_embeded\python.exe -m pip install -r ComfyUI\custom_nodes\comfyui-web-viewer\requirements.txt.) Restart, and you're done - no models, no extra Python packages beyond the pack's own requirements.
Common issues
OSC over UDP is fire-and-forget: there's no handshake, so when nothing happens you get zero error messages, just silence. Work the checklist: phone and computer on the same network; server_ip is the machine's LAN IP (not the Docker default); path matches exactly on both sides; port matches; and if you're on Windows, the firewall isn't silently dropping inbound UDP. Flip debug on and the node prints incoming messages to the console - if you see the raw values but the output isn't what you expect, the remap ranges are the culprit. And remember there's one listener per ip:port, so a second control node needs a different port or path, not a copy of the same one.
If you already run OSC gear, this is the cheapest physical control surface you'll ever attach to ComfyUI. If you don't, the XY pad is still the one worth learning on - it's the simplest member of the family, and it's the one you'll reach for when you want to stop typing numbers and start grabbing them.
Inputs (16)
| Name | Type | Default | Description |
|---|---|---|---|
| server_ip | STRING | 172.17.0.2 | — |
| port | INT | 8000 | — |
| path | STRING | /xy | — |
| x_input_min | FLOAT | 0.00-9999–9999 | — |
| x_input_max | FLOAT | 1.00-9999–9999 | — |
| x_output_min | INT | 0-9999–9999 | — |
| x_output_max | INT | 100-9999–9999 | — |
| x_output_invert | BOOLEAN | false | — |
| x_output_default | INT | 50-9999–9999 | — |
| y_input_min | FLOAT | 0.00-9999–9999 | — |
| y_input_max | FLOAT | 1.00-9999–9999 | — |
| y_output_min | INT | 0-9999–9999 | — |
| y_output_max | INT | 100-9999–9999 | — |
| y_output_invert | BOOLEAN | false | — |
| y_output_default | INT | 50-9999–9999 | — |
| debug | BOOLEAN | false | — |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| X_INT | INT | — |
| Y_INT | INT | — |
| X_FLOAT | FLOAT | — |
| Y_FLOAT | FLOAT | — |
| X_RAW | FLOAT | — |
| Y_RAW | FLOAT | — |