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.
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>, "fallback" : <How much time (in us, default 250000) without receiving packets will make us drop to the substream below> }
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>" } }