Skip to content

Plugins ​

A plugin is what a client talks to after it attaches a handle: {"janus": "attach", "plugin": "janus.plugin.videoroom"}. The core handles sessions, ICE, DTLS and SRTP; the plugin decides what the media and the messages mean. This port has eleven plugins, the same eleven the C server builds by default or by option. Each has its own page with real requests and replies, a reference, and a list of what does not work yet.

PluginPackage nameWhat it is forCargo featureConfig fileBench pageStatus
EchoTestjanus.plugin.echotestSends back what you send: the smallest test of a deploymentplugin-echotest (default)janus.plugin.echotest.jcfgEchoTestverified audio, video, data channel, recording
VideoRoomjanus.plugin.videoroomVideo conference SFU: publishers and subscribersplugin-videoroomjanus.plugin.videoroom.jcfgVideoRoomgap rooms verified; publish to subscribe fails (the subscriber's attached event has no JSEP)
VideoCalljanus.plugin.videocallOne-to-one call between two registered usersplugin-videocalljanus.plugin.videocall.jcfgVideoCallverified register, call, accept, media, hangup
Streamingjanus.plugin.streamingWatch RTP, RTSP or file sources as WebRTC streamsplugin-streamingjanus.plugin.streaming.jcfgStreamingverified mountpoint management, watch
RecordPlayjanus.plugin.recordplayRecord a WebRTC session to .nfo and .mjr files and play it backplugin-recordplay (default)janus.plugin.recordplay.jcfgRecordPlayfails playback connects but the server sends 0 packets
TextRoomjanus.plugin.textroomText chat rooms over data channelsplugin-textroomjanus.plugin.textroom.jcfgTextRoomverified setup, join, message, whisper, list
AudioBridgejanus.plugin.audiobridgeAudio conference mixer (Opus) with RTP forwardersplugin-audiobridgejanus.plugin.audiobridge.jcfgAudioBridgefails joins, but the mix is never sent back (0 packets)
SIPjanus.plugin.sipRegister at a SIP server and place or receive calls from a browserplugin-sipjanus.plugin.sip.jcfgSIPgap guest register and call signalling verified against a test peer; media not exercised; one shared SIP socket
NoSIPjanus.plugin.nosipWebRTC to plain RTP bridge; your application carries the SDPplugin-nosipjanus.plugin.nosip.jcfgNoSIPgap generate and process verified, browser to peer RTP verified; peer to browser media is not delivered
Luajanus.plugin.lua, or the name the script givesWrite a plugin as a Lua scriptplugin-luajanus.plugin.lua.jcfg (needs general.script)Run all checks, lua.echotestgap sample echotest.lua echoes audio and video; load errors are not explained in the log
Duktape (JavaScript)janus.plugin.duktape, or the name the script givesWrite a plugin as a JavaScript script (engine: Boa, not Duktape)plugin-duktapejanus.plugin.duktape.jcfg (needs general.script)Run all checks, duktape.echotestverified sample echotest.js echoes audio and video

The status column comes from the Bench results of 2026-11-04 against this binary, plus the transcripts recorded for the pages (the Status page, /parity/status, lists the port of each C file as a percentage; those numbers say how much code is written, not whether the flow works). Each plugin page says exactly what was run and what was only read from the source.

How plugins are enabled in this port ​

The C server loads each plugin as a shared library (libjanus_<name>.so) from plugins_folder. This port has no dynamic loading. Every plugin is a Rust crate compiled into the single janus binary, and each is a Cargo feature, the same way the C build has --enable-plugin-* options.

  • Choose plugins when you build. The default build has only plugin-echotest and plugin-recordplay. Add the rest with --features:

    sh
    cargo build -p janus --features "plugin-videoroom plugin-videocall plugin-streaming plugin-textroom plugin-audiobridge plugin-sip plugin-nosip plugin-lua plugin-duktape"

    The feature list is in janus/Cargo.toml, and Build and run explains it.

  • A compiled-in plugin starts at boot. It reads janus.plugin.<name>.jcfg from the configs folder. Some plugins need a key to start: RecordPlay needs general.path, and Lua and Duktape need general.script (see their pages). Every key is in the plugin files reference.

  • Turn one off at run time with plugins.disable in janus.jcfg: a comma-separated list of the C library file names, one per plugin. Verified with disable = "libjanus_audiobridge.so,libjanus_sip.so": the server logged Plugin 'libjanus_audiobridge.so' has been disabled, skipping... (and the same for SIP), and GET /janus/info no longer listed them.

    text
    plugins: {
    	disable = "libjanus_audiobridge.so,libjanus_sip.so"
    }
  • Nothing is loaded from plugins_folder. The setting is still checked, as in C: if janus.jcfg sets plugins_folder (or transports_folder), that folder must exist, even if it is empty, or the server stops with Couldn't access plugins folder.... Left unset, the default is only logged. The startup log still prints lines like Loading plugin 'libjanus_textroom.so'... as C does, but no file is read from the folder.

  • See what runs with GET /janus/info: its plugins object lists every loaded plugin by package name, with the name, author, description and version. A script plugin is listed under the package name its script returns from getPackage() (janus.plugin.echolua for the C sample). A plugin whose feature is not compiled in, or that is disabled, or that failed to start, is simply absent: an attach to it gets an error.

Where the requests are ​

Every plugin request is a Janus API message with a body. The Janus API walkthrough shows the envelope, WebRTC from a browser shows how the SDP and ICE parts fit in, and the Admin API can query a handle's plugin state (handle_info) and send an admin message to a plugin (message_plugin). Plugin errors come back as success at the Janus level with error_code inside plugindata.data: see error codes.

GPL-3.0-or-later, like the Janus gateway it ports.