Skip to content

External Show Control — IN/OUT Commands ​

This guide explains how to connect Exaplay 3 to an external show control system (ETC Eos lighting console, Medialon, QLab, Crestron, Q-SYS, CueLab, Alcorn McBride, a custom PLC, or any other device that can send network commands). It covers every supported protocol, with tested command examples and a troubleshooting checklist for each direction.

Ready-made examples: Independently versioned starting points for Crestron, Q-SYS (plugin + Lua), AMX, QLab/CueLab, ETC Eos, Bitfocus Companion (a module for Stream Deck control, with live status on the keys), Extron Global Scripter, Medialon, Alcorn McBride, Node-RED, TouchDesigner, Home Assistant and generic TCP/OSC clients are installed with Exaplay in its integrations folder (by default C:\Program Files\Exaplay 3\integrations, also in the Start menu as Show-control integrations) — or download them in any browser that can open Exaplay under Control → Integrations. Each one states whether it was validated in vendor tooling or is illustrative source: the Q-SYS plugin's Lua, the Crestron modules' SIMPL# library (built with Crestron's SDK), the Companion module and the Extron, Node-RED, TouchDesigner and Home Assistant templates carry automated tests of their own logic, and none of them has been run against a live engine on the vendor's own hardware. Treat them as a head start, not as certified drivers. For a step-by-step guide by system — Stream Deck, Home Assistant, smart plugs, your own panel — see Connecting External Systems.

Show Control


Part 1 — Commands INTO Exaplay (Incoming) ​

1A — HTTP Control (most flexible) ​

Any device that can send an HTTP POST request can control Exaplay.

Fire a cue by name:

bash
curl -X POST http://192.168.1.5:8123/cue/trigger \
  -H "Content-Type: application/json" \
  -d '{"name": "Scene 1 - Opening"}'

Scoping to one composition: without a scope, /cue/trigger fires the first matching cue across all compositions in project order. If several Timelines share a cue name (e.g. every act has a "Blackout" cue), add "comp": "comp_act2" (or comp-uid) to disambiguate.

The same "trigger cue X in composition Y" action looks different on each protocol — the cue argument always accepts either the index or the cue name:

Protocol"cue 5 in comp_act2""cue Blackout in comp_act2"
TCP / UDP dotted (primary)comp_act2.cue.go=5comp_act2.cue.go=Blackout
TCP / UDP classicset:cue,comp_act2,5set:cue,comp_act2,Blackout
HTTPPOST /project · {"req":"cue.go","comp-uid":<uid>,"cue":5}{"req":"cue.go","comp-uid":<uid>,"name":"Blackout"}
OSC/exaplay/comp_act2/cue 5/exaplay/comp_act2/cue "Blackout"

Play a composition by name (shortcut — no UID lookup required):

bash
curl -X POST http://192.168.1.5:8123/composition/play \
  -H "Content-Type: application/json" \
  -d '{"name":"Main Show"}'

Transport control (play/pause/stop/seek by UID) and Playlist navigation go through POST /project with the matching req; setting a property value (e.g. layer opacity) is POST /data with "type":"exaObj". Full endpoint list, request/response bodies, and error responses: HTTP REST API.

Stop all playback:

bash
curl -X POST http://192.168.1.5:8123/stop

Tip: To find the correct path for any property, open it in the Inspector, hover over the 🔗 link icon beside it, and read its Path in the tooltip.


1B — OSC (Open Sound Control) ​

OSC is supported by virtually every professional show control system.

Exaplay OSC listen port: 8000 (default). OSC receive is always active — there is nothing to enable; the port is changed under Menu → Settings → Communication → OSC Listen.

The address pattern is /<prefix>/<composition>/<command> — the prefix defaults to exaplay and <composition> is either the composition's ID (its variable name, e.g. comp1) or its name (case-insensitive; use _ in place of spaces, e.g. Main_Screen for "Main Screen"). If a reference matches both, the ID wins.

