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);
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);
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: truepara desligar um dispositivo da conferência (apenas moderadores)raisehand: true/falsepara alterar o estado da mão levantada. Só pode ser efetuado pelo próprio dispositivo, caso contrário é eliminado.
Ações da media
muteAudiosó é possível aos moderadores silenciarem o áudio de um participantemuteVideoainda não suportado.activepara marcar o media como ativo.voiceActivitypara indicar o estado da atividade vocal de um fluxo de media (apenas relevante para o áudio)
Exemplo
So, the application/confOrder+json will contain:
{
"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 (
defaultModeratorspode conter uma lista de moderadores predefinidos)Se
localModeratorsEnabledfortrue, todas as contas do dispositivo serão moderadorasSe
allModeratorsEnabledfortrue, 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.