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

Instalar o SDK

Use o comando npm install para instalar os SDKs Comuns 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. Aqui, você cria uma nova instância CallClient. Você pode configurá-la com opções personalizadas, como uma instância Logger.

Quando você tem uma CallClient instância, é possível criar uma CallAgent instância, chamando o createCallAgentmétodo na instância CallClient. 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()

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.

Ao iniciar, ingressar ou aceitar uma chamada com vídeo ativado, se a câmera estiver sendo usada por outro processo ou se estiver desabilitada no sistema operacional, a chamada começará com o vídeo desativado e um diagnóstico de chamada cameraStartFailed: true será gerado.

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 for resolvida, o estado da chamada será definido como LocalHold. Se for uma chamada 1:1, o outro participante também será colocado em espera e o estado da chamada da perspectiva desse participante será definido como 'RemoteHold'. O outro participante pode colocar ainda mais sua chamada em espera, o que resultaria em uma alteração de estado para LocalHold. Se esta for uma chamada em grupo, o hold é apenas uma operação local, não irá colocar a chamada em espera para outros participantes dessa chamada. Para retomar totalmente essa chamada, todos os usuários que iniciaram a retenção devem retomá-la.

Para retomar a chamada em espera:

await call.resume();

Quando a API resume for resolvida, o estado de chamada será 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 unmuteassí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 receberá o áudio da chamada (áudio do participante remoto). O áudio da chamada não será ouvido no alto-falante e o participante não poderá ouvir até que ''call.unmuteIncomingAudio()'' seja chamado. No entanto, podemos aplicar filtro no áudio de chamada e reproduzir o áudio filtrado.

Ativar mudo para outros participantes

Observação

Esta API é fornecida como uma versão prévia para desenvolvedores e pode ser alterada com base nos comentários que recebemos. Para usar esta API, use a versão ''beta'' do SDK da Web de Chamada dos Serviços de Comunicação do Azure versão 1.18.1 ou superior.

Para ativar mudo de todos os outros participantes ou ativar mudo de um participante específico, use as APIs muteAllRemoteParticipants assíncronas na chamada e mute no participante remoto:

//mute all participants except yourself
await call.muteAllRemoteParticipants();

//mute a specific participant
await call.remoteParticipants[0].mute();

Gerenciar participantes remotos

Todos os participantes remotos são detalhados na API 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:

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 remoteParticipant = call.addParticipant(pstnIdentifier, {alternateCallerId: '<ALTERNATE_CALLER_ID>'});

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á para Disconnected depois de dois minutos.
  • callEndReason: Para saber por que um participante saiu da chamada, verifique a propriedade callEndReason:

    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, por exemplo, o UserB retira o UserC, da perspectiva do UserA, o UserA não verá esse sinalizador ser definido para o UserC. Em outras palavras, o UserA não verá a propriedade callEndReason do UserC ser definida.
  • isMuted status: para descobrir se um participante remoto está com o mudo ativado, verifique a propriedade isMuted. Ele retorna Boolean.

    const isMuted = remoteParticipant.isMuted;
    
  • isSpeaking status: para descobrir se um participante remoto está falando, verifique a propriedade isSpeaking. Ele retorna Boolean.

    const isSpeaking = remoteParticipant.isSpeaking;
    
  • videoStreams: Para inspecionar todos os fluxos de vídeo que um determinado participante está enviando nesta chamada, verifique a coleção videoStreams. Ele contém objetos RemoteVideoStream.

    const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
    
  • displayName: Para obter o nome de exibição para este participante remoto, inspecione a propriedade displayName que ele retorna String.

    const displayName = remoteParticipant.displayName;
    
  • endpointDetails: obtenha os detalhes de todos os pontos de extremidade deste participante remoto

        const endpointDetails: EndpointDetails[] = remoteParticipant.endpointDetails;
    

    Observação: um participante remoto pode estar na chamada de muitos pontos de extremidade e cada ponto de extremidade terá seu próprio participantId exclusivo. participantId é diferente da ID bruta do RemoteParticipant.identifier.

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 da Web em muitos pontos de extremidade e cada ponto de extremidade terá seu próprio participantIdexclusivo. 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 a chamada é colocada em espera por um participante local. Nenhuma mídia está fluindo entre o ponto de extremidade local e os participantes remotos.
  • RemoteHold: Indica que a chamada foi colocada em espera pelo participante remoto. 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 estado Disconnected.
  • Disconnected: Estado da chamada final. Se a conexão de rede for perdida, o estado será alterado para Disconnected depois de dois minutos.

