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.
| Plugin | Package name | What it is for | Cargo feature | Config file | Bench page | Status |
|---|---|---|---|---|---|---|
| EchoTest | janus.plugin.echotest | Sends back what you send: the smallest test of a deployment | plugin-echotest (default) | janus.plugin.echotest.jcfg | EchoTest | verified audio, video, data channel, recording |
| VideoRoom | janus.plugin.videoroom | Video conference SFU: publishers and subscribers | plugin-videoroom | janus.plugin.videoroom.jcfg | VideoRoom | gap rooms verified; publish to subscribe fails (the subscriber's attached event has no JSEP) |
| VideoCall | janus.plugin.videocall | One-to-one call between two registered users | plugin-videocall | janus.plugin.videocall.jcfg | VideoCall | verified register, call, accept, media, hangup |
| Streaming | janus.plugin.streaming | Watch RTP, RTSP or file sources as WebRTC streams | plugin-streaming | janus.plugin.streaming.jcfg | Streaming | verified mountpoint management, watch |
| RecordPlay | janus.plugin.recordplay | Record a WebRTC session to .nfo and .mjr files and play it back | plugin-recordplay (default) | janus.plugin.recordplay.jcfg | RecordPlay | fails playback connects but the server sends 0 packets |
| TextRoom | janus.plugin.textroom | Text chat rooms over data channels | plugin-textroom | janus.plugin.textroom.jcfg | TextRoom | verified setup, join, message, whisper, list |
| AudioBridge | janus.plugin.audiobridge | Audio conference mixer (Opus) with RTP forwarders | plugin-audiobridge | janus.plugin.audiobridge.jcfg | AudioBridge | fails joins, but the mix is never sent back (0 packets) |
| SIP | janus.plugin.sip | Register at a SIP server and place or receive calls from a browser | plugin-sip | janus.plugin.sip.jcfg | SIP | gap guest register and call signalling verified against a test peer; media not exercised; one shared SIP socket |
| NoSIP | janus.plugin.nosip | WebRTC to plain RTP bridge; your application carries the SDP | plugin-nosip | janus.plugin.nosip.jcfg | NoSIP | gap generate and process verified, browser to peer RTP verified; peer to browser media is not delivered |
| Lua | janus.plugin.lua, or the name the script gives | Write a plugin as a Lua script | plugin-lua | janus.plugin.lua.jcfg (needs general.script) | Run all checks, lua.echotest | gap 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 gives | Write a plugin as a JavaScript script (engine: Boa, not Duktape) | plugin-duktape | janus.plugin.duktape.jcfg (needs general.script) | Run all checks, duktape.echotest | verified 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-echotestandplugin-recordplay. Add the rest with--features:shcargo 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>.jcfgfrom the configs folder. Some plugins need a key to start: RecordPlay needsgeneral.path, and Lua and Duktape needgeneral.script(see their pages). Every key is in the plugin files reference.Turn one off at run time with
plugins.disableinjanus.jcfg: a comma-separated list of the C library file names, one per plugin. Verified withdisable = "libjanus_audiobridge.so,libjanus_sip.so": the server loggedPlugin 'libjanus_audiobridge.so' has been disabled, skipping...(and the same for SIP), andGET /janus/infono longer listed them.textplugins: { disable = "libjanus_audiobridge.so,libjanus_sip.so" }Nothing is loaded from
plugins_folder. The setting is still checked, as in C: ifjanus.jcfgsetsplugins_folder(ortransports_folder), that folder must exist, even if it is empty, or the server stops withCouldn't access plugins folder.... Left unset, the default is only logged. The startup log still prints lines likeLoading plugin 'libjanus_textroom.so'...as C does, but no file is read from the folder.See what runs with
GET /janus/info: itspluginsobject 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 fromgetPackage()(janus.plugin.echoluafor the C sample). A plugin whose feature is not compiled in, or that is disabled, or that failed to start, is simply absent: anattachto 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.