Janus Video Room Plugin
May 01, 2020
1 min

video room plugin

There are two type conference media server. there are SFC(Selective Forwarding Unit) and MCU(Multipoint Control Unit). This plugin implementing a base with SFU. An SFU is capable of receiving multiple media streams and then decide which of these media streams should be sent to which participants. The plugin implements a virtual conferencing room peers can join and leave at any time. This room is based on a Publish/Subscribe pattern. Each peer can publish her/his own live audio/video feeds: each feed becomes an available stream in the room the other participants can attach to. This means that this plugin allows the realization of several different scenarios, ranging from a simple webinar (one speaker, several listeners) to a fully meshed video conference (each peer sending and receiving to and from all the others).

how work?

initiate janus with attaching plugin

Janus.init({debug: "all", callback: function() {
      // Make sure the browser supports WebRTC
      // Create session
        janusRoom = new Janus(
              server: JANUS_SERVER_URL,
              iceServers: ICE_SERVERS,
              success: function() {
                  // Attach to VideoRoom plugin
                          plugin: "janus.plugin.videoroom",

inform to janus you are publisher or subscriber

const register = { "request": "join", "room": myroom, "ptype": "publisher", "display": reg };

if you can join to the janus session. you will receive joined event

if (event != undefined && event != null) {
    if (event === "joined") {
        // Publisher/manager created, negotiate WebRTC and attach to existing feeds, if any
        myid = msg["id"];
        mypvtid = msg["private_id"];
        id:  msg["id"],
        privateId: msg["private_id"],
        local: true,
        console.log("Successfully joined room " + msg["room"] + " with ID " + myid);

if you publisher you have to createOffer

            media: { audioRecv: false, videoRecv: false, audioSend: useAudio, videoSend: true },    // Publishers are sendonly
            success: function(jsep) {
                Janus.debug("Got publisher SDP!");

                const publish = { "request": "configure", "audio": useAudio, "video": true };
                vroomHandle.send({"message": publish, "jsep": jsep});
            error: function(error) {
                Janus.error("WebRTC error:", error);
                if (useAudio) {

if you are success with sdb exchange. janus will publish local stream and you also will receive the stream

onlocalstream: function(stream) {
    mystream = stream;
    const video = document.querySelector('video#localvideo');
    const videoTracks = stream.getVideoTracks();
    console.log(`Using video device: ${videoTracks[0].label}`);
    video.srcObject = stream;

if you are subscriber you will receive publisher events.

if (msg["publishers"] !== undefined && msg["publishers"] !== null) {
        let list = msg["publishers"];
        console.log("Got a list of available publishers/feeds:");
        for (let f in list) {
            let id = list[f]["id"];
            let display = list[f]["display"];
            let audioCodec = list[f]["audio_codec"];
            let videoCodec = list[f]["video_codec"];
            privateId: msg["private_id"],
            local: false,
            newRemoteFeed(id, display, audioCodec, videoCodec);

you have to attach one video plugin for one publisher

function newRemoteFeed(id, display, audio, video) {
    console.log('rmote fsfsdfkdfdsff')
    // A new feed has been published, create a new plugin handle and attach to it as a subscriber
    let remoteFeed = null;
            plugin: "janus.plugin.videoroom",
            opaqueId: opaqueId,
            success: function(pluginHandle) {
                remoteFeed = pluginHandle;
                console.log("Plugin attached! (" + remoteFeed.getPlugin() + ", id=" + remoteFeed.getId() + ")");
                console.log("  -- This is a subscriber");
                // We wait for the plugin to send us an offer
                let subscribe = {
                    request: "join",
                    room: myroom,
                    ptype: "subscriber",
                    feed: id,
                    private_id: mypvtid
                remoteFeed.videoCodec = video;
                remoteFeed.send({ message: subscribe });

if subscribed, you can negotiate the sdp with remote peer.

 onmessage: function(msg, jsep) {
    console.log('got message from subscripber--------')
    Janus.debug(" ::: Got a message (subscriber) :::", msg);
    let event = msg["videoroom"];
    console.log("Event: " + event);
    if(event) {
        if(event === "attached") {
            console.log(`subscriber created and attached!`);
            feeds[msg['id']] = remoteFeed;
            remoteFeed.rfid = msg["id"];
            remoteFeed.rfdisplay = msg["display"];
    if(jsep) {
        Janus.debug("Handling SDP as well...", jsep);
        // Answer and attach
                jsep: jsep,
                // Add data:true here if you want to subscribe to datachannels as well
                // (obviously only works if the publisher offered them in the first place)
                media: { audioSend: false, videoSend: false },  // We want recvonly audio/video
                success: function(jsep) {
                    console.log("Got SDP!", jsep);
                    let body = { request: "start", room: myroom };
                    remoteFeed.send({ message: body, jsep: jsep });
                error: function(error) {
                    console.error("WebRTC error:", error);

you will receive remote stream from

 onremotestream: function(stream) {
    Janus.attachMediaStream(document.getElementById(`participant-video-${remoteFeed.rfid}`), stream);
    let videoTracks = stream.getVideoTracks()

let start video conference with janus cheers !!.



Related Posts

How to install Janus Gateway in Ubuntu Server 18.04
July 15, 2021
1 min