Ensure the Janus gateway is compiled with the VideoRoom plugin enabled (it is included by default); edit janus.plugin.videoroom.jcfg to set global defaults such as admin_key for room management and whether rooms are recorded by default.
Create a room by sending a Janus API message to the videoroom plugin handle with request: 'create', including room (integer), description, bitrate, max_publishers, and optionally record: true with rec_dir pointing to your recording path.
Each participant establishes a Janus session via HTTP long-poll or WebSocket, attaches to the videoroom plugin, and sends a join message with request: 'join', room, ptype: 'publisher', and display name.
After joining as publisher, the client sends an offer SDP in a publish request; Janus responds with an answer SDP. The client then sends trickled ICE candidates via the trickle Janus API message.
To subscribe to another publisher, create a separate plugin handle, join with ptype: 'subscriber', and specify the publisher's feed ID; Janus sends an offer for the subscriber handle and the client answers.
Manage rooms server-side via the Janus Admin API (requires admin_secret) or via plugin messages with the admin_key to list rooms, kick participants, or destroy rooms.
Known gotchas
Each publisher and each subscription feed requires its own separate Janus plugin handle; reusing a handle for multiple purposes causes unexpected behavior.
The Janus VideoRoom plugin caps bitrate per publisher via the bitrate room config option — if unset, publishers negotiate freely and may overwhelm downstream subscribers.
If the Janus server is behind NAT, set nat_1_1_mapping in janus.jcfg to the public IP; otherwise ICE candidates advertise private addresses and connections fail from external clients.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp