6.3 KiB
Conference protocol
This document aims to describe the evolutions we will do for managing conferences (audio/video). The goal is to improve the current implementation which simply merges SIP calls and provide a grid view, to a view where participants are listed, can be muted independently, or the video layout changed (to show only one participant)
Definitions
- Host: Is the user who mix the audio/video streams for the others
- Participant: Every user in the conference, even the host
Disclaimer
This document only describes the first steps for now. This means the identification of participants and position in the video mixer sent to all participants.
Possible layouts
- GRID: Every member is shown with the same height/width
- ONE_BIG_WITH_SMALL: One member is zoomed and the other preview is shown
- ONE_BIG: One member take the full screen rendered
Two new methods are available to manage the conference Layout in CallManager:
/**
* Change the conference layout
* @param confId
* @param layout 0 = matrix, 1 = one big, others in small, 2 = one in big
*/
void setConferenceLayout(const std::string& confId, int layout);
/**
* Change the active participant (used in layout != matrix)
* @param confId
* @param participantId If participantId not found, the local video will be shown
*/
void setActiveParticipant(const std::string& confId, const std::string& participantId);
Implementation
The implementation is pretty straightforward. Everything is managed by conference.cpp
(to link participant to sources) and video_mixer.cpp
(to render the wanted layout).
Syncing Conferences Informations
Note: Actually, the word participant is used for callId mixed in a conference. This can lead at first to some problems for the API and must be fixed in the future
The goal is to notify all participants of the metadata of the rendered video. This means what participant is in the conference and where the video is located.
If a participant is itself a conference, its incoming layout info should be merged when sent to other participants. Layout info must not be merged when sent back to a conference.
Layout Info
The Layout is stored as a VectorMapStringString for clients and internally with a vector with the following format:
Layout = {
{
"uri": "participant", "x":"0", "y":"0", "w": "0", "h": "0", "isModerator": "true"
},
{
"uri": "participant1", "x":"0", "y":"0", "w": "0", "h": "0", "isModerator": "false"
}
(...)
}
Possible keys are:
- uri = account's uri
- device = device's id
- media = media's id
- active = if the participant is active
- x = position (x) in the video
- y = position (y) in the video
- w = size (width) in the video
- h = size (height) in the video
- videoMuted = if the video is muted
- audioLocalMuted = if the audio is locally muted
- audioModeratorMuted = if the audio is muted by moderators
- isModerator = if it's a moderator
- handRaised = if the hand is raised
In the future, isTalking
will probably be added
New API
A new method (in CallManager) and a new signal to respectively get current conference infos and updates are available:
VectorMapStringString getConferenceInfos(const std::string& confId);
void onConferenceInfosUpdated(const std::string& confId, const VectorMapStringString& infos);
Implementation
The Conference
Object (which only exists if we mix calls, this means that we are the master) manages the information for the whole conference, based on the LayoutInfos of each Call
object. The getConferenceInfos will retrieve info directly from this object.
So, every Call
object now has a LayoutInfo and if updated, ask the Conference
object to updates its info.
The master of a conference sends its info via the SIP channel as a message with the following MIME type:
application/confInfo+json
So, if a call receives some confInfo, we know that this call is a member of a conference.
To summarize, Call
manages received layouts, Conference
-managed sent layouts.
Changing the state of the conference
To change the state of the conference, participants needs to send orders that the host will handle.
The protocol have the following needs:
It should handle orders at multiple levels. In fact for a conference the is 3 levels to define a participant:
- The account which is the identity of the participant
- Devices, because each account can join via multiple devices
- Medias, because there can be multiple videos by devices (eg 1 camera and 1 screen sharing)
To save bandwidth, clients should be able to send multiple orders at once.
General actions
To change a layout, the moderator can send a payload with "application/confOrder+json" as type: where 0 is a grid, 1 is one user in big, others in small, 2 is one in big
Account's actions
For now, there is no action supported, however, in the future moderator: true/false
should be handled to change a moderator.
Device's actions
hangup: true
to hangup a device from the conference (only moderators)raisehand: true/false
to change the raise hand's status. Only doable by the device itself, else dropped.
Media's actions
muteAudio
only doable by moderators to mute the audio of a participantmuteVideo
not supported yet.active
to mark the media as active.
Example
So, the application/confOrder+json
will contains:
{
"989587609427420" : {
"moderator": true/false
"devices": {
"40940943604396R64363": {
"hangup": true,
"raisehand": true/false,
"media":{
"3532532662432" : {
"muteAudio": true/false,
"muteVideo": true/false,
"active": true/false
}
}
}
}
}
"layout": 0/1/2,
}
Controlling moderators
There is actually 3 possibilities:
- Changing account's config to add a list of moderators (In the config.yml (
defaultModerators
can contains a list of default moderators) - If
localModeratorsEnabled
is true, all accounts of the device will be moderators - If
allModeratorsEnabled
is true, anybody in the conference will be a moderator
Future
- Separate streams to allow more controls?