Protocolo da conferência
Este documento visa descrever as evoluções que iremos efetuar na gestão de conferências (áudio/vídeo). O objetivo é melhorar a implementação atual, que se limita a fundir chamadas SIP e a fornecer uma vista em grelha, para uma vista em que os participantes são listados, podem ser silenciados independentemente ou a disposição do vídeo pode ser alterada (para mostrar apenas um participante)
Definições
Hospedeiro: é o utilizador que mistura os fluxos de áudio/vídeo para os outros
Participante: Todos os utilizadores da conferência, mesmo o hospedeiro
Isenção de responsabilidade
Para já, este documento descreve apenas os primeiros passos. Isto significa que a identificação dos participantes e a posição no misturador de vídeo é enviada a todos os participantes.
Layouts possíveis
Grelha: todos os membros são apresentados com a mesma altura/largura
UM_GRANDE_COM_UM_PEQUENO: Um membro é ampliado e a outra pré-visualização é mostrada
UM_GRANDE: um membro cobre todo ecrã
Estão disponíveis dois novos métodos para gerir o layout da conferência no 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);
Implementação
A implementação é bastante simples. Tudo é gerido por conference.cpp
(para ligar os participantes às fontes) e video_mixer.cpp
(para renderizar o layout desejado).
Sincronização das informações das conferências
Nota: atualmente, a palavra participante é utilizada para o callID misturado numa conferência. Este facto pode, inicialmente, causar alguns problemas na API e deve ser corrigido no futuro
O objetivo é notificar todos os participantes sobre os metadados do vídeo processado. Isto significa qual o participante que está na conferência e onde se encontra o vídeo.
Se um participante for ele próprio uma conferência, as suas informações de apresentação recebidas devem ser fundidas quando enviadas a outros participantes. As informações de apresentação não devem ser fundidas quando enviadas de volta para uma conferência.
Informações sobre o layout
O layout é armazenado como um VectorMapStringString para clientes e internamente com um vetor
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"
}
(...)
}
As chaves possíveis são:
uri = uri da conta
device = ID (identificação) do dispositivo
media = identificação da media
active = se o participante estiver ativo
x = posição (x) no vídeo
y = posição (y) no vídeo
w = tamanho (largura) no vídeo
h = tamanho (altura) no vídeo
videoMuted = se o vídeo está silenciado
audioLocalMuted = se o áudio está localmente silenciado
audioModeratorMuted = se o áudio é silenciado pelos moderadores
isModerator = se é um moderador
handRaised = se a mão estiver levantada
voiceActivity = se o fluxo tem atividade de voz
recording = se o par estiver a gravar a conferência
Nova API
Estão disponíveis um novo método (no CallManager) e um novo sinal para, respetivamente, obter informações e atualizações da conferência atual:
VectorMapStringString getConferenceInfos(const std::string& confId);
void onConferenceInfosUpdated(const std::string& confId, const VectorMapStringString& infos);
Implementação
O objeto Conference
(que só existe se misturarmos chamadas, o que significa que somos o mestre) gere a informação de toda a conferência, com base nos LayoutInfos de cada objeto Call
. O getConferenceInfos irá obter informações diretamente deste objeto.
Assim, cada objeto Call
tem agora um LayoutInfo e, se atualizado, pede ao objeto Conference
para atualizar a sua informação.
O mestre de uma conferência envia as suas informações através do canal SIP como uma mensagem com o seguinte tipo MIME: application/confInfo+json
Assim, se uma chamada receber algum confInfo, sabemos que essa chamada é membro de uma conferência.
Resumindo, Call
gere os layouts recebidos, Conference
gere os layouts enviados.
Alterar o estado da conferência
Para mudar o estado da conferência, os participantes precisam de enviar ordens com as quais o hospedeiro irá lidar.
O protocolo tem as seguintes necessidades:
Deve tratar as ordens a vários níveis. De facto, para uma conferência, existem 3 níveis para definir um participante:
A conta que representa a identidade do participante
Dispositivos, porque cada conta pode aderir através de vários dispositivos
Medias, porque pode haver vários vídeos por dispositivos (por exemplo, 1 câmara e 1 partilha de ecrã)
Para poupar largura de banda, os clientes devem poder enviar várias ordens de uma só vez.
Ações gerais
Para alterar um esquema, o moderador pode enviar uma carga com «application/confOrder+json» como tipo: onde 0 é uma grelha, 1 é um utilizador em grande, outros em pequeno, 2 é um em grande
Ações da conta
Por enquanto, não existe nenhuma ação suportada, no entanto, no futuro moderador: verdadeiro/falso
deve ser tratado para alterar um moderador.
Ações do dispositivo
hangup: true
para desligar um dispositivo da conferência (apenas moderadores)raisehand: true/false
para alterar o estado da mão levantada. Só pode ser efetuado pelo próprio dispositivo, caso contrário é eliminado.
Ações da media
muteAudio
só é possível aos moderadores silenciarem o áudio de um participantemuteVideo
ainda não suportado.active
para marcar o media como ativo.voiceActivity
para indicar o estado da atividade vocal de um fluxo de media (apenas relevante para o áudio)
Exemplo
Assim, o application/confOrder+json
conterá:
{
"989587609427420" : {
"moderator": true/false,
"devices": {
"40940943604396R64363": {
"hangup": true,
"raisehand": true/false,
"media":{
"3532532662432" : {
"muteAudio": true/false,
"muteVideo": true/false,
"active": true/false,
"voiceActivity": true/false
}
}
}
}
},
"layout": 0/1/2,
}
Nota: o tipo de media deve ser incluído nas informações das conferências e pode ser utilizado pelo cliente para melhorar a visualização (por exemplo, não cortar a partilha de ecrã)
Controlo dos moderadores
Na verdade, existem 3 possibilidades:
Alterar a configuração da conta para adicionar uma lista de moderadores (no config.yml (
defaultModerators
pode conter uma lista de moderadores predefinidos)Se
localModeratorsEnabled
fortrue
, todas as contas do dispositivo serão moderadorasSe
allModeratorsEnabled
fortrue
, qualquer pessoa na conferência será um moderador
Futuro
Fluxos separados para permitir mais controlos?
Notas / comentários
É provável que o protocolo evolua para necessidades futuras. Penso que é preferível dispormos de um campo «versão». A versão mais antiga será reconhecida se este campo não existir.