Descubra por que uma chamada terminou inspecionando a Propriedade callEndReason:

const callEndReason = call.callEndReason;
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 ou 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 no 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 de 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();

Ativar mudo para outros participantes

Observação

Esta API é fornecida como uma visualização pública para desenvolvedores e pode ser alterada com base nos comentários que recebemos. Para usar essa API, use a versão ''beta'' do SDK do Android de Chamada dos Serviços de Comunicação do Azure versão 2.6.0-beta.5 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();

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, ...]
    

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

Criar o projeto do Xcode

No Xcode, crie um projeto do iOS e selecione o modelo Aplicativo de Modo de Exibição Único. Este início rápido usa a estrutura SwiftUI, portanto, você deve definir a Linguagem como Swift e a Interface como SwiftUI.

Você não criará testes durante este início rápido. Fique à vontade para limpar a caixa de seleção Incluir Testes.

Captura de tela que mostra a janela para a criação de um projeto no Xcode.

Instalar o pacote e as dependências usando o CocoaPods

  1. Crie um Podfile para seu aplicativo, como este exemplo:

    platform :ios, '13.0'
    use_frameworks!
    target 'AzureCommunicationCallingSample' do
        pod 'AzureCommunicationCalling', '~> 1.0.0'
    end
    
  2. Execute pod install.

  3. 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 a uma cadeia de caracteres que será incluída na caixa de diálogo que o sistema usa para solicitar 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ê precisará dela para as solicitações de permissão do áudio no código.

import AzureCommunicationCalling
import AVFoundation

Inicialização do CallAgent

Para criar umaCallAgentinstânciaCallClient,você precisa usar um método callClient.createCallAgentque retorne de modo assíncrono um objetoCallAgentdepois 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 noCallAgente 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 APIsmuteeunmuteassí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")
    }
}

Ativar mudo para outros participantes

Observação

Esta API é fornecida como uma visualização pública para desenvolvedores e pode ser alterada com base nos comentários que recebemos. Para usar essa API, use a versão ''beta'' do SDK do iOS de Chamada dos Serviços de Comunicação do Azure versão 2.7.0-beta.3 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.")
    }
}

Gerenciar os participantes remotos

Todos os participantes remotos são representados peloRemoteParticipante estão disponíveis por meio daremoteParticipantscoleçã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 aremoveParticipantAPI. 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, ...]

Configurar o backup do sistema

Criar o projeto do Visual Studio

Para um aplicativo UWP, no Visual Studio 2022, crie um novo projeto 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.

As etapas a seguir exemplificam como localizar, baixar e instalar o pacote do NuGet do SDK de chamada:

  1. Abra o Gerenciador de Pacotes do NuGet selecionando Ferramentas>Gerenciador de Pacotes do NuGet>Gerenciar de Pacotes do NuGet para Solução.
  2. Selecione Procurar e, em seguida, insira Azure.Communication.Calling.WindowsClient na caixa de pesquisa.
  3. Verifique se a caixa de seleção Incluir pré-lançamento está marcada.
  4. Selecione o pacote Azure.Communication.Calling.WindowsClient e selecione Azure.Communication.Calling.WindowsClient1.4.0-beta.1 ou uma versão mais recente.
  5. Marque a caixa de seleção que corresponde ao projeto dos Serviços de Comunicação na guia à direita.
  6. Selecione o botão 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.

  1. No painel Solution Explorer, clique duas vezes no arquivo com a extensão .appxmanifest.
  2. Clique na guia Capabilities.
  3. 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.

  1. No painel Solution Explorer, clique duas vezes no arquivo nomeado MainPage.xaml para UWP ou MainWindows.xaml para WinUI 3.
  2. No painel central, procure o código XAML na versão prévia da interface do usuário.
  3. 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.

  1. No painel Solution Explorer, clique na seta ao lado esquerdo do arquivo nomeado MainPage.xaml for UWP ou MainWindows.xaml para WinUI 3.
  2. Clique duas vezes no arquivo nomeado MainPage.xaml.cs ou MainWindows.xaml.cs.
  3. 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

Esta API é fornecida como uma visualização pública para desenvolvedores e pode ser alterada com base nos comentários que recebemos. Para usar essa API, use a versão ''beta'' do SDK do Windows de Chamada dos Serviços de Comunicação do Azure versão 1.4.0-beta.1 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();

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.

Próximas etapas