OSC AddressArgumentsAction
/exaplay/<comp>/play(none)Start the named composition
/exaplay/<comp>/start(none)Start the named composition (alias for play)
/exaplay/<comp>/pause(none)Pause the named composition
/exaplay/<comp>/stop(none)Stop the named composition
/exaplay/<comp>/cuei (index) or s (name)Fire a cue by index or name in a Timeline or Playlist
/exaplay/<timeline>/framei (frame)Timeline: jump to that frame (at the Timecode frame rate)
/exaplay/global/start(none)Start all compositions (play all)
/exaplay/global/stop(none)Stop all compositions (stop all)
/exaplay/global/showmodes (on/off/toggle) or i/f (1/0)Set global Show Mode
/exaplay/global/videomutes (on/off/toggle) or i/f (1/0), optional second f (fade seconds)Blank every output to black (and back), over the blank fade time. A second argument also becomes the blank fade time
/exaplay/global/blankfadef or i (seconds, 0–60)Set the blank fade time without blanking
/exaplay/global/identifys (on/off/toggle) or i/f (1/0)Label every output window on the wall (Identify)
/exaplay/global/showguidess (on/off/toggle) or i/f (1/0)Outline every screen and field on the wall (Outlines)
/exaplay/global/audiomutes (on/off/toggle) or i/f (1/0)Mute the show's audio (on a multi-client master: every machine)
/exaplay/global/correctionbypasss (on/off/toggle) or i/f (1/0)Raw wall: the outputs without their calibration (on a multi-client master: every machine)
/exaplay/global/failovers (promote/arm/disarm)Main/Backup failover — send it to the backup machine. See Main / Backup Failover
/exaplay/global/restart(none) or s (project/clean)Restart exaplay (reload current project, or clean for empty)
/exaplay/track/<channel>x [y] (numbers)Feed an Inputs channel
/timecode (configurable)f, i, or s (HH:MM:SS:FF)Drive timecode-slaved compositions

Note: to fire a cue by name without naming a composition (searched across all compositions), use the HTTP endpoint POST /cue/trigger instead.

No seek over OSC: cuetime is the internal master→client sync channel, not a seek — a standalone or master engine ignores it. Seek with TCP/UDP comp1.set:time=12.5 or HTTP; on a Timeline, /exaplay/comp1/frame <n> jumps to a frame.

No property writes over OSC: OSC has no set: verb. To drive a value from OSC, send /exaplay/track/<channel> and map that channel in Inputs. The on/off verbs also take the word in the address: /exaplay/global/showmode/on.

Full address list, argument types and what Exaplay sends: OSC Reference.

What a complete OSC command looks like — every message is one UDP packet to <engine-ip>:8000 containing the OSC address and its arguments (usually none or one; videomute takes an optional second). With the default prefix exaplay, a composition comp1 named "Main Show" and a Playlist comp2 named "Lobby":

/exaplay/comp1/play                  # start comp1 (no argument)
/exaplay/Main_Show/play              # the same, addressed by name ("Main Show")
/exaplay/comp1/start                 # start comp1 (alias for play)
/exaplay/comp1/pause                 # pause comp1
/exaplay/comp1/stop                  # stop comp1
/exaplay/comp1/cue 5                 # trigger cue index 5 in comp1 (int argument)
/exaplay/comp1/cue "Blackout"        # trigger the cue named Blackout in comp1
/exaplay/Lobby/cue 2                 # play Playlist item 2 (1-based position)
/exaplay/Lobby/cue "Act 1"           # play the Playlist item named "Act 1"
/exaplay/comp1/frame 750             # Timeline comp1: jump to frame 750
/exaplay/global/start                # global command: start ALL compositions
/exaplay/global/stop                 # global command: stop ALL compositions
/exaplay/global/showmode "on"        # global command: Show Mode on
/exaplay/global/restart "clean"      # global command: restart with empty project

To control a different composition, only the second address segment changes — e.g. /exaplay/comp2/play starts comp2. The composition's Inspector shows a ready-to-copy address in its Show Control section (the inline ID field holds the number part of the id: ID 11 → comp11); the TCP/UDP command get:complist lists every composition's id and name.

Index semantics for /cue: on a Timeline the argument is the cue's variable index; on a Playlist it is the 1-based list position — both identical to TCP/UDP set:cue and HTTP cue.go. A string argument is matched against the cue/item name within that composition. (Backward compatibility: Playlist /cue historically matched the item's internal variable index; when a numeric argument doesn't resolve to a position, the engine falls back to that legacy match, so old integrations keep working.)

Example — ETC Eos console firing cue 3 in comp1:

In the Eos Macro editor, add a Network command:

/exaplay/comp1/cue 3
  UDP to 192.168.1.5:8000

Example — Qlab sending OSC:

  1. In Qlab, add a Network cue.
  2. Set Type to OSC message.
  3. Set destination to 192.168.1.5:8000.
  4. Set message: /exaplay/comp1/play (or by name: /exaplay/Main_Show/play).

