Fork me on GitHub
Data Structures | Macros | Typedefs | Enumerations | Functions
janus_videoroom.c File Reference

Janus VideoRoom plugin. More...

#include "plugin.h"
#include <jansson.h>
#include "../debug.h"
#include "../apierror.h"
#include "../config.h"
#include "../mutex.h"
#include "../rtp.h"
#include "../rtcp.h"
#include "../record.h"
#include "../sdp-utils.h"
#include "../utils.h"
#include <sys/types.h>
#include <sys/socket.h>
Include dependency graph for janus_videoroom.c:

Data Structures

struct  janus_videoroom_message
 
struct  janus_videoroom
 
struct  janus_videoroom_session
 
struct  janus_videoroom_rtp_forwarder
 
struct  janus_videoroom_participant
 
struct  janus_videoroom_listener
 
struct  janus_videoroom_rtp_relay_packet
 

Macros

#define JANUS_VIDEOROOM_VERSION   8
 
#define JANUS_VIDEOROOM_VERSION_STRING   "0.0.8"
 
#define JANUS_VIDEOROOM_DESCRIPTION   "This is a plugin implementing a videoconferencing SFU (Selective Forwarding Unit) for Janus, that is an audio/video router."
 
#define JANUS_VIDEOROOM_NAME   "JANUS VideoRoom plugin"
 
#define JANUS_VIDEOROOM_AUTHOR   "Meetecho s.r.l."
 
#define JANUS_VIDEOROOM_PACKAGE   "janus.plugin.videoroom"
 
#define OPUS_PT   111
 
#define ISAC32_PT   104
 
#define ISAC16_PT   103
 
#define PCMU_PT   0
 
#define PCMA_PT   8
 
#define G722_PT   9
 
#define VP8_PT   96
 
#define VP9_PT   101
 
#define H264_PT   107
 
#define JANUS_VIDEOROOM_ERROR_UNKNOWN_ERROR   499
 
#define JANUS_VIDEOROOM_ERROR_NO_MESSAGE   421
 
#define JANUS_VIDEOROOM_ERROR_INVALID_JSON   422
 
#define JANUS_VIDEOROOM_ERROR_INVALID_REQUEST   423
 
#define JANUS_VIDEOROOM_ERROR_JOIN_FIRST   424
 
#define JANUS_VIDEOROOM_ERROR_ALREADY_JOINED   425
 
#define JANUS_VIDEOROOM_ERROR_NO_SUCH_ROOM   426
 
#define JANUS_VIDEOROOM_ERROR_ROOM_EXISTS   427
 
#define JANUS_VIDEOROOM_ERROR_NO_SUCH_FEED   428
 
#define JANUS_VIDEOROOM_ERROR_MISSING_ELEMENT   429
 
#define JANUS_VIDEOROOM_ERROR_INVALID_ELEMENT   430
 
#define JANUS_VIDEOROOM_ERROR_INVALID_SDP_TYPE   431
 
#define JANUS_VIDEOROOM_ERROR_PUBLISHERS_FULL   432
 
#define JANUS_VIDEOROOM_ERROR_UNAUTHORIZED   433
 
#define JANUS_VIDEOROOM_ERROR_ALREADY_PUBLISHED   434
 
#define JANUS_VIDEOROOM_ERROR_NOT_PUBLISHED   435
 
#define JANUS_VIDEOROOM_ERROR_ID_EXISTS   436
 
#define JANUS_VIDEOROOM_ERROR_INVALID_SDP   437
 

Typedefs

typedef enum janus_videoroom_p_type janus_videoroom_p_type
 
typedef struct janus_videoroom_message janus_videoroom_message
 
typedef enum janus_videoroom_audiocodec janus_videoroom_audiocodec
 
typedef enum janus_videoroom_videocodec janus_videoroom_videocodec
 
typedef struct janus_videoroom janus_videoroom
 
typedef struct janus_videoroom_session janus_videoroom_session
 
typedef struct janus_videoroom_rtp_forwarder janus_videoroom_rtp_forwarder
 
typedef struct janus_videoroom_participant janus_videoroom_participant
 
typedef struct janus_videoroom_listener janus_videoroom_listener
 
typedef struct janus_videoroom_rtp_relay_packet janus_videoroom_rtp_relay_packet
 

Enumerations

enum  janus_videoroom_p_type { janus_videoroom_p_type_none = 0, janus_videoroom_p_type_subscriber, janus_videoroom_p_type_publisher }
 
enum  janus_videoroom_audiocodec {
  JANUS_VIDEOROOM_OPUS, JANUS_VIDEOROOM_ISAC_32K, JANUS_VIDEOROOM_ISAC_16K, JANUS_VIDEOROOM_PCMU,
  JANUS_VIDEOROOM_PCMA, JANUS_VIDEOROOM_G722
}
 
enum  janus_videoroom_videocodec { JANUS_VIDEOROOM_VP8, JANUS_VIDEOROOM_VP9, JANUS_VIDEOROOM_H264 }
 

Functions

janus_plugincreate (void)
 
int janus_videoroom_init (janus_callbacks *callback, const char *config_path)
 
void janus_videoroom_destroy (void)
 
int janus_videoroom_get_api_compatibility (void)
 
int janus_videoroom_get_version (void)
 
const char * janus_videoroom_get_version_string (void)
 
const char * janus_videoroom_get_description (void)
 
const char * janus_videoroom_get_name (void)
 
const char * janus_videoroom_get_author (void)
 
const char * janus_videoroom_get_package (void)
 
void janus_videoroom_create_session (janus_plugin_session *handle, int *error)
 
struct janus_plugin_resultjanus_videoroom_handle_message (janus_plugin_session *handle, char *transaction, json_t *message, json_t *jsep)
 
void janus_videoroom_setup_media (janus_plugin_session *handle)
 
void janus_videoroom_incoming_rtp (janus_plugin_session *handle, int video, char *buf, int len)
 
void janus_videoroom_incoming_rtcp (janus_plugin_session *handle, int video, char *buf, int len)
 
void janus_videoroom_incoming_data (janus_plugin_session *handle, char *buf, int len)
 
void janus_videoroom_slow_link (janus_plugin_session *handle, int uplink, int video)
 
void janus_videoroom_hangup_media (janus_plugin_session *handle)
 
void janus_videoroom_destroy_session (janus_plugin_session *handle, int *error)
 
json_t * janus_videoroom_query_session (janus_plugin_session *handle)
 

Detailed Description

Janus VideoRoom plugin.

Author
Lorenzo Miniero loren.nosp@m.zo@m.nosp@m.eetec.nosp@m.ho.c.nosp@m.om

This is a plugin implementing a videoconferencing SFU (Selective Forwarding Unit) for Janus, that is an audio/video router. This means that 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 his/her own live audio/video feeds: this 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).

For what concerns the subscriber side, there are two different ways to attach to a publisher's feed: a generic 'listener', which can attach to a single feed, and a more complex 'Multiplexed listener', which instead can attach to more feeds using the same PeerConnection. The generic 'listener' is the default, which means that if you want to watch more feeds at the same time, you'll need to create multiple 'listeners' to attach at any of them. The 'Multiplexed listener', instead, is a more complex alternative that exploits the so called RTCWEB 'Plan B', which multiplexes more streams on a single PeerConnection and in the SDP: while more efficient in terms of resources, though, this approach is experimental, and currently only available on Google Chrome, so use it wisely.

Note
As of now, work on Plan B is still going on, and as such its support in Janus is flaky to say the least. Don't try to attach as a Multiplexed listener or bad things will probably happen!

