Control Video Playback from Max/MSP over OSC
Max/MSP is often the interaction brain of an installation — reading sensors, running the logic, deciding what should happen. When that logic needs to put a pre-rendered video on a separate screen, Max should not have to decode it inside Jitter. This guide uses Max as the controller and DearScenario Player as the remote player, connected over OSC.
Why offload playback from Jitter?
Max can play video with jit.movie, but that ties decoding and output to the patch’s machine and its CPU/GPU budget. In installation work you often want:
- The Max logic on one machine, the playback display on another
- Several remote screens driven from one patch
- Pre-rendered video at full quality without competing with real-time DSP or Jitter processing
- Freedom to edit and reload the patch without interrupting what is on the screens
DearScenario Player handles the video on the remote machine. Max tells it what to do with a few OSC messages.
Setup
- Install and launch DearScenario Player on the playback machine (see HTTP node setup guide)
- Put both machines on the same network
- In
config.json, setnetwork.enable_osctotrueand restart the player. OSC uses UDP port18290.
Sending OSC with udpsend
Max’s built-in udpsend object speaks OSC natively: any message that begins with a / address is packed and sent as an OSC message. Point one at the node:
[udpsend 192.168.1.100 18290]Then feed it message boxes. Discrete cues — the things that happen at a moment:
[/player/play_media C:/media/scene_a.mp4 0. 0]
[/player/pause]Connect each message box to udpsend and bang it (from a sensor threshold, a metro, a key, a UI button). Use $1 to substitute a live value into a message:
[/player/volume $1] ← float in
[/player/seek_sec $1] ← seconds in
[/player/loop $1] ← 1 or 0Continuous control
Max is number- and signal-native, so streaming a live value into the player is natural — the same strength TouchDesigner has. Map any control source to a parameter and send it continuously:
[sensor / line / snapshot~] → [scale 0. 1.] → [/player/volume $1] → [udpsend]Two things to keep it healthy:
- Throttle the rate. Put a
speedlim 33orqlimbefore the message box so you send around 30 updates per second, not one per scheduler tick. The node does not need more, and you avoid flooding the network - Send on change. A
changeobject drops repeats so you only transmit when the value actually moves
Watch the path formatting
Max splits a message on spaces, so a file path is the one place to be careful:
- Use forward slashes —
C:/media/scene_a.mp4works on the Windows playback machine and avoids backslash escaping - Avoid spaces in paths where you can. If a path must contain spaces, build the message with
sprintf/combineand asymoutso it stays a single OSC argument instead of several - The path refers to a file on the DearScenario Player machine, not on the Max machine — copy media to the playback box in advance
OSC address reference
DearScenario Player listens for OSC on port 18290. The addresses you will use most from Max:
| OSC Address | Type | Action |
|---|---|---|
/player/play_media | s, sfi, or sii | Load and play (source; optional cue sec and loop) |
/player/prepare | s, sfi, or sii | Load and leave ready/paused |
/player/play | — | Start or resume playback |
/player/pause | — | Pause playback |
/player/cue | — | Return to cue point while keeping media loaded |
/player/stop | — | Stop and remove media |
/player/seek_sec | float or int | Seek to time in seconds |
/player/volume | float or int | Set volume (float 0–1; int 0 or 1) |
/player/mute | int | Mute (1) or unmute (0) |
/player/loop | int | Enable (1) or disable (0) looping |
Common patterns
- Sensor trigger: A threshold fires
/player/play_mediawith source and cue arguments - Continuous map: An envelope drives
/player/volumeor/player/seek_secthrough a throttled stream - Timeline: A
metro+countersteps through/player/play_mediacommands to sequence content - Multi-node: One
udpsendper node IP; bang the same message into several to switch many screens together
Reliability: OSC is fire-and-forget
OSC has no success acknowledgement. Later absolute-value updates can replace a dropped volume or seek message. For cues that must reach a verified playback state before the show continues, use HTTP status observation:
- Immediate
/player/errorreplies go to the sender’s UDP source port. A receiver must share that source port/socket arrangement to see them; they do not report later media-loading or playback failures. - For validation and queue-admission feedback, send the command over HTTP with
maxurl(POST to/api/command).{"ok": true}does not confirm successful loading or playback. If a cue depends on media being ready or playing, also inspectstate,source, anderrorthroughGET /api/status— see the HTTP guide
A common split: OSC for everything continuous and for low-stakes triggers, HTTP plus status observation for cues that require verified playback state.
Where DearScenario Player fits
DearScenario Player is a playback API node: headless on a Windows PC or Raspberry Pi, with the same command model over HTTP and OSC, and no CMS or creative engine of its own. Max holds the logic and the live data; DearScenario Player turns it into video on a remote screen. OSC over udpsend is the shortest path between the two.
Next step: If you also drive screens from a visual environment, see TouchDesigner over OSC, or put a low-cost Raspberry Pi node behind each display.