Example — Show Mode ON/OFF via OSC:

/exaplay/global/showmode "on"
/exaplay/global/showmode "off"
/exaplay/global/showmode "toggle"

Example — Blank (fade to black) via OSC:

/exaplay/global/videomute "on"        # fade every output to black
/exaplay/global/videomute "off"       # fade back up
/exaplay/global/videomute "on" 3.0    # …over 3 seconds — this also sets the blank fade time to 3 s for later blanks
/exaplay/global/blankfade 3.0         # set the fade time for later blanks

Blank dims the picture while the output windows stay where they are, over the blank fade time, which the slim caret (▾) beside the BLANK button in the header picks: Cut (no fade), 2 s, 5 s or 10 s, or type any other time under Custom. A fade time sent with videomute replaces that time the same way, so later blanks — the BLANK button included — use it too. Show Mode is the other switch: it puts the output windows up or takes them down, with no fade. On a multi-client rig the master mirrors both the blank and its fade time to every client, so the whole wall fades as one.

Example — Identify via OSC:

/exaplay/global/identify "on"
/exaplay/global/identify "off"
/exaplay/global/identify "toggle"

Identify draws a labelled frame on every output window — the output's name, the machine rendering it, the resolution, and the assigned calibration channel if it has one — so you can see which physical projector or screen is which. It is the same button as Identify in the Stage tab.

On a multiclient rig it is a property of the whole rig: send it to the master and every paired client labels its own outputs too. Sending it to a client directly labels only that machine. Identify draws over live content, so turn it off before going on air.

Example — Outlines via OSC:

/exaplay/global/showguides "on"
/exaplay/global/showguides "off"
/exaplay/global/showguides "toggle"

Outlines is Identify one level up: every screen draws its own box on the wall with its name, and every field on that screen draws its box and name inside it — Identify says which projector you are looking at, Outlines says which rectangle of the picture. It is the same button as Outlines in the Stage tab, and it follows the same rig rule: sent to the master, every paired client outlines the screens it renders. It draws over live content too, so turn it off before going on air.

Example — Restart exaplay via OSC:

/exaplay/global/restart              # restart and reload the current project
/exaplay/global/restart "project"    # same as above (explicit)
/exaplay/global/restart "clean"      # restart with no project loaded

1C — Art-Net / sACN DMX input (console → Exaplay) ​

A lighting desk can drive Exaplay directly over Art-Net or sACN (E1.31) DMX: patch Exaplay as a 12-channel fixture and the desk's buttons and faders play, stop, cue and seek the show.

  1. Open Menu → Settings → Communication, switch Art-Net Input (UDP 6454) and/or sACN (E1.31) Input (UDP 5568, multicast joined per mapped universe) on.
  2. Open Control → Inputs → Lighting desk (DMX) → Edit mappings…, press Patch Exaplay Control fixture…, pick the protocol, universe, start address and composition.
  3. Patch the same 12-channel fixture on the console at that address — channels 1–8 are Play, Pause, Stop, Next, Previous, Cue Go, Cue Selection and Show Mode, 9/10 a 16-bit Seek, 11/12 a 16-bit numeric property.

Individual rows can be added and learned from the console as well. See Art-Net DMX input for every mode and action.

ArtNet timecode (OpTimeCode) is a different thing: to chase a running timecode set Settings → Timecode → Timecode Mode to Receive Art-Net timecode — or use OSC, LTC, or MTC (see Timecode Sync).


1D — LTC (Linear Timecode via Audio) ​

  1. Connect the LTC output from your console to an audio input on the Exaplay ASIO interface.
  2. Open Menu → Settings → Timecode and set Timecode Mode to Receive LTC, Linear Timecode.
  3. Pick the Input Channel and set the frame rate to match the console (details: Receive: LTC).
  4. Open Control → Monitor → Timecode: the IN card shows receiving and locked when the signal is detected.

1E — TCP Text Protocol ​

Exaplay accepts persistent TCP connections carrying dotted-path commands (comp1.play) or the classic comma form (play,comp1). This is ideal for Medialon, Alcorn McBride, Crestron/AMX, and any custom PLC that works natively with raw TCP sockets.

Default port: 8100 (configure in Menu → Settings → Communication → TCP Listen)

→ get:complist
← comp1,Main Show
← END

→ comp1.play
← OK