Considering that this plugin allows for several different WebRTC PeerConnections to be on at the same time for the same peer (specifically, each peer potentially has 1 PeerConnection on for publishing and N on for subscriptions from other peers), each peer may need to attach several times to the same plugin for every stream: this means that each peer needs to have at least one handle active for managing its relation with the plugin (joining a room, leaving a room, muting/unmuting, publishing, receiving events), and needs to open a new one each time he/she wants to subscribe to a feed from another participant (or a single one in case a 'Multiplexed listener is used). The handle used for a subscription, however, would be logically a "slave" to the master one used for managing the room: this means that it cannot be used, for instance, to unmute in the room, as its only purpose would be to provide a context in which creating the sendonly PeerConnection for the subscription to the active participant.

Rooms to make available are listed in the plugin configuration file. A pre-filled configuration file is provided in conf/janus.plugin.videoroom.cfg and includes a demo room for testing. The same plugin is also used dynamically (that is, with rooms created on the fly via API) in the Screen Sharing demo as well.

To add more rooms or modify the existing one, you can use the following syntax:

[<unique room ID>]
description = This is my awesome room
is_private = yes|no (private rooms don't appear when you do a 'list' request)
secret = <optional password needed for manipulating (e.g. destroying) the room>
pin = <optional password needed for joining the room>
require_pvtid = yes|no (whether subscriptions are required to provide a valid
             a valid private_id to associate with a publisher, default=no)
publishers = <max number of concurrent senders> (e.g., 6 for a video
             conference or 1 for a webinar)
bitrate = <max video bitrate for senders> (e.g., 128000)
fir_freq = <send a FIR to publishers every fir_freq seconds> (0=disable)
audiocodec = opus|isac32|isac16|pcmu|pcma|g722 (audio codec to force on publishers, default=opus)
videocodec = vp8|vp9|h264 (video codec to force on publishers, default=vp8)
audiolevel_ext = yes|no (whether the ssrc-audio-level RTP extension must be
        negotiated/used or not for new publishers, default=yes)
audiolevel_event = yes|no (whether to emit event to other users or not)
audio_active_packets = 100 (number of packets with audio level, default=100, 2 seconds)
audio_level_average = 25 (average value of audio level, 127=muted, 0='too loud', default=25)
videoorientation_ext = yes|no (whether the video-orientation RTP extension must be
        negotiated/used or not for new publishers, default=yes)
playoutdelay_ext = yes|no (whether the playout-delay RTP extension must be
        negotiated/used or not for new publishers, default=yes)
record = true|false (whether this room should be recorded, default=false)
rec_dir = <folder where recordings should be stored, when enabled>

Note that recording will work with all codecs except iSAC.

Video Room API

The Video Room API supports several requests, some of which are synchronous and some asynchronous. There are some situations, though, (invalid JSON, invalid request) which will always result in a synchronous error response even for asynchronous requests.

create , destroy , exists, list, allowed, kick and and listparticipants are synchronous requests, which means you'll get a response directly within the context of the transaction. create allows you to create a new video room dynamically, as an alternative to using the configuration file; destroy removes a video room and destroys it, kicking all the users out as part of the process; exists allows you to check whether a specific video room exists; finally, list lists all the available rooms, while listparticipants lists all the participants of a specific room and their details.

The join , joinandconfigure , configure , publish , unpublish , start , pause , switch , stop , add , remove and leave requests instead are all asynchronous, which means you'll get a notification about their success or failure in an event. join allows you to join a specific video room, specifying whether that specific PeerConnection will be used for publishing or watching; configure can be used to modify some of the participation settings (e.g., bitrate cap); joinandconfigure combines the previous two requests in a single one (just for publishers); publish can be used to start sending media to broadcast to the other participants, while unpublish does the opposite; start allows you to start receiving media from a publisher you've subscribed to previously by means of a join , while pause pauses the delivery of the media; the switch request can be used to change the source of the media flowing over a specific PeerConnection (e.g., I was watching Alice, I want to watch Bob now) without having to create a new handle for that; stop interrupts a viewer instance; finally, leave allows you to leave a video room for good.

Notice that, in general, all users can create rooms. If you want to limit this functionality, you can configure an admin admin_key in the plugin settings. When configured, only "create" requests that include the correct admin_key value in an "admin_key" property will succeed, and will be rejected otherwise.

Actual API docs: TBD.

Plugins

Macro Definition Documentation

#define G722_PT   9
#define H264_PT   107
#define ISAC16_PT   103
#define ISAC32_PT   104
#define JANUS_VIDEOROOM_AUTHOR   "Meetecho s.r.l."
#define JANUS_VIDEOROOM_DESCRIPTION   "This is a plugin implementing a videoconferencing SFU (Selective Forwarding Unit) for Janus, that is an audio/video router."
#define JANUS_VIDEOROOM_ERROR_ALREADY_JOINED   425
#define JANUS_VIDEOROOM_ERROR_ALREADY_PUBLISHED   434
#define JANUS_VIDEOROOM_ERROR_ID_EXISTS   436
#define JANUS_VIDEOROOM_ERROR_INVALID_ELEMENT   430
#define JANUS_VIDEOROOM_ERROR_INVALID_JSON   422
#define JANUS_VIDEOROOM_ERROR_INVALID_REQUEST   423
#define JANUS_VIDEOROOM_ERROR_INVALID_SDP   437
#define JANUS_VIDEOROOM_ERROR_INVALID_SDP_TYPE   431
#define JANUS_VIDEOROOM_ERROR_JOIN_FIRST   424
#define JANUS_VIDEOROOM_ERROR_MISSING_ELEMENT   429
#define JANUS_VIDEOROOM_ERROR_NO_MESSAGE   421
#define JANUS_VIDEOROOM_ERROR_NO_SUCH_FEED   428
#define JANUS_VIDEOROOM_ERROR_NO_SUCH_ROOM   426
#define JANUS_VIDEOROOM_ERROR_NOT_PUBLISHED   435
#define JANUS_VIDEOROOM_ERROR_PUBLISHERS_FULL   432
#define JANUS_VIDEOROOM_ERROR_ROOM_EXISTS   427
#define JANUS_VIDEOROOM_ERROR_UNAUTHORIZED   433
#define JANUS_VIDEOROOM_ERROR_UNKNOWN_ERROR   499
#define JANUS_VIDEOROOM_NAME   "JANUS VideoRoom plugin"
#define JANUS_VIDEOROOM_PACKAGE   "janus.plugin.videoroom"
#define JANUS_VIDEOROOM_VERSION   8
#define JANUS_VIDEOROOM_VERSION_STRING   "0.0.8"
#define OPUS_PT   111
#define PCMA_PT   8
#define PCMU_PT   0
#define VP8_PT   96
#define VP9_PT   101

Typedef Documentation

Enumeration Type Documentation

Enumerator
JANUS_VIDEOROOM_OPUS 
JANUS_VIDEOROOM_ISAC_32K 
JANUS_VIDEOROOM_ISAC_16K 
JANUS_VIDEOROOM_PCMU 
JANUS_VIDEOROOM_PCMA 
JANUS_VIDEOROOM_G722 
Enumerator
janus_videoroom_p_type_none 
janus_videoroom_p_type_subscriber 
janus_videoroom_p_type_publisher 
Enumerator
JANUS_VIDEOROOM_VP8 
JANUS_VIDEOROOM_VP9 
JANUS_VIDEOROOM_H264 

Function Documentation

janus_plugin* create ( void  )
void janus_videoroom_create_session ( janus_plugin_session handle,
int *  error 
)
void janus_videoroom_destroy ( void  )
void janus_videoroom_destroy_session ( janus_plugin_session handle,
int *  error 
)
int janus_videoroom_get_api_compatibility ( void  )
const char * janus_videoroom_get_author ( void  )
const char * janus_videoroom_get_description ( void  )
const char * janus_videoroom_get_name ( void  )
const char * janus_videoroom_get_package ( void  )
int janus_videoroom_get_version ( void  )
const char * janus_videoroom_get_version_string ( void  )
struct janus_plugin_result * janus_videoroom_handle_message ( janus_plugin_session handle,
char *  transaction,
json_t *  message,
json_t *  jsep 
)
void janus_videoroom_hangup_media ( janus_plugin_session handle)
void janus_videoroom_incoming_data ( janus_plugin_session handle,
char *  buf,
int  len 
)
void janus_videoroom_incoming_rtcp ( janus_plugin_session handle,
int  video,
char *  buf,
int  len 
)
void janus_videoroom_incoming_rtp ( janus_plugin_session handle,
int  video,
char *  buf,
int  len 
)
int janus_videoroom_init ( janus_callbacks callback,
const char *  config_path 
)
json_t * janus_videoroom_query_session ( janus_plugin_session handle)
void janus_videoroom_setup_media ( janus_plugin_session handle)
void janus_videoroom_slow_link ( janus_plugin_session handle,
int  uplink,
int  video 
)