Gerenciar chamadas
Saiba como gerenciar chamadas com os SDKs dos Serviços de Comunicação do Azure. Vamos aprender como fazer chamadas, gerenciar seus participantes e propriedades.
Pré-requisitos
- Uma conta do Azure com uma assinatura ativa. Crie uma conta gratuitamente.
- Um recurso dos Serviços de Comunicação implantado. Crie um recurso dos Serviços de Comunicação.
- Um
User Access Token
para habilitar o cliente de chamada. Para obter mais informações sobre como obter umUser Access Token
- Opcional: conclua o guia de início rápido para começar a adicionar chamadas ao seu aplicativo
Instalar o SDK
Use o comando npm install
para instalar o SDK Comum e de Chamada dos Serviços de Comunicação do Azure para JavaScript:
npm install @azure/communication-common --save
npm install @azure/communication-calling --save
Inicializar objetos necessários
Uma instância CallClient
é necessária para a maioria das operações de chamada. Ao criar uma instância de CallClient
, você pode configurá-la com opções personalizadas, como uma instância de Logger
.
Com a instância de CallClient
, você pode criar uma instância de CallAgent
chamando o createCallAgent
. Esse método retorna de modo assíncrono um objeto de instância CallAgent
.
O método createCallAgent
usa CommunicationTokenCredential
como um argumento. Ele aceita um token de acesso do usuário.
Você pode usar o método getDeviceManager
na instância CallClient
para acessar o deviceManager
.
const { CallClient } = require('@azure/communication-calling');
const { AzureCommunicationTokenCredential} = require('@azure/communication-common');
const { AzureLogger, setLogLevel } = require("@azure/logger");
// Set the logger's log level
setLogLevel('verbose');
// Redirect log output to console, file, buffer, REST API, or whatever location you want
AzureLogger.log = (...args) => {
console.log(...args); // Redirect log output to console
};
const userToken = '<USER_TOKEN>';
callClient = new CallClient(options);
const tokenCredential = new AzureCommunicationTokenCredential(userToken);
const callAgent = await callClient.createCallAgent(tokenCredential, {displayName: 'optional Azure Communication Services user name'});
const deviceManager = await callClient.getDeviceManager()
Como gerenciar melhor a conectividade do SDK com a infraestrutura da Microsoft
A instância Call Agent
ajuda você a gerenciar chamadas (para ingressar ou iniciar chamadas). Para trabalhar, o SDK de chamada precisa se conectar à infraestrutura da Microsoft para receber notificações de chamadas de entrada e coordenar outros detalhes da chamada. O seu Call Agent
tem dois estados possíveis:
Conectado: um valor connectionStatue Call Agent
de Connected
significa que o SDK do cliente está conectado e capaz de receber notificações da infraestrutura da Microsoft.
Desconectado: um valor connectionStatue Call Agent
de Disconnected
declara que há um problema que está impedindo o SDK de se conectar corretamente. Call Agent
deve ser recriado.
invalidToken
: se um token tiver expirado ou for inválido, a instânciaCall Agent
se desconecta com este erro.connectionIssue
: se houver um problema com o cliente se conectando à infraestrutura da Microsoft, depois de muitas tentativasCall Agent
expõe o erroconnectionIssue
.
Você pode verificar se o local Call Agent
está conectado à infraestrutura da Microsoft inspecionando o valor atual da propriedade connectionState
. Durante uma chamada ativa, você pode ouvir o evento connectionStateChanged
para determinar se Call Agent
é alterado do estado Conectado ao Desconectado.
const connectionState = callAgentInstance.connectionState;
console.log(connectionState); // it may return either of 'Connected' | 'Disconnected'
const connectionStateCallback = (args) => {
console.log(args); // it will return an object with oldState and newState, each of having a value of either of 'Connected' | 'Disconnected'
// it will also return reason, either of 'invalidToken' | 'connectionIssue'
}
callAgentInstance.on('connectionStateChanged', connectionStateCallback);
Fazer uma chamada
Para criar e iniciar uma chamada, use uma das APIs no callAgent
e forneça um usuário que você criou por meio do SDK de identidade dos Serviços de Comunicação.
A criação e o início da chamada são síncronos. A instância call
permite que você assine eventos de chamada.
Realizar uma chamada 1: n para um usuário ou PSTN
Para chamar outro usuário dos Serviços de Comunicação, use o startCall
método em callAgent
e passe o destinatárioCommunicationUserIdentifier
que você criou com a biblioteca de Administração dos Serviços de Comunicação.
Para uma chamada “1:1” a um usuário, use o seguinte código:
const userCallee = { communicationUserId: '<ACS_USER_ID>' }
const oneToOneCall = callAgent.startCall([userCallee]);
Para fazer uma chamada para uma rede telefônica pública comutada (PSTN), use o startCall
método em callAgent
e passe o destinatário PhoneNumberIdentifier
. O recurso Serviços de Comunicação precisa estar configurado para permitir a chamada de PSTN.
Ao chamar um número de PSTN, especifique a seu ID de chamador alternativo. Um ID de Chamador alternativo é um número de telefone (com base no padrão E.164) que identifica o chamador em uma chamada PSTN. É o número de telefone que o destinatário da chamada vê para uma chamada de entrada.
Observação
Verifique os detalhes da oferta de chamadas PSTN. Para obter acesso ao programa de versão prévia, inscreva-se no programa de usuário pioneiro.
Para uma chamada 1:1 a um número PSTN, use o seguinte código:
const pstnCallee = { phoneNumber: '<ACS_USER_ID>' }
const alternateCallerId = {phoneNumber: '<ALTERNATE_CALLER_ID>'};
const oneToOneCall = callAgent.startCall([pstnCallee], { alternateCallerId });
Para uma chamada 1:n a um usuário e um número PSTN, use o seguinte código:
const userCallee = { communicationUserId: '<ACS_USER_ID>' }
const pstnCallee = { phoneNumber: '<PHONE_NUMBER>'};
const alternateCallerId = {phoneNumber: '<ALTERNATE_CALLER_ID>'};
const groupCall = callAgent.startCall([userCallee, pstnCallee], { alternateCallerId });
Ingressar em uma chamada de sala
Para ingressar em uma chamada room
, crie uma instância de um objeto de contexto com a propriedade roomId
como o identificador room
. Para ingressar na chamada, use o método de join
e passe a instância de contexto.
const context = { roomId: '<RoomId>' }
const call = callAgent.join(context);
Uma room
oferece aos desenvolvedores de aplicativos um controle melhor sobre quem pode ingressar em uma chamada, quando eles se encontram e como eles colaboram. Para saber mais sobre o rooms
, leia a documentação conceitual ou siga a guia de início rápido.
Ingressar em um grupo
Observação
O parâmetro groupId
é considerado metadados do sistema e pode ser usado pela Microsoft para operações que são necessárias para executar o sistema. Não inclua dados pessoais no valor groupId
. A Microsoft não trata esse parâmetro como dados pessoais e seu conteúdo pode estar visível para funcionários da Microsoft ou armazenado a longo prazo.
O parâmetro groupId
requer que os dados estejam no formato GUID. É recomendável usar GUIDs gerados aleatoriamente que não são considerados dados pessoais em seus sistemas.
Para iniciar uma nova chamada de grupo ou ingressar em uma chamada de grupo em andamento, use o método join
e passe um objeto com uma propriedadegroupId
. O groupId
valor deve ser um GUID.
const context = { groupId: '<GUID>'};
const call = callAgent.join(context);
Receber uma chamada de entrada
A instância callAgent
emite um evento incomingCall
quando a identidade registrada recebe uma chamada de entrada. Para escutar esse evento, assine usando uma destas opções:
const incomingCallHandler = async (args: { incomingCall: IncomingCall }) => {
const incomingCall = args.incomingCall;
// Get incoming call ID
var incomingCallId = incomingCall.id
// Get information about this Call. This API is provided as a preview for developers
// and may change based on feedback that we receive. Do not use this API in a production environment.
// To use this api please use 'beta' release of Azure Communication Services Calling Web SDK
var callInfo = incomingCall.info;
// Get information about caller
var callerInfo = incomingCall.callerInfo
// Accept the call
var call = await incomingCall.accept();
// Reject the call
incomingCall.reject();
// Subscribe to callEnded event and get the call end reason
incomingCall.on('callEnded', args => {
console.log(args.callEndReason);
});
// callEndReason is also a property of IncomingCall
var callEndReason = incomingCall.callEndReason;
};
callAgentInstance.on('incomingCall', incomingCallHandler);
O evento incomingCall
inclui uma instância incomingCall
que você pode aceitar ou rejeitar.
O SDK de Chamadas da Comunicação do Azure gera um diagnóstico de chamada com cameraStartFailed: true se a câmera não estiver disponível ao iniciar, aceitar ou ingressar em uma chamada com vídeo habilitado. Nesse caso, a chamada começa com o vídeo desativado. A câmera pode não estar disponível porque está sendo usada por outro processo ou porque está desabilitada no sistema operacional.
Reter e retomar chamada
Observação
Em um determinado momento, deve haver apenas 1 chamada ativa (no estado Connected
, com mídia ativa). Todas as outras chamadas devem ser colocadas em espera por um usuário ou programaticamente pelo aplicativo. Isso é comum em cenários como centros de contato, em que um usuário pode precisar lidar com várias chamadas de saída e de entrada, todas as chamadas inativas devem ser colocadas em espera e o usuário deve interagir com outras pessoas apenas na chamada ativa
Para reter ou retomar a chamada, você pode usar as APIs assíncronas hold
e resume
:
Para reter a chamada
await call.hold();
Quando a API hold
é resolvida, o estado de chamada é definido como LocalHold
. Em uma chamada 1:1, o outro participante também é colocado em espera, e o estado da chamada do ponto de vista desse participante é definido como “RemoteHold”. Mais tarde, o outro participante pode colocar sua chamada em espera, o que resultaria em uma mudança de estado para LocalHold
.
Em uma chamada em grupo ou reunião, a operação hold
é uma operação local, ou seja, ela não coloca a chamada em espera para outros participantes da chamada.
Para retomar a chamada, todos os usuários que iniciaram a pausa devem retomá-la.
Para retomar a chamada em espera:
await call.resume();
Quando a API resume
for resolvida, o estado de chamada é definido novamente como Connected
.
Ativar e desativar o mudo de chamadas
Para ativar ou desativar o mudo no ponto de extremidade local, você pode usar as APIs mute
e unmute
assíncronas:
//mute local device (microphone / sent audio)
await call.mute();
//unmute local device (microphone / sent audio)
await call.unmute();
Ativar e desativar mudo do áudio de entrada
Ativar o mudo do áudio de entrada define o volume de chamada como 0. Para ativar ou desativar o mudo do áudio de entrada, você pode usar as APIs assíncronas muteIncomingAudio
e unmuteIncomingAudio
:
//mute local device (speaker)
await call.muteIncomingAudio();
//unmute local device (speaker)
await call.unmuteIncomingAudio();
Quando o áudio de entrada estiver mudo, o SDK do cliente participante ainda recebe o áudio da chamada (áudio do participante remoto). O áudio da chamada não é ouvido no alto-falante e o participante não é capaz de ouvir até que “call.unmuteIncomingAudio()” seja chamado. No entanto, podemos aplicar filtro no áudio de chamada e reproduzir o áudio filtrado.
Gerenciar participantes remotos
Todos os participantes remotos são detalhados no objeto RemoteParticipant
e estão disponíveis por meio da coleção remoteParticipants
em uma instância de chamada. O remoteParticipants
é acessível de uma instância Call
.
Listar os participantes em uma chamada
A coleção remoteParticipants
retorna uma lista de participantes remotos na chamada fornecida:
call.remoteParticipants; // [remoteParticipant, remoteParticipant....]
Adicionar um participante a uma chamada
Para adicionar um participante (um usuário ou um número de telefone) a uma chamada, você pode usar a API addParticipant
. Forneça de um dos tiposIdentifier
. Ele retorna de modo síncrono à instância remoteParticipant
. O evento remoteParticipantsUpdated
da chamada é gerado quando um participante é adicionado com êxito à chamada.
const userIdentifier = { communicationUserId: '<ACS_USER_ID>' };
const pstnIdentifier = { phoneNumber: '<PHONE_NUMBER>' }
const remoteParticipant = call.addParticipant(userIdentifier);
const alternateCallerId = { phoneNumber: '<ALTERNATE_CALLER_ID>' };
const remoteParticipant = call.addParticipant(pstnIdentifier, { alternateCallerId });
Remover um participante de uma chamada
Para remover um participante (um usuário ou um número de telefone) de uma chamada, você pode invocar removeParticipant
. Você precisa passar um dos tipos Identifier
. Esse método resolve de modo assíncrono depois que o participante for removido da chamada. O participante também será removido da coleção remoteParticipants
.
const userIdentifier = { communicationUserId: '<ACS_USER_ID>' };
const pstnIdentifier = { phoneNumber: '<PHONE_NUMBER>' }
await call.removeParticipant(userIdentifier);
await call.removeParticipant(pstnIdentifier);
Acessar as propriedades do participante remoto
Os participantes remotos têm um conjunto de propriedades e coleções associadas:
CommunicationIdentifier
: Obtenha o identificador um participante remoto. A identidade é um de um dos tiposCommunicationIdentifier
:
const identifier = remoteParticipant.identifier;
A identidade é um dos tipos
CommunicationIdentifier
:{ communicationUserId: '<ACS_USER_ID'> }
: Objeto que representa o usuário dos Serviços de Comunicação do Azure.{ phoneNumber: '<E.164>' }
: Objeto que representa o número de telefone no formato E. 164.{ microsoftTeamsUserId: '<TEAMS_USER_ID>', isAnonymous?: boolean; cloud?: "public" | "dod" | "gcch" }
: Objeto que representa o usuário Equipes.{ id: string }
: identificador que representa o objeto que não se ajusta a nenhum dos outros tipos de identificador
state
: Obtenha o estado de um participante remoto.
const state = remoteParticipant.state;
O estado pode ser:
Idle
: Estado inicial.Connecting
: Estado de transição enquanto um participante está se conectando à chamada.Ringing
: O participante está tocando.Connected
: O participante está conectado à chamada.Hold
: O participante está em espera.EarlyMedia
: Comunicado que é reproduzido antes que um participante se conecte à chamada.InLobby
: indica que o participante remoto está no lobby.Disconnected
: Estado final. O participante está desconectado da chamada. Se o participante remoto perder sua conectividade de rede, seu estado mudará paraDisconnected
depois de dois minutos.
callEndReason
: Para saber por que um participante saiu da chamada, verifique a propriedadecallEndReason
:const callEndReason = remoteParticipant.callEndReason; const callEndReasonCode = callEndReason.code // (number) code associated with the reason const callEndReasonSubCode = callEndReason.subCode // (number) subCode associated with the reason
Observação:
- Essa propriedade só será definida ao adicionar um participante remoto por meio da API Call.addParticipant() e o participante remoto recusar, por exemplo.
- No cenário em que o UsuárioB remove o UsuárioC, do ponto de vista do UsuárioA, o UsuárioA não vê esse sinalizador sendo definido para o UsuárioC. Em outras palavras, o UsuárioA não vê a propriedade callEndReason do UsuárioC ser definida de forma alguma.
isMuted
status: para descobrir se um participante remoto está com o mudo ativado, verifique a propriedadeisMuted
. Ele retornaBoolean
.const isMuted = remoteParticipant.isMuted;
isSpeaking
status: para descobrir se um participante remoto está falando, verifique a propriedadeisSpeaking
. Ele retornaBoolean
.const isSpeaking = remoteParticipant.isSpeaking;
videoStreams
: Para inspecionar todos os fluxos de vídeo que um determinado participante está enviando nesta chamada, verifique a coleçãovideoStreams
. Ele contém objetosRemoteVideoStream
.const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
displayName
: Para obter o nome de exibição para este participante remoto, inspecione a propriedadedisplayName
que ele retorna String.const displayName = remoteParticipant.displayName;
endpointDetails
: obtenha os detalhes de todos os pontos de extremidade deste participante remotoconst endpointDetails: EndpointDetails[] = remoteParticipant.endpointDetails;
Observação: um participante remoto pode estar na chamada de muitos pontos de extremidade e cada ponto de extremidade tem seu próprio
participantId
exclusivo.participantId
é diferente da ID bruta do RemoteParticipant.identifier.
Ativar mudo para outros participantes
Observação
Para usar essa API, use o SDK da Web de Chamada dos Serviços de Comunicação do Azure versão 1.26.1 ou superior.
Para silenciar todos os outros participantes ou silenciar um participante específico conectado a uma chamada, você pode usar as APIs assíncronas muteAllRemoteParticipants
na chamada e mute
no participante remoto. O evento mutedByOthers
de Chamada é gerado quando o participante local é silenciado por outras pessoas.
Observação: não há suporte para os cenários para silenciar os participantes PSTN (número de telefone) ou os participantes da chamada 1:1.
//mute all participants except yourself
await call.muteAllRemoteParticipants();
//mute a specific participant
await call.remoteParticipants[0].mute();
Verifique as propriedades da chamada
Obtenha o ID exclusiva (cadeia de caracteres) para uma chamada:
const callId: string = call.id;
Obtenha a ID do participante local:
const participantId: string = call.info.participantId;
Observação: uma identidade dos Serviços de Comunicação do Azure pode usar o SDK de chamada na Web em muitos pontos de extremidade, e cada ponto de extremidade tem seu próprio participantId
exclusivo. participantId
é diferente da ID bruta de identidade dos Serviços de Comunicação do Azure.
Recupere a ID do thread se ingressar em uma reunião do Teams:
const threadId: string | undefined = call.info.threadId;
Obter informações sobre a chamada:
const callInfo = call.info;
Saiba mais sobre outros participantes na chamada, inspecionando a coleção remoteParticipants
na instância de ' chamada ':
const remoteParticipants = call.remoteParticipants;
Identifique o chamador de uma chamada de entrada:
const callerIdentity = call.callerInfo.identifier;
identifier
é um de um dos tiposCommunicationIdentifier
.
Obter o estado de uma chamada:
const callState = call.state;
Isso retorna uma cadeia de caracteres que representa o estado atual de uma chamada:
None
: Estado inicial da chamada.Connecting
: Estado de transição inicial quando uma chamada ser realizada ou aceita.Ringing
: Para uma chamada de saída, indica que para os participantes remotos que a chamada está tocando. Ele estáIncoming
no seu lado.EarlyMedia
: Indica um estado no qual um comunicado é reproduzido antes da chamada ser conectada.Connected
: Indica que a chamada está conectada.LocalHold
: indica que um participante local da chamada colocou a chamada em espera. Nenhuma mídia está fluindo entre o ponto de extremidade local e os participantes remotos.RemoteHold
: indica que um participante remoto da chamada colocou a chamada em espera. Nenhuma mídia está fluindo entre o ponto de extremidade local e os participantes remotos.InLobby
: indica que o usuário está no lobby.Disconnecting
: Estado de transição antes que a chamada vá para um estadoDisconnected
.Disconnected
: Estado da chamada final. Se a conexão de rede for perdida, o estado será alterado paraDisconnected
depois de dois minutos.
Descubra por que uma chamada terminou inspecionando a Propriedade callEndReason
:
const callEndReason = call.callEndReason;
const callEndReasonMessage = callEndReason.message // (string) user friendly message
const callEndReasonCode = callEndReason.code // (number) code associated with the reason
const callEndReasonSubCode = callEndReason.subCode // (number) subCode associated with the reason
Saiba se a chamada atual é de entrada ou saída inspecionando a propriedade direction
. Ele retorna CallDirection
.
const isIncoming = call.direction == 'Incoming';
const isOutgoing = call.direction == 'Outgoing';
Inspecione os fluxos de vídeo ativos e os fluxos de compartilhamento de tela ativos verificando a coleção localVideoStreams
. A API localVideoStreams
retorna objetos LocalVideoStream
do tipo Video
, ScreenSharing
ou RawMedia
.
const localVideoStreams = call.localVideoStreams;
Verifique se o microfone atual está mudo. Ele retorna Boolean
.
const muted = call.isMuted;
Verifique se o áudio de entrada atual (alto-falante) está mudo. Ele retorna Boolean
.
const incomingAudioMuted = call.isIncomingAudioMuted;
Verifique se o vídeo está ativado. Ele retorna Boolean
.
const isLocalVideoStarted = call.isLocalVideoStarted;
Verifique se o compartilhamento de tela está ativado. Ele retorna Boolean
.
const isScreenSharingOn = call.isScreenSharingOn;
Instalar o SDK
Localize o arquivo build.gradle
de nível do projeto e adicione mavenCentral()
à lista de repositórios em buildscript
e allprojects
:
buildscript {
repositories {
...
mavenCentral()
...
}
}
allprojects {
repositories {
...
mavenCentral()
...
}
}
Em seguida, no arquivo build.gradle
no nível do módulo, adicione as seguintes linhas à seção dependencies
:
dependencies {
...
implementation 'com.azure.android:azure-communication-calling:1.0.0'
...
}
Inicializar objetos necessários
Para criar uma instância CallAgent
, você precisa chamar o método createCallAgent
em uma instância CallClient
. Essa chamada retorna de forma assíncrona um objeto de instância CallAgent
.
O método createCallAgent
usa CommunicationUserCredential
como argumento, que encapsula um token de acesso.
Para acessar DeviceManager
, você deverá criar uma instância callAgent
primeiro. Em seguida, você poderá usar o método CallClient.getDeviceManager
para obter DeviceManager
.
String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an activity, for instance
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential).get();
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
Para definir um nome de exibição para o chamador, use este método alternativo:
String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an activity, for instance
CallAgentOptions callAgentOptions = new CallAgentOptions();
callAgentOptions.setDisplayName("Alice Bob");
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential, callAgentOptions).get();
Fazer uma chamada
Para criar e iniciar uma chamada, você precisa chamar o método CallAgent.startCall()
e fornecer o Identifier
dos receptores da chamada.
Para ingressar em uma chamada de grupo, você precisa chamar o método CallAgent.join()
e fornecer o groupId. As IDs de grupo precisam estar no formato GUID ou UUID.
A criação e o início da chamada são síncronos. A instância de chamada permite que você assine todos os eventos na chamada.
Realize uma chamada 1:1 para um usuário
Para realizar uma chamada para outro usuário dos Serviços de Comunicação, invoque o método call
em callAgent
e passe um objeto com a chave communicationUserId
.
StartCallOptions startCallOptions = new StartCallOptions();
Context appContext = this.getApplicationContext();
CommunicationUserIdentifier acsUserId = new CommunicationUserIdentifier(<USER_ID>);
CommunicationUserIdentifier participants[] = new CommunicationUserIdentifier[]{ acsUserId };
call oneToOneCall = callAgent.startCall(appContext, participants, startCallOptions);
Realizar uma chamada 1:n com usuários e PSTN
Observação
Verifique os detalhes da oferta de chamadas PSTN. Para obter acesso ao programa de versão prévia, inscreva-se no programa de usuário pioneiro.
Para realizar uma chamada 1:n para um usuário e um número de PSTN, você precisa especificar o número de telefone do receptor da chamada. O recurso Serviços de Comunicação precisa estar configurado para permitir a chamada PSTN:
CommunicationUserIdentifier acsUser1 = new CommunicationUserIdentifier(<USER_ID>);
PhoneNumberIdentifier acsUser2 = new PhoneNumberIdentifier("<PHONE_NUMBER>");
CommunicationIdentifier participants[] = new CommunicationIdentifier[]{ acsUser1, acsUser2 };
StartCallOptions startCallOptions = new StartCallOptions();
Context appContext = this.getApplicationContext();
Call groupCall = callAgent.startCall(participants, startCallOptions);
Aceitar uma chamada
Para aceitar uma chamada, chame o método 'accept' em um objeto de chamada.
Context appContext = this.getApplicationContext();
IncomingCall incomingCall = retrieveIncomingCall();
Call call = incomingCall.accept(context).get();
Para aceitar uma chamada com a câmera de vídeo ligada:
Context appContext = this.getApplicationContext();
IncomingCall incomingCall = retrieveIncomingCall();
AcceptCallOptions acceptCallOptions = new AcceptCallOptions();
VideoDeviceInfo desiredCamera = callClient.getDeviceManager().get().getCameraList().get(0);
acceptCallOptions.setVideoOptions(new VideoOptions(new LocalVideoStream(desiredCamera, appContext)));
Call call = incomingCall.accept(context, acceptCallOptions).get();
A chamada de entrada pode ser obtida assinando o evento onIncomingCall
no objeto callAgent
:
// Assuming "callAgent" is an instance property obtained by calling the 'createCallAgent' method on CallClient instance
public Call retrieveIncomingCall() {
IncomingCall incomingCall;
callAgent.addOnIncomingCallListener(new IncomingCallListener() {
void onIncomingCall(IncomingCall inboundCall) {
// Look for incoming call
incomingCall = inboundCall;
}
});
return incomingCall;
}
Ingressar em uma chamada de sala
Use o CallAgent
e RoomCallLocator
para ingressar em uma chamada de sala especificando um roomId
. O método CallAgent.join
retornará um objeto Call
:
val roomCallLocator = RoomCallLocator(roomId)
call = callAgent.join(applicationContext, roomCallLocator, joinCallOptions)
Uma room
oferece aos desenvolvedores de aplicativos um controle melhor sobre quem pode ingressar em uma chamada, quando eles se encontram e como eles colaboram. Para saber mais sobre o rooms
, leia a documentação conceitual ou siga a guia de início rápido.
Ingressar em um grupo
Para iniciar uma nova chamada em grupo ou ingressar em uma chamada em grupo em andamento, chame o método 'join' e passe um objeto com uma propriedade groupId
. O valor deve ser um GUID.
Context appContext = this.getApplicationContext();
GroupCallLocator groupCallLocator = new GroupCallLocator("<GUID>");
JoinCallOptions joinCallOptions = new JoinCallOptions();
call = callAgent.join(context, groupCallLocator, joinCallOptions);
Propriedades da chamada
Obtenha a ID exclusiva desta chamada:
String callId = call.getId();
Para saber mais sobre outros participantes na chamada, inspecione a coleção remoteParticipant
na instância call
:
List<RemoteParticipant> remoteParticipants = call.getRemoteParticipants();
A identidade do chamador se a chamada for de entrada:
CommunicationIdentifier callerId = call.getCallerInfo().getIdentifier();
Obtenha o estado da chamada:
CallState callState = call.getState();
Isso retorna uma cadeia de caracteres que representa o estado atual de uma chamada:
- 'NONE' - Estado da chamada inicial
- 'EARLY_MEDIA' - Indica um estado no qual um comunicado é reproduzido antes de a chamada ser conectada
- 'CONNECTING' - Estado de transição inicial depois que a chamada é feita ou aceita
- 'RINGING' – Em uma chamada de saída, indica para os participantes remotos que a chamada está tocando
- 'CONNECTED' – A chamada está conectada
- 'LOCAL_HOLD' – A chamada é colocada em espera pelo participante local, nenhuma mídia está sendo transmitida entre o ponto de extremidade local e os participantes remotos
- 'REMOTE_HOLD' – A chamada é colocada em espera por um participante remoto, nenhuma mídia está sendo transmitida entre o ponto de extremidade local e os participantes remotos
- 'DISCONNECTING' – Estado de transição antes que a chamada vá para o estado 'Disconnected'
- 'DISCONNECTED' – Estado final da chamada
- 'IN_LOBBY' – No lobby para uma interoperabilidade de reuniões do Teams
Para saber por que uma chamada terminou, inspecione a propriedade callEndReason
. Ela contém o código/subcódigo:
CallEndReason callEndReason = call.getCallEndReason();
int code = callEndReason.getCode();
int subCode = callEndReason.getSubCode();
Para ver se a chamada atual é uma chamada de entrada ou de saída, inspecione a propriedade callDirection
:
CallDirection callDirection = call.getCallDirection();
// callDirection == CallDirection.INCOMING for incoming call
// callDirection == CallDirection.OUTGOING for outgoing call
Para ver se o microfone atual está no mudo, inspecione a propriedade muted
:
boolean muted = call.isMuted();
Para inspecionar os fluxos de vídeo ativos, verifique a coleção localVideoStreams
:
List<LocalVideoStream> localVideoStreams = call.getLocalVideoStreams();
Ativar e desativar mudo
Para ativar ou desativar o mudo no ponto de extremidade local, você pode usar as APIs mute
e unmute
assíncronas:
Context appContext = this.getApplicationContext();
call.mute(appContext).get();
call.unmute(appContext).get();
Alterar o volume da chamada
Enquanto você estiver em uma chamada, as chaves de volume de hardware no telefone devem permitir que o usuário altere o volume de chamada.
Isso é feito usando o método setVolumeControlStream
com o tipo de fluxo AudioManager.STREAM_VOICE_CALL
na Atividade em que a chamada está sendo colocada.
Isso permite que as chaves de volume de hardware alterem o volume da chamada (anotado por um ícone de telefone ou algo semelhante no controle deslizante do volume), impedindo a alteração do volume para outros perfis de som, como alarmes, mídia ou volume de todo o sistema. Para obter mais informações, você pode verificar Tratando alterações na saída de áudio | Desenvolvedores do Android.
@Override
protected void onCreate(Bundle savedInstanceState) {
...
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
}
Gerenciamento de participantes remotos
Todos os participantes remotos são representados pelo tipo RemoteParticipant
e estão disponíveis por meio da coleção remoteParticipants
em uma instância de chamada.
Listar os participantes em uma chamada
A coleção remoteParticipants
retorna uma lista de participantes remotos na chamada fornecida:
List<RemoteParticipant> remoteParticipants = call.getRemoteParticipants(); // [remoteParticipant, remoteParticipant....]
Adicionar um participante a uma chamada
Para adicionar um participante a uma chamada (um usuário ou um número de telefone), você pode invocar addParticipant
.
Isso retornará de modo síncrono a instância do participante remoto.
const acsUser = new CommunicationUserIdentifier("<acs user id>");
const acsPhone = new PhoneNumberIdentifier("<phone number>");
RemoteParticipant remoteParticipant1 = call.addParticipant(acsUser);
AddPhoneNumberOptions addPhoneNumberOptions = new AddPhoneNumberOptions(new PhoneNumberIdentifier("<alternate phone number>"));
RemoteParticipant remoteParticipant2 = call.addParticipant(acsPhone, addPhoneNumberOptions);
Remover um participante de uma chamada
Para remover um participante de uma chamada (um usuário ou um número de telefone), você pode invocar removeParticipant
.
Isso será resolvido de modo assíncrono quando o participante for removido da chamada.
O participante também será removido da coleção remoteParticipants
.
RemoteParticipant acsUserRemoteParticipant = call.getParticipants().get(0);
RemoteParticipant acsPhoneRemoteParticipant = call.getParticipants().get(1);
call.removeParticipant(acsUserRemoteParticipant).get();
call.removeParticipant(acsPhoneRemoteParticipant).get();
Propriedades do participante remoto
Qualquer participante remoto tem um conjunto de propriedades e coleções associadas a ele:
Obtenha o identificador desse participante remoto. A identidade é um dos tipos de 'Identifier'
CommunicationIdentifier participantIdentifier = remoteParticipant.getIdentifier();
Obtém o estado deste participante remoto.
ParticipantState state = remoteParticipant.getState();
O estado pode ser um dos seguintes
'IDLE' – Estado inicial
'EARLY_MEDIA' – O comunicado é reproduzido antes de o participante estar conectado à chamada
'RINGING' – A chamada do participante está tocando
'CONNECTING' – Estado de transição enquanto o participante está se conectando à chamada
'CONNECTED' – O participante está conectado à chamada
'HOLD' – O participante está em espera
'IN_LOBBY' – O participante está aguardando no lobby ser admitido. Atualmente, ele usado somente no cenário de interoperabilidade do Teams
'DISCONNECTED' – O estado final, em que o participante está desconectado da chamada
Para saber por que um participante saiu da chamada, inspecione a propriedade
callEndReason
:CallEndReason callEndReason = remoteParticipant.getCallEndReason();
Para verificar se esse participante remoto está com o mudo ativado ou não, inspecione a propriedade
isMuted
:boolean isParticipantMuted = remoteParticipant.isMuted();
Para verificar se esse participante remoto está falando ou não, inspecione a propriedade
isSpeaking
:boolean isParticipantSpeaking = remoteParticipant.isSpeaking();
Para inspecionar todos os fluxos de vídeo que um determinado participante está enviando nesta chamada, verifique a coleção
videoStreams
:List<RemoteVideoStream> videoStreams = remoteParticipant.getVideoStreams(); // [RemoteVideoStream, RemoteVideoStream, ...]
Ativar mudo para outros participantes
Observação
Para usar esta API, use o SDK do Android de Chamada dos Serviços de Comunicação do Azure versão 2.11.0 ou superior.
Para ativar o mudo de todos os outros participantes em uma chamada, use a API muteAllRemoteParticipants
na chamada.
call.muteAllRemoteParticipants();
Para ativar o mudo de um participante remoto específico, use a API mute
em um determinado participante remoto.
remoteParticipant.mute();
Para notificar o participante local de que ele foi silenciado por outras pessoas, assine o evento onMutedByOthers
.
Como usar os serviços em primeiro plano
Nos casos em que você quiser executar uma tarefa visível ao usuário, mesmo quando seu aplicativo estiver em segundo plano, você poderá usar os Serviços em primeiro plano.
Com os Serviços em primeiro plano, você pode, por exemplo, manter uma notificação visível ao usuário quando o aplicativo estiver em uma chamada ativa. Dessa forma, mesmo que o usuário vá para a tela inicial ou remova o aplicativo da tela do recente, a chamada continuará ativa.
Se você não usar um Serviço em primeiro plano enquanto estiver em uma chamada, navegar até a tela inicial poderá manter a chamada ativa, mas a remoção do aplicativo da tela recente poderá interromper a chamada se o sistema operacional Android eliminar o processo do aplicativo.
Inicie o Serviço em primeiro plano ao iniciar/ingressar em uma chamada, por exemplo:
call = callAgent.startCall(context, participants, options);
startService(yourForegroundServiceIntent);
E pare o Serviço em primeiro plano quando desligar a chamada ou o status da chamada for Desconectado, por exemplo:
call.hangUp(new HangUpOptions()).get();
stopService(yourForegroundServiceIntent);
Observações sobre o uso dos Serviços em primeiro plano
Saiba que, em certos cenários, por exemplo, a interrupção de um Serviço em primeiro plano já em execução quando o aplicativo é removido da lista de recentes, a notificação visível ao usuário será removido e o sistema operacional Android poderá manter o processo do aplicativo ativo por um período de tempo extra, o que significa que a chamada ainda pode estar ativa durante esse período.
Se o aplicativo estiver parando o Serviço em primeiro plano no método onTaskRemoved
do serviço, por exemplo, seu aplicativo poderá iniciar/parar o áudio e o vídeo de acordo com o ciclo de vida da atividade, como parar o áudio e o vídeo quando a atividade é destruída com a substituição do método onDestroy
.
Configurar o backup do sistema
Siga essas etapas para configurar seu sistema.
Criar o projeto do Xcode
No Xcode, crie um projeto do iOS e selecione o modelo Aplicativo de Modo de Exibição Único. Como este artigo usa a estrutura SwiftUI, defina Linguagem como Swift e Interface como SwiftUI.
Você não criará testes neste artigo. Fique à vontade para limpar a caixa de seleção Incluir Testes.
Instalar o pacote e as dependências usando o CocoaPods
Crie um Podfile para seu aplicativo, como este exemplo:
platform :ios, '13.0' use_frameworks! target 'AzureCommunicationCallingSample' do pod 'AzureCommunicationCalling', '~> 1.0.0' end
Execute
pod install
.Abra o
.xcworkspace
usando o Xcode.
Solicitar acesso ao microfone
Para acessar o microfone do dispositivo, você precisa atualizar a lista de propriedades de informações do aplicativo usando NSMicrophoneUsageDescription
. Defina o valor associado como uma cadeia de caracteres incluída na caixa de diálogo que é usada pelo sistema para solicitar o acesso do usuário.
Clique com o botão direito do mouse na entrada Info.plist da árvore de projeto e selecione Abrir Como>Código-Fonte. Adicione as linhas a seguir na seção do nível superior<dict>
e, em seguida, salve o arquivo.
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>
Configurar o framework de aplicativos
Abra o arquivo ContentView.swift
do projeto. Adicione uma declaração import
à parte superior do arquivo para importar a biblioteca AzureCommunicationCalling
. Além disso, importeAVFoundation
. Você precisa dele para solicitações de permissão de áudio no código.
import AzureCommunicationCalling
import AVFoundation
Inicialização do CallAgent
Para criar umaCallAgent
instânciaCallClient
,você precisa usar um método callClient.createCallAgent
que retorne de modo assíncrono um objetoCallAgent
depois que ele for inicializado.
Para criar um cliente de chamada, passe um objeto CommunicationTokenCredential
:
import AzureCommunication
let tokenString = "token_string"
var userCredential: CommunicationTokenCredential?
do {
let options = CommunicationTokenRefreshOptions(initialToken: token, refreshProactively: true, tokenRefresher: self.fetchTokenSync)
userCredential = try CommunicationTokenCredential(withOptions: options)
} catch {
updates("Couldn't created Credential object", false)
initializationDispatchGroup!.leave()
return
}
// tokenProvider needs to be implemented by Contoso, which fetches a new token
public func fetchTokenSync(then onCompletion: TokenRefreshOnCompletion) {
let newToken = self.tokenProvider!.fetchNewToken()
onCompletion(newToken, nil)
}
Passe o objeto CommunicationTokenCredential
que você criou para CallClient
e defina o nome de exibição:
self.callClient = CallClient()
let callAgentOptions = CallAgentOptions()
options.displayName = " iOS Azure Communication Services User"
self.callClient!.createCallAgent(userCredential: userCredential!,
options: callAgentOptions) { (callAgent, error) in
if error == nil {
print("Create agent succeeded")
self.callAgent = callAgent
} else {
print("Create agent failed")
}
})
Observação
Ao implementar representantes de evento do aplicativo, o aplicativo precisa manter uma referência forte aos objetos que exigem assinaturas de evento. Por exemplo, quando um objeto RemoteParticipant
é retornado ao invocar o método call.addParticipant
e o aplicativo define o delegado a ser escutado em RemoteParticipantDelegate
, o aplicativo precisa manter uma referência forte ao objeto RemoteParticipant
. Caso contrário, se esse objeto for coletado, o representante lançará uma exceção do erro catastrófico quando o SDK da chamada tentar a invocação de plataforma do objeto.
Realizar uma chamada de saída
Para criar e iniciar uma chamada, você precisa chamar uma das APIs noCallAgent
e fornecer a Identidade dos Serviços de Comunicação de um usuário que você provisionou usando o SDK de Gerenciamento dos Serviços de Comunicação.
A criação e o início da chamada são síncronos. Você receberá uma instância da chamada que permite assinar todos os eventos da chamada.
Realizar uma chamada 1:1 para um usuário ou uma chamada 1:n com usuários e PSTN
let callees = [CommunicationUser(identifier: 'UserId')]
self.callAgent?.startCall(participants: callees, options: StartCallOptions()) { (call, error) in
if error == nil {
print("Successfully started outgoing call")
self.call = call
} else {
print("Failed to start outgoing call")
}
}
Realizar uma chamada 1:n com usuários e PSTN
Observação
Verifique os detalhes da oferta de chamadas PSTN. Para obter acesso ao programa de versão prévia, inscreva-se no programa de usuário pioneiro.
Para identificar a chamada do PSTN, você precisa especificar o número de telefone adquirido com os Serviços de Comunicação do Azure.
let pstnCallee = PhoneNumberIdentifier(phoneNumber: '+1999999999')
let callee = CommunicationUserIdentifier('UserId')
self.callAgent?.startCall(participants: [pstnCallee, callee], options: StartCallOptions()) { (groupCall, error) in
if error == nil {
print("Successfully started outgoing call to multiple participants")
self.call = groupCall
} else {
print("Failed to start outgoing call to multiple participants")
}
}
Ingressar em uma chamada de sala
Para ingressar em uma chamada room
, especifique a propriedade roomId
como o identificador room
. Para ingressar na chamada, use o método de join
e passe a roomCallLocator
.
func joinRoomCall() {
if self.callAgent == nil {
print("CallAgent not initialized")
return
}
if (self.roomId.isEmpty) {
print("Room ID not set")
return
}
// Join a call with a Room ID
let options = JoinCallOptions()
let audioOptions = AudioOptions()
audioOptions.muted = self.muted
options.audioOptions = audioOptions
let roomCallLocator = RoomCallLocator(roomId: roomId)
self.callAgent!.join(with: roomCallLocator, joinCallOptions: options) { (call, error) in
self.setCallAndObserver(call: call, error: error)
}
}
Uma room
oferece aos desenvolvedores de aplicativos um controle melhor sobre quem pode ingressar em uma chamada, quando eles se encontram e como eles colaboram. Para saber mais sobre o rooms
, leia a documentação conceitual ou siga a guia de início rápido.
Ingressar em um grupo
Para ingressar em uma chamada, você precisa chamar uma das APIsCallAgent
.
let groupCallLocator = GroupCallLocator(groupId: UUID(uuidString: "uuid_string")!)
self.callAgent?.join(with: groupCallLocator, joinCallOptions: JoinCallOptions()) { (call, error) in
if error == nil {
print("Successfully joined group call")
self.call = call
} else {
print("Failed to join group call")
}
}
Assinar a chamada de entrada
Assinar o evento da chamada de entrada.
final class IncomingCallHandler: NSObject, CallAgentDelegate, IncomingCallDelegate
{
// Event raised when there is an incoming call
public func callAgent(_ callAgent: CallAgent, didReceiveIncomingCall incomingcall: IncomingCall) {
self.incomingCall = incomingcall
// Subscribe to get OnCallEnded event
self.incomingCall?.delegate = self
}
// Event raised when incoming call was not answered
public func incomingCall(_ incomingCall: IncomingCall, didEnd args: PropertyChangedEventArgs) {
print("Incoming call was not answered")
self.incomingCall = nil
}
}
Aceitar uma chamada de entrada
Para aceitar uma chamada, chame o método accept
em um objeto IncomingCall
.
self.incomingCall!.accept(options: AcceptCallOptions()) { (call, error) in
if (error == nil) {
print("Successfully accepted incoming call")
self.call = call
} else {
print("Failed to accept incoming call")
}
}
let firstCamera: VideoDeviceInfo? = self.deviceManager!.cameras.first
localVideoStreams = [LocalVideoStream]()
localVideoStreams!.append(LocalVideoStream(camera: firstCamera!))
let acceptCallOptions = AcceptCallOptions()
acceptCallOptions.videoOptions = VideoOptions(localVideoStreams: localVideoStreams!)
if let incomingCall = self.incomingCall {
incomingCall.accept(options: acceptCallOptions) { (call, error) in
if error == nil {
print("Incoming call accepted")
} else {
print("Failed to accept incoming call")
}
}
} else {
print("No incoming call found to accept")
}
Executar as operações de chamada média
Você pode executar várias operações durante uma chamada para gerenciar as configurações relacionadas ao vídeo e ao áudio.
Ativar e desativar mudo
Para ativar ou desativar o mudo no ponto de extremidade local, você pode usar as APIsmute
eunmute
assíncronas.
call!.mute { (error) in
if error == nil {
print("Successfully muted")
} else {
print("Failed to mute")
}
}
Use o código a seguir para desativar o local do ponto de extremidade de forma assíncrona.
call!.unmute { (error) in
if error == nil {
print("Successfully un-muted")
} else {
print("Failed to unmute")
}
}
Gerenciar os participantes remotos
Todos os participantes remotos são representados peloRemoteParticipant
e estão disponíveis por meio daremoteParticipants
coleção em uma instância de chamada.
Listar os participantes em uma chamada
call.remoteParticipants
Adicionar um participante a uma chamada
Para adicionar um participante a uma chamada (um usuário ou um número de telefone), você pode invocar da plataformaaddParticipant
. Esta janela de Comando retornará de modo síncrono uma instância do participante remoto.
let remoteParticipantAdded: RemoteParticipant = call.add(participant: CommunicationUserIdentifier(identifier: "userId"))
Remover um participante de uma chamada
Para remover um participante de uma chamada (um usuário ou um número de telefone),você pode invocar da plataforma aremoveParticipant
API. Isso será resolvido de modo assíncrono.
call!.remove(participant: remoteParticipantAdded) { (error) in
if (error == nil) {
print("Successfully removed participant")
} else {
print("Failed to remove participant")
}
}
Obter as propriedades do participante remoto
// [RemoteParticipantDelegate] delegate - an object you provide to receive events from this RemoteParticipant instance
var remoteParticipantDelegate = remoteParticipant.delegate
// [CommunicationIdentifier] identity - same as the one used to provision a token for another user
var identity = remoteParticipant.identifier
// ParticipantStateIdle = 0, ParticipantStateEarlyMedia = 1, ParticipantStateConnecting = 2, ParticipantStateConnected = 3, ParticipantStateOnHold = 4, ParticipantStateInLobby = 5, ParticipantStateDisconnected = 6
var state = remoteParticipant.state
// [Error] callEndReason - reason why participant left the call, contains code/subcode/message
var callEndReason = remoteParticipant.callEndReason
// [Bool] isMuted - indicating if participant is muted
var isMuted = remoteParticipant.isMuted
// [Bool] isSpeaking - indicating if participant is currently speaking
var isSpeaking = remoteParticipant.isSpeaking
// RemoteVideoStream[] - collection of video streams this participants has
var videoStreams = remoteParticipant.videoStreams // [RemoteVideoStream, RemoteVideoStream, ...]
Ativar mudo para outros participantes
Observação
Para usar essa API, use o SDK do iOS de Chamada dos Serviços de Comunicação do Azure versão 2.13.0 ou superior.
Para ativar o mudo de todos os outros participantes em uma chamada, use a API muteAllRemoteParticipants
na chamada.
call!.muteAllRemoteParticipants { (error) in
if error == nil {
print("Successfully muted all remote participants.")
} else {
print("Failed to mute remote participants.")
}
}
Para ativar o mudo de um participante remoto específico, use a API mute
em um determinado participante remoto.
remoteParticipant.mute { (error) in
if error == nil {
print("Successfully muted participant.")
} else {
print("Failed to mute participant.")
}
}
Para notificar o participante local de que ele foi silenciado por outras pessoas, assine o evento onMutedByOthers
.
Configurar o backup do sistema
Siga essas etapas para configurar seu sistema.
Criar o projeto do Visual Studio
Para um aplicativo da Plataforma Universal do Windows, no Visual Studio 2022, crie um projeto de Aplicativo em branco (Universal do Windows). Depois de inserir o nome do projeto, fique à vontade para escolher qualquer SDK do Windows posterior a 10.0.17763.0.
Para um aplicativo WinUI 3, crie um novo projeto com o modelo Aplicativo em Branco, Empacotado (WinUI 3 na Área de Trabalho) para configurar um aplicativo WinUI 3 de página única. O SDK do Aplicativo do Windows versão 1.3 ou posterior é necessário.
Instalar o pacote e as dependências usando o Gerenciador de Pacotes do NuGet
As bibliotecas e as APIs do SDK de Chamada estão disponíveis publicamente por meio de um pacote NuGet.
Para localizar, baixar e instalar o pacote NuGet do SDK de Chamada, faça o seguinte:
- Abra o Gerenciador de Pacotes do NuGet selecionando Ferramentas>Gerenciador de Pacotes do NuGet>Gerenciar de Pacotes do NuGet para Solução.
- Selecione Procurar e insira Azure.Communication.Calling.WindowsClient na caixa de pesquisa.
- Verifique se a caixa de seleção Incluir pré-lançamento está marcada.
- Selecione o pacote Azure.Communication.Calling.WindowsClient e Azure.Communication.Calling.WindowsClient 1.4.0-beta.1 ou uma versão mais recente.
- Marque a caixa de seleção que corresponde ao projeto dos Serviços de Comunicação do Azure no painel direito.
- Selecione Instalar.
Solicitar acesso ao microfone
O aplicativo precisará de acesso ao microfone para ser executado corretamente. Em aplicativos UWP, a capacidade do microfone deve ser declarada no arquivo de manifesto do aplicativo.
As etapas a seguir exemplificam como fazer isso.
- No painel
Solution Explorer
, clique duas vezes no arquivo com a extensão.appxmanifest
. - Clique na guia
Capabilities
. - Marque a caixa de seleção
Microphone
na lista de recursos.
Criar botões de interface do usuário para iniciar e desligar a chamada
Este aplicativo de exemplo simples contém dois botões. Um para iniciar a chamada e outro para desligar uma chamada iniciada. As etapas a seguir exemplificam como adicionar esses botões ao aplicativo.
- No painel
Solution Explorer
, clique duas vezes no arquivo nomeadoMainPage.xaml
para UWP ouMainWindows.xaml
para WinUI 3. - No painel central, procure o código XAML na versão prévia da interface do usuário.
- Modifique o código XAML conforme o trecho a seguir:
<TextBox x:Name="CalleeTextBox" PlaceholderText="Who would you like to call?" />
<StackPanel>
<Button x:Name="CallButton" Content="Start/Join call" Click="CallButton_Click" />
<Button x:Name="HangupButton" Content="Hang up" Click="HangupButton_Click" />
</StackPanel>
Configuração do aplicativo com APIs do SDK de chamada
As APIs do SDK de chamada estão em dois namespaces diferentes. As etapas a seguir informam ao compilador C# sobre esses namespaces que permitem que o Intellisense do Visual Studio auxilie no desenvolvimento de código.
- No painel
Solution Explorer
, clique na seta ao lado esquerdo do arquivo nomeadoMainPage.xaml
for UWP ouMainWindows.xaml
para WinUI 3. - Clique duas vezes no arquivo nomeado
MainPage.xaml.cs
ouMainWindows.xaml.cs
. - Adicione os comandos a seguir na parte inferior das instruções
using
atuais.
using Azure.Communication.Calling.WindowsClient;
Mantenha MainPage.xaml.cs
ou MainWindows.xaml.cs
aberto. As próximas etapas adicionarão mais código a ele.
Permitir interações de aplicativo
Os botões da interface do usuário adicionados anteriormente precisam operar por cima de um CommunicationCall
iniciado. Isso significa que um membro de dados CommunicationCall
deve ser adicionado à classe MainPage
ou MainWindow
.
Além disso, para permitir que a operação assíncrona criando CallAgent
seja bem-sucedida, um membro de dados CallAgent
também deve ser adicionado à mesma classe.
Adicione os seguintes membros de dados à classe MainPage
ou MainWindow
:
CallAgent callAgent;
CommunicationCall call;
Criar identificadores de botão
Anteriormente, dois botões de interface do usuário foram adicionados ao código XAML. O código a seguir adiciona os manipuladores a serem executados quando um usuário seleciona o botão. O código a seguir deve ser adicionado depois dos membros de dados da seção anterior.
private async void CallButton_Click(object sender, RoutedEventArgs e)
{
// Start call
}
private async void HangupButton_Click(object sender, RoutedEventArgs e)
{
// End the current call
}
Modelo de objeto
As classes e as interfaces a seguir administram alguns dos principais recursos da biblioteca de clientes de Chamada dos Serviços de Comunicação do Azure para UWP.
Nome | Descrição |
---|---|
CallClient |
O CallClient é o ponto de entrada principal para a biblioteca de clientes de Chamada. |
CallAgent |
O CallAgent é usado para iniciar e ingressar em chamadas. |
CommunicationCall |
O CommunicationCall é usado para gerenciar chamadas iniciadas ou ingressadas. |
CommunicationTokenCredential |
O CommunicationTokenCredential é usado como a credencial de token de segurança para criar uma instância CallAgent . |
CallAgentOptions |
O CallAgentOptions contém informações para identificar o chamador. |
HangupOptions |
O HangupOptions informa se uma chamada deve ser encerrada para todos os participantes. |
Inicializar o CallAgent
Para criar uma instância CallAgent
de CallClient
, você deve usar o método CallClient.CreateCallAgentAsync
que retorna de forma assíncrona um objeto CallAgent
quando ele for inicializado.
Para criar CallAgent
, você deve passar um objeto CallTokenCredential
e um objeto CallAgentOptions
. Tenha em mente que CallTokenCredential
é lançado se um token malformado for passado.
O código a seguir deve ser inserido e a função auxiliar a ser chamada na inicialização do aplicativo.
var callClient = new CallClient();
this.deviceManager = await callClient.GetDeviceManagerAsync();
var tokenCredential = new CallTokenCredential("<AUTHENTICATION_TOKEN>");
var callAgentOptions = new CallAgentOptions()
{
DisplayName = "<DISPLAY_NAME>"
};
this.callAgent = await callClient.CreateCallAgentAsync(tokenCredential, callAgentOptions);
Altere o <AUTHENTICATION_TOKEN>
com um token de credencial válido para o recurso. Consulte a documentação do token de acesso do usuário se um token de credencial precisar ser originado.
Criar CallAgent e fazer uma chamada
Os objetos necessários para criar um CallAgent
estão agora prontos. É hora de criar CallAgent
de forma assíncrona e fazer uma chamada.
O código a seguir deve ser adicionado após a manipulação da exceção da etapa anterior.
var startCallOptions = new StartCallOptions();
var callees = new [] { new UserCallIdentifier(CalleeTextBox.Text.Trim()) };
this.call = await this.callAgent.StartCallAsync(callees, startCallOptions);
this.call.OnStateChanged += Call_OnStateChangedAsync;
Fique à vontade para usar 8:echo123
e conversar com o bot de eco dos Serviços de Comunicação do Azure.
Ativar mudo e desativar mudo
Para ativar ou desativar o mudo do áudio de saída, você pode usar as APIs assíncronas MuteOutgoingAudioAsync
e UnmuteOutgoingAudioAsync
:
// mute outgoing audio
await this.call.MuteOutgoingAudioAsync();
// unmute outgoing audio
await this.call.UnmuteOutgoingAudioAsync();
Ativar mudo para outros participantes
Observação
Para usar essa API, use o SDK do Windows de Chamada dos Serviços de Comunicação do Azure versão 1.9.0 ou superior.
Para ativar mudo de todos os outros participantes ou ativar mudo de um participante específico, use as APIs MuteAllRemoteParticipantsAsync
assíncronas na chamada e MuteAsync
no participante remoto:
// mute all participants except yourself
await this.call.MuteAllRemoteParticipantsAsync();
// mute specific participant in the call
await this.call.RemoteParticipants.FirstOrDefault().MuteAsync();
Para notificar o participante local de que ele foi silenciado por outras pessoas, assine o evento MutedByOthers
.
Encerrar uma chamada
Depois que uma chamada for iniciada, o método HangupAsync
do objeto CommunicationCall
deve ser usado para desligar a chamada.
Uma instância do HangupOptions
também deve ser usada para informar se a chamada deve ser encerrada para todos os seus participantes.
O código a seguir deve ser adicionado dentro do HangupButton_Click
.
this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions() { ForEveryone = false });
Executar o código
Verifique se o Visual Studio criará o aplicativo para x64
, x86
ou ARM64
e clique em F5
para iniciar a execução do aplicativo. Depois, clique no botão Call
para fazer uma chamada para o receptor definido.
Tenha em mente que, na primeira vez que o aplicativo for executado, o sistema solicitará que o usuário conceda acesso ao microfone.