→ Main Show.play
← OK                        # the composition's name works in place of the id

→ comp1.cue.go=5            # classic: set:cue,comp1,5
← OK

Every command is a single line terminated by \r, \n or \r\n, answered with one response line (OK, a value, or ERR,<reason>) — except while a project is loading, when commands are dropped without a reply, so a controller should read with a timeout. Full command reference — dotted vs. comma syntax, transport, cue triggering, Playlist navigation, volume/alpha/loop, status queries, global commands, and error codes: TCP Command API.

The same text commands also work as fire-and-forget UDP datagrams on port 8200 (Menu → Settings → Communication → UDP Listen, on by default). See the UDP Command API for details.


Part 2 — Commands OUT of Exaplay (Outgoing) ​

2A — OSC Output ​

Exaplay can transmit its current playback position and custom events to any OSC listener.

Configure OSC output:

  1. Open Menu → Settings → Communication and add the destination to OSC Clients (one host:port per line, e.g. 192.168.1.20:9000).
  2. In Menu → Settings → Timecode, set Timecode Mode to Master: send timecode, pick the Master Composition, switch on OSC Timecode Out and set its OSC Address (default /timecode).

Every tick, Exaplay sends a bundle to that address carrying the master composition time in seconds (float32), the frame rate (int32) and the timecode as an HH:MM:SS:FF string — to every host in OSC Clients. Details: OSC Output.

Custom OSC via Data Tracks:

Any Data Track can output to an OSC address. While the composition plays it streams the curve's current value (a float) to that address continuously, up to Rate (Hz) times a second (default 120):

Data Track "LightingMaster"
  Format:   OSC
  Address:  192.168.1.20
  Port:     8000
  OSC Path: /eos/fader/1/value

  Keyframes: fade from 0 to 1.0 over 5 seconds

2B — ArtNet DMX Output ​

Exaplay can drive lighting fixtures, dimmers, and LED controllers directly over Art-Net, independent of any lighting console. This is useful for installations where Exaplay is the only show control system.

See ArtNet & DMX Output for the full guide.


2C — UDP Output ​

Any Data Track can output raw UDP datagrams to any device that accepts them:

Data Track "MotionRig"
  Format:   UDP
  Address:  192.168.1.30
  Port:     9500

The current interpolated value is sent as a 4-byte big-endian float, continuously while the composition plays (up to Rate (Hz) times a second, default 120).


2D — Drive Exaplay's own values from a Data Track ​

The same curve can target Exaplay itself — the properties the Inspector edits and the dotted set: command addresses — so a timeline moves a clip, rides a volume or sweeps a generative source's parameter without any external controller:

Data Track "PanAcross"
  Format: Exaplay value
  Target: comp1.media3.mapping.x
  Out Min / Out Max: 0 / 1920

  Keyframes: ramp from 0 to 1 over 5 seconds
  → the clip travels from the left edge to the right edge of a Full HD screen

Data Track "DuckMusic"
  Format: Exaplay value
  Target: comp1.audio.volume
  Out Min / Out Max: 0 / 100

  Keyframes: 1 → 0.2 over 1 second while the announcement plays, back to 1 after

The Target field completes the dotted path as you type it, and the ⚡ wizard picks it from the project tree: click the clip, and the values an operator drives are listed by name — opacity, volume, position, size, rotation, visibility, and the generative parameters that clip runs. Out Min / Out Max are filled in with the value's own range, so a volume is 0–100 without you typing it and Position X on a 1664×832 wall is 0–1664 rather than 0–1. Anything else the object carries is typed instead of picked. Scaling can also be a plain Factor (value × factor + offset) or As drawn. An on/off property (a clip's show) switches at the middle of the curve's range. When the composition stops, the property is back at the value it had before the curve touched it (Restore on stop). See Data Tracks — Driving Exaplay's own values.


2E — Named routes: $Variables instead of an IP in every cue ​

A cue's OSC/TCP/UDP/ArtNet line and a Data Track's Address field all take a $Name in place of the address. The name is resolved when the command is sent, so re-addressing a lighting desk is one edit, not one edit per cue.

Define the routes. Three places, searched from the inside out — the first one that defines a name wins:

WhereScopeTravels with
Composition Inspector → Variablesthat compositionthe show
Project properties (the ⌂ home icon at the top of the Inspector) → Variablesthe whole showthe show
Menu → Settings → System → Global Variablesthis machinethe machine

