Fork me on GitHub
VideoCall plugin documentation

This is a simple video call plugin for Janus, allowing two WebRTC peers to call each other through the Janus core. The idea is to provide a similar service as the well known AppRTC demo (https://apprtc.appspot.com), but with the media flowing through a server rather than being peer-to-peer.

The plugin provides a simple fake registration mechanism. A peer attaching to the plugin needs to specify a username, which acts as a "phone number": if the username is free, it is associated with the peer, which means he/she can be "called" using that username by another peer. Peers can either "call" another peer, by specifying their username, or wait for a call. The approach used by this plugin is similar to the one employed by the echo test one: all frames (RTP/RTCP) coming from one peer are relayed to the other.

Just as in the janus_videocall.c plugin, there are knobs to control whether audio and/or video should be muted or not, and if the bitrate of the peer needs to be capped by means of REMB messages.

Video Call API

All requests you can send in the Video Call API are asynchronous, which means all responses (successes and errors) will be delivered as events with the same transaction.

The supported requests are list , register , call , accept , set and hangup . list allows you to get a list of all the registered peers; register can be used to register a username to call and be called; call is used to start a video call with somebody through the plugin, while accept is used to accept the call in case one is invited instead of inviting; set can be used to configure some call-related settings (e.g., a cap on the send bandwidth); finally, hangup can be used to terminate the communication at any time, either to hangup an ongoing call or to cancel/decline a call that hasn't started yet.

The list request has to be formatted as follows:

{
        "request" : "list"
}

A successful request will result in an array of peers to be returned:

{
        "videocall" : "event",
        "result" : {
                "list": [       // Array of peers
                        "alice78",
                        "bob51",
                        // others
                ]
        }
}

An error instead (and the same applies to all other requests, so this won't be repeated) would provide both an error code and a more verbose description of the cause of the issue:

{
        "videocall" : "event",
        "error_code" : <numeric ID, check Macros below>,
        "error" : "<error description as a string>"
}

To register a username to call and be called, the register request can be used. This works on a "first come, first served" basis: there's no authentication involved, you just specify the username you'd like to use and, if free, it's assigned to you. Notice that there's no way to unregister: you have to close the handle to free the username. The register request has to be formatted as follows:

{
        "request" : "register",
        "username" : "<desired unique username>"
}

If successul, this will result in a registered event:

{
        "videocall" : "event",
        "result" : {
                "event" : "registered",
                "username" : "<same username, registered>"
        }
}

Once you're registered, you can either start a new call or wait to be called by someone else who knows your username. To start a new call, the call request can be used: this request must be attached to a JSEP offer containing the WebRTC-related info to setup a new media session. A call request has to be formatted as follows:

{
        "request" : "call",
        "username" : "<username to call>"
}

If successul, this will result in a calling event:

{
        "videocall" : "event",
        "result" : {
                "event" : "calling",
                "username" : "<same username, registered>"
        }
}

At the same time, the user being called will receive an incomingcall event

{
        "videocall" : "event",
        "result" : {
                "event" : "incomingcall",
                "username" : "<your username>"
        }
}

To accept the call, the accept request can be used. This request must be attached to a JSEP answer containing the WebRTC-related information to complete the actual PeerConnection setup. A accept request has to be formatted as follows:

{
        "request" : "accept"
}

If successul, both the caller and the callee will receive an accepted event to notify them about the success of the signalling:

{
        "videocall" : "event",
        "result" : {
                "event" : "accepted",
                "username" : "<caller username>"
        }
}

At this point, the media-related settings of the call can be modified on either side by means of a set request, which acts pretty much as the one in the Echo Test API . The set request has to be formatted as follows. All the attributes (except request) are optional, so any request can contain a subset of them:

{
        "request" : "set",
        "audio" : true|false,
        "video" : true|false,
        "bitrate" : <numeric bitrate value>,
        "record" : true|false,
        "filename" : <base path/filename to use for the recording>,
        "substream" : <substream to receive (0-2), in case simulcasting is enabled>,
        "temporal" : <temporal layers to receive (0-2), in case simulcasting is enabled>
}

audio instructs the plugin to do or do not relay audio frames; video does the same for video; bitrate caps the bandwidth to force on the browser encoding side (e.g., 128000 for 128kbps); record enables or disables the recording of this peer; in case recording is enabled, filename allows to specify a base path/filename to use for the files (-audio.mjr, -video.mjr and -data.mjr are automatically appended). Beware that enabling the recording only records this user's contribution, and not the whole call: to record both sides, you need to enable recording for both the peers in the call. Finally, in case the call uses simulcasting, substream and temporal can be used to manually pick which substream and/or temporal layer should be received from the peer.

A successful request will result in a set event:

{
        "videocall" : "event",
        "result" : {
                "event" : "set"
        }
}

Notice that the set request is also what you use when you want to renegotiate a session, e.g., for the purpose of adding/removing media streams or forcing an ICE restart. In that case, even an empty set request is fine, as long as it accompanies a new JSEP offer or answer (depending on who originated the session update). The user receiving the updated JSEP offer/answer will get an update event:

{
        "videocall" : "event",
        "result" : {
                "event" : "update",
        }
}

To decline an incoming call, cancel an attempt to call or simply hangup an ongoing conversation, the hangup request can be used, which has to be formatted as follows:

{
        "request" : "hangup"
}

Whatever the reason of a call being closed (e.g., a hangup request, a PeerConnection being closed, or something else), both parties in the communication will receive a hangup event:

{
        "videocall" : "event",
        "result" : {
                "event" : "hangup",
                "username" : "<username of who closed the communication>",
                "reason" : "<description of what happened>"
        }
}