One definition per line, # or // start a comment. A comment must be on its own line — text after a value is part of the value:

Console   = 10.10.10.10:8000
MediaRack = 192.168.1.30:9500

The spacing you type around the = is not part of the value; a trailing space is (a variable standing for a device command may end in one).

Use them. Anywhere a cue script takes an address, and in a Data Track's Address field:

OSC>$Console,/cue/5/go,i:1
TCP>$MediaRack,PLAY 3\r

Everything after the comma in a TCP>/UDP> line is sent byte for byte — TCP>$MediaRack, PLAY 3\r sends a leading space. Full line syntax: Cue Script Reference.

A variable can also stand for part of a longer string — write ${Name} when it is not the whole field:

OSC>$Console,/cue/${ActNumber}/go

Carrying the show to another venue: ?=. A plain = in the project wins over the machine's Global Variables, which is what you want while the routes belong to the show. Write ?= instead and the definition becomes a default: the show still runs on its own, and any machine that defines the same name in Global Variables overrides it — no edit to the show file.

# in the project's Variables
# our own desk
Console ?= 10.10.10.10:8000

# in the venue's Global Variables — this machine wins
Console  = 172.16.4.9:8000

A route that resolves to nothing is never half-sent. The engine refuses the send, writes the missing name to the log, and shows it in the Monitor as an ERROR row (a Data Track says the same in its Status field). Before a show, Menu → Check Project lists every $Name a cue or Data Track uses that this machine does not define — which is exactly the state a show authored elsewhere arrives in.

In a TCP/UDP message body, a leading $ is your device's text, not a variable. Protocols that open with one (NMEA sentences, some desks) are sent exactly as before and are never refused; only the explicit ${Name} form is read as a reference there. Addresses have no such ambiguity and are always checked.

In the OSC Clients list, only Global Variables. A line there may be a $Name, resolved against System → Global Variables only (not project or composition Variables). A line that does not resolve is skipped without a Monitor error. For ARTNET> the variable must hold the IP only — the port is always 6454.


2F — Set a value from a cue, without knowing the syntax ​

A cue script can set any property Exaplay has — the same set: line the TCP API uses:

comp1.set:audio.volume=80              a composition's volume
comp1.track1.media1.set:image.alpha=50 a clip at half opacity
comp1.media3.set:mapping.x=50%         a clip at the middle of its field

You do not have to type it. In the cue's script box (under Action) press ⚡ Wizard → Browse, click the composition or the clip in the tree, and pick Set a value…:

  • Value lists what an operator drives, by name and with its current value: Opacity, Volume, Position X / Y, Size W / H, Rotation, Visible — plus every parameter of the generative source that clip runs. The list describes the object you clicked, so a composition offers its own opacity and volume and no position.
  • Set to takes the value, with the range under the field: 0–100 % for an opacity, 0–1664 px for a position on a 1664×832 wall (read from the clip's own field or screen — not a guess). Position and size can be given in px or %; the percent is measured against the same surface.
  • Other value takes anything else this object carries — a colour correction, a crop corner, an EQ band — as its own set: path.

The preview shows the finished line, and Apply puts it in the cue. The same line also works verbatim over the external TCP or UDP port, so a cue you built here can be copied into a lighting desk or a show controller.


Call a REST device or a webhook from a cue (HTTP>) ​

Smart plugs, projectors and cameras with a web API, Node-RED and Home Assistant are switched with one HTTP> line in a cue script or a command button:

HTTP>GET http://10.0.0.30/relay/0?turn=on                                  a Shelly plug on
HTTP>POST http://homeassistant.local:8123/api/webhook/show-start,{"scene":"act2"}
HTTP>POST http://${NodeRed}/show,start act 2

The body follows the first comma after the address; a body starting with { or [ goes out as JSON. Put the device in a named route (NodeRed = 10.0.0.12:1880) and the cue keeps working when the venue's address changes. The Monitor shows each call with the device's status code — an ERROR row says why a call failed (no connection, a timeout, HTTP 401). A user name or password in the address is refused. Full syntax: Cue Script Reference › HTTP.


Part 3 — Verifying Communication with the Monitor ​

The Monitor is the single most important tool for diagnosing show control integration issues.

How to Use the Monitor ​

  1. Open Control → Monitor.
  2. Trigger a command from the external system.
  3. Check Network Traffic for an entry.

What Good Looks Like ​

ProtocolNetwork Traffic entry
HTTP triggerPOST /cue/trigger name=Scene 1 -> 200 (sender 192.168.1.20)
OSC receivedOSC /exaplay/comp_main/play (address plus an argument preview; no sender)
ArtNet DMX sent by a cueCue → ArtNet Universe 0 Channel 1 = 255 (target 192.168.1.50:6454)
OSC sent by a Data TrackDataTrack [datatrack1] → /eos/fader/1/value = 0.750000 (target 192.168.1.20:8000)

If an expected entry is missing, the packet never reached Exaplay — see Part 4.


Part 4 — Troubleshooting ​

No incoming commands received ​

CheckWhat to do
IP addressOpen the Monitor → Listeners card, HTTP row → confirm the correct IP address
PortConfirm the sending device is targeting the correct port (REST: 8123, OSC: 8000, TCP: 8100, UDP: 8200)
FirewallAllow inbound UDP 8000, 8200 and TCP 8123, 8100 in Windows Defender Firewall
SubnetBoth devices must be on the same subnet (e.g. 192.168.1.x / 255.255.255.0)
OSC addressThe prefix is case-insensitive (/Exaplay/… works), but verbs and composition IDs are not — /exaplay/comp_main/Play does nothing. Composition names are case-insensitive, with _ for a space

Windows Firewall — allow Exaplay ports:

batch
netsh advfirewall firewall add rule name="Exaplay HTTP" dir=in action=allow protocol=TCP localport=8123
netsh advfirewall firewall add rule name="Exaplay TCP Control" dir=in action=allow protocol=TCP localport=8100
netsh advfirewall firewall add rule name="Exaplay OSC" dir=in action=allow protocol=UDP localport=8000
netsh advfirewall firewall add rule name="Exaplay UDP Control" dir=in action=allow protocol=UDP localport=8200

ArtNet timecode not locking ​

Timecode Mode must be Receive Art-Net timecode (Settings → Timecode, then Apply & Restart Timecode) — in any other mode incoming Art-Net TC is shown as status only. Check the console sends OpTimeCode to this machine (broadcast or unicast) on the Art-Net port (UDP 6454, Windows Firewall inbound), that the composition is in a timecode slave mode, and Monitor for artnet:timecode events. Art-Net DMX input (a console pressing Play) is a separate switch — see 1C above.

ArtNet DMX input does nothing ​

The DMX mappings dialog (Control → Inputs → Lighting desk (DMX) → Edit mappings…) shows the listener's own status line: no DMX yet means no packet reached the port (subnet, broadcast/unicast target, firewall on UDP 6454, zero-based universe); port could not be opened means another Art-Net node owns the port on this machine; this machine is a CLIENT means the console is patched to a client — patch the master. A row whose Live value moves but whose action never runs has no target composition.


OSC going out but console not receiving ​

CheckWhat to do
Destination IPConfirm the console's IP in Menu → Settings → Communication → OSC Clients
Destination portConfirm the console's OSC receive port matches the configured destination port
Console OSC enabledMany consoles require OSC receive to be explicitly enabled
Firewall on the console machineEnsure the console's firewall allows incoming UDP on the OSC port
Monitor → Network TrafficOutgoing OSC messages should appear in the log — confirm they are being sent

HTTP control returns 404 or connection refused ​

CheckWhat to do
Engine runningThe engine (not just the UI) must be running — check the tray icon
PortHTTP control uses port 8123 — ensure no other app is using this port
Endpoint pathCheck the exact endpoint path (case-sensitive); verify the property path in the Inspector if needed
JSON formatRequest body must be valid JSON (send it with a Content-Type: application/json header; the engine reads the body as JSON either way)

Part 5 — Quick Reference ​

Incoming commands summary ​

ProtocolPortEnable in
REST HTTP8123 (TCP)Always on
OSC8000 (UDP)Always on — port set in Settings → Communication → OSC Listen
LTCAudio input channelSettings → Timecode (mode Receive LTC, Linear Timecode)
TCP Text Protocol8100 (TCP)Settings → Communication → TCP Listen
UDP Text Protocol8200 (UDP)On by default — Settings → Communication → UDP Listen
ArtNet DMX in6454 (UDP)Settings → Communication → Art-Net Input
sACN DMX in5568 (UDP)Settings → Communication → sACN (E1.31) Input
ArtNet timecode in6454 (UDP)Settings → Timecode → Receive Art-Net timecode
WebSocket events8123 (WS)Always on (same port as HTTP)

Outgoing commands summary ​

ProtocolPortEnable in
OSC outputConfigurable UDPSettings → Communication → OSC Clients
ArtNet DMX out6454 (UDP)Data Track → Format: ArtNet
UDP rawConfigurableData Track → Format: UDP
HTTP / REST callFrom the URL (80 / 443 by default)Cue script → HTTP>METHOD url[,body]

Part 6 — Integration Examples by System ​

ETC Eos / Ion ​

  1. Exaplay listens for OSC on port 8000 by default — nothing to enable.
  2. In Eos, create a Macro with a Network cue: OSC /exaplay/comp1/cue 1 → target 192.168.1.5:8000. A cue name works as the argument too: /exaplay/comp1/cue "My Cue". To search every composition for a name, send an HTTP POST to http://192.168.1.5:8123/cue/trigger with body {"name":"My Cue"} instead.
  3. For bidirectional: configure Eos OSC Tx to send timecode, and Exaplay OSC Rx to receive it.

Qlab (Mac) ​

  1. Add a Network cue in Qlab.
  2. Select OSC or HTTP based on preference.
  3. For OSC: target 192.168.1.5:8000, address /exaplay/comp1/play (or /exaplay/comp1/cue with a cue number or name to fire a specific cue).
  4. For HTTP (fires a cue by name across all compositions): target http://192.168.1.5:8123/cue/trigger, method POST, body {"name":"My Cue"}.

Q-SYS (QSC) ​

Use the Exaplay plugin: copy integrations\qsys\exaplay.qplug from the Exaplay folder (or download it under Control → Integrations on the Q-SYS Designer PC) into Documents\QSC\Q-SYS Designer\Plugins\, restart Q-SYS Designer and place Exaplay → Exaplay 3 Media Server in the schematic. In the block's properties set Engine IP Address and TCP Port (8100 unless you changed TCP Listen) and, under Compositions, how many composition strips you want. The plugin fills its composition pickers from the engine, and offers transport, cues by number or name, volume, Show Mode, PJLink and a command console. Without the plugin, a Lua TcpSocket to port 8100 works too — see TCP Command API → Q-SYS.

To check the connection, open Control → Monitor: the Listeners card shows the address and port the Core must reach, Send a test command (TCP) sends the same line the plugin's Play button sends before any Core is online, and Network Traffic shows every command from the Core with Exaplay's reply.

Walkthrough

☰ menu → Walkthroughs → Inputs & show control → Q-SYS drives the show

Medialon / Alcorn McBride, Crestron / AMX, CueLab ​

All of these connect over the same TCP Text Protocol (some also support REST HTTP or OSC as an alternative) described in 1E above — a persistent socket to port 8100 sending commands like comp1.play\r (or by name: Main Show.play\r; the classic play,comp1\r works too). Ready-to-use client code (SIMPL+/SIMPL# for Crestron/AMX, TCP Device config for Medialon/Alcorn, OSC/REST setup for CueLab) and the full command table live in one place: TCP Command API → Connecting from Common Show Control Systems.

CueLab can additionally receive Exaplay's timecode back over OSC, for bidirectional sync:

  1. In Exaplay, open Menu → Settings → Communication → OSC Clients.
  2. Set destination to <CueLab machine IP>:<CueLab OSC Rx port> (check CueLab Settings → Network → OSC Input).
  3. With Timecode Mode = Master: send timecode, Exaplay sends an OSC bundle to /timecode (the address is configurable) on every tick, carrying three arguments: float32 seconds, int32 framerate, and the HH:MM:SS:FF string — CueLab can use this to auto-follow Exaplay's timeline. See Timecode Sync.

Summary Checklist ​

  • [ ] Engine IP address confirmed (Monitor → Listeners, HTTP row)
  • [ ] Firewall rules added for ports 8123 (TCP), 8100 (TCP), 8000 (UDP) and 8200 (UDP)
  • [ ] OSC listen port confirmed (default 8000, always on)
  • [ ] OSC Clients configured with the correct destination IP/port (if sending telemetry out)
  • [ ] LTC audio channel and frame rate configured (if using LTC)
  • [ ] HTTP control tested from the external system
  • [ ] Monitor → Network Traffic shows incoming commands from the external system
  • [ ] Monitor → Network Traffic shows outgoing commands to the external system
  • [ ] Full show run-through with all external triggers verified

Exaplay 3 User Documentation