Partilhar via


Gerir chamadas

Saiba como gerenciar chamadas com os SDKs dos Serviços de Comunicação do Azure. Aprenderemos a fazer chamadas, gerenciar seus participantes e propriedades.

Pré-requisitos

Instale o SDK

Use o npm install comando para instalar o SDK de Chamada e Comum 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 CallClient instância é necessária para a maioria das operações de chamada. Ao criar uma nova CallClient instância, você pode configurá-la com opções personalizadas, como uma Logger instância.

Com a CallClient instância, você pode criar uma CallAgent instância chamando o createCallAgentarquivo . Esse método retorna de forma assíncrona um objeto de CallAgent instância.

O createCallAgent método usa CommunicationTokenCredential como argumento. Ele aceita um token de acesso de usuário.

Você pode usar o getDeviceManager método na CallClient instância para acessar deviceManagero .

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 Call Agent instância ajuda você a gerenciar chamadas (para ingressar ou iniciar chamadas). Para funcionar, seu SDK de chamada precisa se conectar à infraestrutura da Microsoft para receber notificações de chamadas recebidas e coordenar outros detalhes da chamada. O seu Call Agent tem dois estados possíveis:

Conectado - Um Call Agent valor connectionStatue significa que o SDK do Connected cliente está conectado e é capaz de receber notificações da infraestrutura da Microsoft.

Desconectado - Um Call Agent valor connectionStatue de Disconnected estados há um problema que está impedindo o SDK de se conectar corretamente. Call Agent devem ser recriados.

  • invalidToken: Se um token expirou ou é inválido Call Agent , a instância se desconecta com esse erro.
  • connectionIssue: Se houver um problema com o cliente se conectando à infrascture da Microsoft, depois de muitas tentativas Call Agent expõe o connectionIssue erro.

Você pode verificar se seu local Call Agent está conectado à infraestrutura da Microsoft inspecionando o valor atual da connectionState propriedade. Durante uma chamada ativa, você pode ouvir o connectionStateChanged evento para determinar se Call Agent muda do estado Conectado para 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 e callAgent forneça um usuário criado 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 call instância permite que você se inscreva para chamar eventos.

Fazer 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 e callAgent passe o do destinatário que você criou com a biblioteca de administração dos Serviços de CommunicationUserIdentifier Comunicação.

Para uma chamada "1:1" para 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 PSTN (rede telefônica pública comutada), use o startCall método e callAgent passe o PhoneNumberIdentifier. O recurso dos Serviços de Comunicação deve ser configurado para permitir chamadas PSTN.

Quando você chamar um número PSTN, especifique sua ID de chamador alternativa. Um ID de chamador alternativo é um número de telefone (baseado 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 recebida.

Nota

Verifique os detalhes da oferta de chamadas RTPC. Para acesso ao programa de pré-visualização, candidate-se ao programa de adoção antecipada.

Para uma chamada 1:1 para 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 para 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 });

Participe de uma chamada de sala

Para ingressar em uma room chamada, você pode instanciar um objeto de contexto com a roomId propriedade como room identificador. Para ingressar na chamada, use o join método e passe a instância de contexto.

const context = { roomId: '<RoomId>' }
const call = callAgent.join(context);

A room oferece aos desenvolvedores de aplicativos um melhor controle sobre quem pode participar de uma chamada, quando eles se encontram e como eles colaboram. Para saber mais sobre roomso , você pode ler a documentação conceitual ou seguir o guia de início rápido.

Participar numa chamada de grupo

Nota

O groupId parâmetro é 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 groupId valor. A Microsoft não trata esse parâmetro como dados pessoais e seu conteúdo pode ser visível para os funcionários da Microsoft ou armazenado a longo prazo.

O groupId parâmetro requer que os dados estejam no formato GUID. Recomendamos o uso de 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 join método e passe um objeto com uma groupId propriedade. O groupId valor tem de ser um GUID.

const context = { groupId: '<GUID>'};
const call = callAgent.join(context);

Receber uma chamada

A callAgent instância emite um incomingCall evento quando a identidade conectada recebe uma chamada de entrada. Para ouvir este evento, inscreva-se 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 incomingCall evento inclui uma incomingCall instância que você pode aceitar ou rejeitar.

O SDK de Chamada de Comunicação do Azure gera um diagnóstico cameraStartFailed: true call se a câmera não estiver disponível ao iniciar, aceitar ou ingressar em uma chamada com vídeo habilitado. Neste caso, a chamada começa com o vídeo desligado. A câmera pode não estar disponível porque está sendo usada por outro processo ou porque está desativada no sistema operacional.

Suspender e retomar a chamada

Nota

Em qualquer momento, deve haver apenas 1 chamada ativa (em Connected estado, com mídia ativa). Todas as outras chamadas devem ser suspensas por um usuário ou programaticamente pelo aplicativo. Isso é comum em cenários como contact centers, onde um usuário pode precisar lidar com várias chamadas de entrada e saída, todas as chamadas inativas devem ser suspensas e o usuário deve interagir com outras pessoas apenas em chamadas ativas

Para manter ou retomar a chamada, você pode usar as APIs assíncronas e resume assíncronashold:

Para realizar a chamada

await call.hold();

Quando hold a API é resolvida, o estado da chamada é definido como LocalHold. Em uma chamada 1:1, o outro participante também é colocado em espera, e o estado da chamada da perspetiva desse participante é definido como 'RemoteHold'. Mais tarde, o outro participante poderia suspender sua chamada, o que resultaria em uma mudança de estado para LocalHold. Em uma chamada de grupo ou reunião - a hold é uma operação local, não mantém a chamada para outros participantes da chamada. Para retomar a chamada, todos os usuários que iniciaram a retenção devem retomá-la.

Para retomar a chamada da espera:

await call.resume();

Quando a resume API é resolvida, o estado da chamada é definido novamente como Connected.

Ativar e desativar o som de uma chamada

Para ativar ou desativar o mudo do ponto de extremidade local, você pode usar as APIs assíncronas e unmute assíncronasmute:

//mute local device (microphone / sent audio)
await call.mute();

//unmute local device (microphone / sent audio)
await call.unmute();

Ativar e desativar o som de entrada

Silenciar áudio de entrada define o volume da chamada como 0. Para ativar ou desativar o mudo do áudio recebido, você pode usar as APIs assíncronas e unmuteIncomingAudio assíncronasmuteIncomingAudio:

//mute local device (speaker)
await call.muteIncomingAudio();

//unmute local device (speaker)
await call.unmuteIncomingAudio();

Quando o áudio de entrada é silenciado, 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 consegue 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 RemoteParticipant objeto e disponibilizados através da remoteParticipants coleção em uma instância de chamada. O remoteParticipants é acessível a partir de uma Call instância.

Listar os participantes de uma chamada

A remoteParticipants coleção retorna uma lista de participantes remotos em uma chamada:

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 addParticipant API. Forneça um dos Identifier tipos. Ele retorna a instância de forma síncrona remoteParticipant . O remoteParticipantsUpdated evento de Call é 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ê tem que passar um dos Identifier tipos. Este método é resolvido de forma assíncrona depois que o participante é removido da chamada. O participante também é retirado da remoteParticipants coleção.

const userIdentifier = { communicationUserId: '<ACS_USER_ID>' };
const pstnIdentifier = { phoneNumber: '<PHONE_NUMBER>' }
await call.removeParticipant(userIdentifier);
await call.removeParticipant(pstnIdentifier);

Acessar propriedades de participantes remotos

Os participantes remotos têm um conjunto de propriedades e coleções associadas:

  • CommunicationIdentifier: Obtenha o identificador de um participante remoto. A identidade é um dos CommunicationIdentifier tipos:
const identifier = remoteParticipant.identifier;
  • Pode ser um dos seguintes CommunicationIdentifier tipos:

    • { 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 do Teams.
    • { id: string }: objeto que representa o identificador que não se encaixa em nenhum dos outros tipos de identificador
  • state: Obter 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á ligado à chamada.
    • Hold: O participante está em espera.
    • EarlyMedia: Anúncio que é reproduzido antes de um participante se conectar à chamada.
    • InLobby: Indica que o participante remoto está no lobby.
    • Disconnected: Estado final. O participante é desligado da chamada. Se o participante remoto perder sua conectividade de rede, seu estado mudará para Disconnected após dois minutos.
  • callEndReason: Para saber por que um participante deixou a chamada, verifique o callEndReason estabelecimento:

    const callEndReason = remoteParticipant.callEndReason;
    const callEndReasonCode = callEndReason.code // (number) code associated with the reason
    const callEndReasonSubCode = callEndReason.subCode // (number) subCode associated with the reason
    

    Nota:

    • Essa propriedade só é definida ao adicionar um participante remoto por meio da API Call.addParticipant() e o participante remoto recusa, por exemplo.
    • No cenário, onde UserB chuta UserC, da perspetiva de UserA, UserA não vê esse sinalizador ser definido para UserC. Em outras palavras, UserA não vê a propriedade callEndReason do UserC ser definida.
  • isMuted status: Para saber se um participante remoto está mudo, verifique a isMuted propriedade. Ele retorna Boolean.

    const isMuted = remoteParticipant.isMuted;
    
  • isSpeaking status: Para saber se um participante remoto está falando, verifique a isSpeaking propriedade. 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 videoStreams coleção. Ele contém RemoteVideoStream objetos.

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

    const displayName = remoteParticipant.displayName;
    
  • endpointDetails: Obtenha os detalhes de todos os endpoints para este participante remoto

        const endpointDetails: EndpointDetails[] = remoteParticipant.endpointDetails;
    

    Nota: Um participante remoto pode estar na chamada a partir de vários pontos de extremidade, e cada ponto de extremidade tem o seu próprio participantId. participantId é diferente do ID bruto do RemoteParticipant.identifier.

Silenciar outros participantes

Nota

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 que esteja conectado a uma chamada, você pode usar as APIs muteAllRemoteParticipants assíncronas na chamada e mute no participante remoto. O mutedByOthers evento da Call é gerado quando o participante local foi silenciado por outros.

Nota: Os cenários para silenciar participantes PSTN (número de telefone) ou participantes de chamadas 1:1 não são suportados.

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

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

Verificar propriedades de chamada

Obtenha o ID exclusivo (string) para uma chamada:

const callId: string = call.id;

Obtenha o ID de 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 tem seu próprio ponto de extremidade exclusivo participantId. participantId é diferente da ID bruta de identidade dos Serviços de Comunicação do Azure.

Recupere o ID do thread se participar de uma reunião do Teams:

const threadId: string | undefined = call.info.threadId;

Obtenha informações sobre a chamada:

const callInfo = call.info;

Saiba mais sobre outros participantes da chamada inspecionando a remoteParticipants coleção na instância 'call':

const remoteParticipants = call.remoteParticipants;

Identifique o chamador de uma chamada recebida:

const callerIdentity = call.callerInfo.identifier;

identifier é um dos CommunicationIdentifier tipos.

Obtenha 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 de chamada inicial.
  • Connecting: Estado de transição inicial quando uma chamada é feita ou aceita.
  • Ringing: Para uma chamada de saída, indica que uma chamada está tocando para participantes remotos. Está Incoming do lado deles.
  • EarlyMedia: Indica um estado em que um anúncio é 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 da chamada ir para um Disconnected estado.
  • Disconnected: Estado final da chamada. Se a conexão de rede for perdida, o estado muda para Disconnected após dois minutos.

Descubra por que uma chamada terminou inspecionando o callEndReason imóvel:

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 de saída, inspecionando a direction propriedade. 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 localVideoStreams coleção. A localVideoStreams API retorna LocalVideoStream objetos do tipo Video, ScreenSharingou 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;

Instale o SDK

Localize seu arquivo no nível build.gradle do projeto e adicione mavenCentral() à lista de repositórios em buildscript e allprojects:

buildscript {
    repositories {
    ...
        mavenCentral()
    ...
    }
}
allprojects {
    repositories {
    ...
        mavenCentral()
    ...
    }
}

Em seguida, no arquivo de nível build.gradle de módulo, adicione as seguintes linhas à dependencies seção:

dependencies {
    ...
    implementation 'com.azure.android:azure-communication-calling:1.0.0'
    ...
}

Inicializar os objetos necessários

Para criar uma CallAgent instância, você precisa chamar o createCallAgent método em uma CallClient instância. Essa chamada retorna de forma assíncrona um objeto de CallAgent instância.

O createCallAgent método toma CommunicationUserCredential como um argumento, que encapsula um token de acesso.

Para acessar DeviceManagero , você deve criar uma callAgent instância primeiro. Então você pode usar o CallClient.getDeviceManager método 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 CallAgent.startCall() método e fornecer o Identifier (s) destinatário(s). Para participar de uma chamada de grupo, você precisa chamar o CallAgent.join() método e fornecer o groupId. As IDs de grupo devem 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.

Fazer uma chamada 1:1 para um usuário

Para fazer uma chamada para outro usuário dos Serviços de Comunicação, invoque o call método e callAgent passe um objeto com communicationUserId chave.

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);

Faça uma chamada 1:n com usuários e PSTN

Nota

Verifique os detalhes da oferta de chamadas RTPC. Para acesso ao programa de pré-visualização, candidate-se ao programa de adoção antecipada.

Para fazer uma chamada 1:n para um usuário e um número PSTN, você precisa especificar o número de telefone do destinatário. Seu recurso de Serviços de Comunicação deve ser configurado para permitir chamadas 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âmara 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 recebida pode ser obtida inscrevendo-se onIncomingCall no evento no callAgent objeto:

// 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;
}

Participe de uma chamada de sala

Use o CallAgent e RoomCallLocator para ingressar em uma chamada de sala especificando um roomIdarquivo . O CallAgent.join método retornará um Call objeto:

val roomCallLocator = RoomCallLocator(roomId)
call = callAgent.join(applicationContext, roomCallLocator, joinCallOptions)

A room oferece aos desenvolvedores de aplicativos um melhor controle sobre quem pode participar de uma chamada, quando eles se encontram e como eles colaboram. Para saber mais sobre roomso , você pode ler a documentação conceitual ou seguir o guia de início rápido.

Participar numa chamada de grupo

Para iniciar uma nova chamada de grupo ou participar de uma chamada de grupo em andamento, você precisa chamar o método 'join' e passar um objeto com uma groupId propriedade. O valor tem de ser um GUID.

Context appContext = this.getApplicationContext();
GroupCallLocator groupCallLocator = new GroupCallLocator("<GUID>");
JoinCallOptions joinCallOptions = new JoinCallOptions();

call = callAgent.join(context, groupCallLocator, joinCallOptions);

Propriedades de chamada

Obtenha o ID exclusivo para esta chamada:

String callId = call.getId();

Para saber mais sobre outros participantes da chamada, inspecione remoteParticipant a call coleta na instância:

List<RemoteParticipant> remoteParticipants = call.getRemoteParticipants();

A identidade do chamador se a chamada estiver chegando:

CommunicationIdentifier callerId = call.getCallerInfo().getIdentifier();

Obtenha o estado da chamada:

CallState callState = call.getState();

Ele retorna uma cadeia de caracteres que representa o estado atual de uma chamada:

  • 'NONE' - estado de chamada inicial
  • 'EARLY_MEDIA' - indica um estado em que um anúncio é reproduzido antes de a chamada ser conectada
  • 'CONEXÃO' - estado de transição inicial assim que a chamada é feita ou aceita
  • 'RINGING' - para uma chamada de saída - indica que a chamada está tocando para participantes remotos
  • 'CONECTADO' - a chamada está conectada
  • 'LOCAL_HOLD' - a chamada é suspensa pelo participante local, nenhuma mídia está fluindo entre o ponto final local e o(s) participante(s) remoto(s)
  • 'REMOTE_HOLD' - a chamada é suspensa por um participante remoto, nenhuma mídia está fluindo entre o ponto final local e o(s) participante(s) remoto(s)
  • 'DESCONEXÃO' - estado de transição antes da chamada ir para o estado 'Desconectado'
  • 'DESCONECTADO' - estado final da chamada
  • 'IN_LOBBY' - no lobby para uma reunião do Teams interoperabilidade

Para saber por que uma chamada terminou, inspecione callEndReason a propriedade. Contém 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 callDirection a propriedade:

CallDirection callDirection = call.getCallDirection(); 
// callDirection == CallDirection.INCOMING for incoming call
// callDirection == CallDirection.OUTGOING for outgoing call

Para ver se o microfone atual está mudo, inspecione a muted propriedade:

boolean muted = call.isMuted();

Para inspecionar fluxos de vídeo ativos, verifique a localVideoStreams coleção:

List<LocalVideoStream> localVideoStreams = call.getLocalVideoStreams();

Ativar e desativar som

Para ativar ou desativar o mudo do ponto de extremidade local, você pode usar as APIs assíncronas e unmute assíncronasmute:

Context appContext = this.getApplicationContext();
call.mute(appContext).get();
call.unmute(appContext).get();

Alterar o volume da chamada

Enquanto você estiver em uma chamada, as teclas de volume de hardware no telefone devem permitir que o usuário altere o volume da chamada. Isso é feito usando o método setVolumeControlStream com o tipo AudioManager.STREAM_VOICE_CALL de fluxo na atividade onde a chamada está sendo feita. Isso permite que as teclas de volume de hardware alterem o volume da chamada (indicado por um ícone de telefone ou algo semelhante no controle deslizante de volume), impedindo que se altere o volume para outros perfis de som, como alarmes, mídia ou volume de todo o sistema. Para obter mais informações, você pode verificar Manipulando alterações na saída de áudio | Desenvolvedores Android.

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
}

Gestão remota de participantes

Todos os participantes remotos são representados por RemoteParticipant tipo e estão disponíveis através da remoteParticipants coleção em uma instância de chamada.

Listar participantes em uma chamada

A remoteParticipants coleção retorna uma lista de participantes remotos em determinada chamada:

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 forma síncrona 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 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 forma assíncrona assim que o participante for removido da chamada. O participante também será retirado da remoteParticipants coleta.

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 para este participante remoto. A identidade é um dos tipos de 'Identificador'

    CommunicationIdentifier participantIdentifier = remoteParticipant.getIdentifier();
    
  • Obtenha o estado deste participante remoto.

    ParticipantState state = remoteParticipant.getState();
    

Estado pode ser um dos

  • 'IDLE' - estado inicial

  • 'EARLY_MEDIA' - o anúncio é reproduzido antes de o participante ser ligado à chamada

  • 'RINGING' - a chamada do participante está a tocar

  • 'CONNECTING' - estado de transição enquanto o participante está se conectando à chamada

  • 'CONECTADO' - o participante está conectado à chamada

  • 'HOLD' - participante está em espera

  • 'IN_LOBBY' - participante aguarda no lobby para ser admitido. Atualmente usado apenas no cenário de interoperabilidade do Teams

  • 'DESCONECTADO' - estado final - o participante está desconectado da chamada

  • Para saber por que um participante deixou a chamada, inspecione callEndReason a propriedade:

    CallEndReason callEndReason = remoteParticipant.getCallEndReason();
    
  • Para verificar se esse participante remoto está silenciado ou não, inspecione a isMuted propriedade:

    boolean isParticipantMuted = remoteParticipant.isMuted();
    
  • Para verificar se esse participante remoto está falando ou não, inspecione o isSpeaking imóvel:

    boolean isParticipantSpeaking = remoteParticipant.isSpeaking();
    
  • Para inspecionar todos os fluxos de vídeo que um determinado participante está enviando nesta chamada, verifique a videoStreams coleção:

    List<RemoteVideoStream> videoStreams = remoteParticipant.getVideoStreams(); // [RemoteVideoStream, RemoteVideoStream, ...]
    

Silenciar outros participantes

Nota

Para usar essa API, use o SDK do Android do Azure Communication Services Calling versão 2.11.0 ou superior.

Para silenciar todos os outros participantes de uma chamada, use a muteAllRemoteParticipants API na chamada.

call.muteAllRemoteParticipants();

Para silenciar um participante remoto específico, use a mute API em um determinado participante remoto.

remoteParticipant.mute();

Para notificar o participante local de que foi silenciado por outros, inscreva-se no onMutedByOthers evento.

Usando serviços de primeiro plano

Nos casos em que você deseja executar uma tarefa visível do usuário, mesmo quando seu aplicativo está em segundo plano, você pode usar os Serviços de Primeiro Plano.

Usando os Serviços de Primeiro Plano, você pode, por exemplo, manter uma notificação visível do usuário quando seu aplicativo tiver 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 de Primeiro Plano durante uma chamada, navegar até a tela inicial pode manter a chamada ativa, mas remover o aplicativo da tela recente pode interromper a chamada se o sistema operacional Android matar o processo do seu aplicativo.

Você deve iniciar o Serviço de Primeiro Plano quando iniciar/ingressar em uma chamada, por exemplo:

call = callAgent.startCall(context, participants, options);
startService(yourForegroundServiceIntent);

E pare o Serviço de Primeiro Plano quando desligar a chamada ou o estado da chamada for Desligado, por exemplo:

call.hangUp(new HangUpOptions()).get();
stopService(yourForegroundServiceIntent);

Notas sobre o uso de serviços de primeiro plano

Lembre-se de que cenários como a interrupção de um Serviço de Primeiro Plano já em execução quando o aplicativo for removido da lista recente, removerão a notificação visível do usuário e o sistema operacional Android poderá manter seu processo de aplicativo ativo por algum período extra de tempo, o que significa que a chamada ainda pode estar ativa durante esse período.

Se seu aplicativo estiver interrompendo o Serviço de Primeiro Plano no método de serviço onTaskRemoved , por exemplo, seu aplicativo poderá iniciar/parar áudio e vídeo de acordo com seu Ciclo de Vida da Atividade , como parar áudio e vídeo quando sua atividade for destruída com a substituição do onDestroy método.

Configure o seu sistema

Siga estes passos para configurar o seu sistema.

Criar o projeto Xcode

No Xcode, crie um novo projeto iOS e selecione o modelo Single View App . Este artigo usa a estrutura SwiftUI, portanto, você deve definir Language como Swift e Interface como SwiftUI.

Você não vai criar testes neste artigo. Sinta-se à vontade para desmarcar a caixa de seleção Incluir testes .

Captura de tela que mostra a janela para criar um projeto no Xcode.

Instale 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 o pod install.

  3. Abra .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 seu aplicativo usando NSMicrophoneUsageDescription. Defina o valor associado para uma cadeia de caracteres 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 do projeto e selecione Abrir como>código-fonte. Adicione as seguintes linhas na secção de nível <dict> superior e, em seguida, guarde o ficheiro.

<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>

Configurar a estrutura do aplicativo

Abra o arquivo do ContentView.swift seu projeto. Adicione uma import declaração à parte superior do arquivo para importar a AzureCommunicationCalling biblioteca. Além disso, importe AVFoundation. Você precisa dele para solicitações de permissão de áudio no código.

import AzureCommunicationCalling
import AVFoundation

Inicializar o CallAgent

Para criar uma CallAgent instância a partir do CallClient, você precisa usar um callClient.createCallAgent método que retorna de forma assíncrona um CallAgent objeto depois que ele é inicializado.

Para criar um cliente de chamada, passe um CommunicationTokenCredential objeto:

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 CommunicationTokenCredential objeto que você criou para CallCliente defina o nome para 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")
        }
})

Nota

Quando o aplicativo implementa delegados de eventos, ele precisa manter uma referência forte aos objetos que exigem assinaturas de eventos. Por exemplo, quando um RemoteParticipant objeto é retornado ao invocar o call.addParticipant método e o aplicativo define o delegado para escutar RemoteParticipantDelegate, o aplicativo deve conter uma referência forte ao RemoteParticipant objeto. Caso contrário, se esse objeto for coletado, o delegado lançará uma exceção fatal quando o SDK de chamada tentar invocar o objeto.

Fazer uma chamada de saída

Para criar e iniciar uma chamada, você precisa chamar uma das APIs CallAgent e fornecer a identidade dos Serviços de Comunicação de um usuário que você provisionou usando o SDK de Gerenciamento de Serviços de Comunicação.

A criação e o início da chamada são síncronos. Você receberá uma instância de chamada que permite que você se inscreva em todos os eventos da chamada.

Faça 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")
     }
}

Faça uma chamada 1:n com usuários e PSTN

Nota

Verifique os detalhes da oferta de chamadas RTPC. Para acesso ao programa de pré-visualização, candidate-se ao programa de adoção antecipada.

Para fazer a chamada para a PSTN, tem de especificar um número de telefone adquirido com os Serviços de Comunicação.

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")
     }
}

Participe de uma chamada de sala

Para ingressar em uma room chamada, especifique a roomId propriedade como o room identificador. Para participar da chamada, use o join método e passe o roomCallLocatorarquivo .

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)
    }
}

A room oferece aos desenvolvedores de aplicativos um melhor controle sobre quem pode participar de uma chamada, quando eles se encontram e como eles colaboram. Para saber mais sobre roomso , você pode ler a documentação conceitual ou seguir o guia de início rápido.

Participar numa chamada de grupo

Para participar de uma chamada, você precisa chamar uma das APIs no CallAgent.

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")
    }
}

Subscrever uma chamada recebida

Inscreva-se em um evento de 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 recebida

Para aceitar uma chamada, chame o accept método em um IncomingCall objeto.

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 operações de chamada intermediária

Você pode executar várias operações durante uma chamada para gerenciar configurações relacionadas a vídeo e áudio.

Ativar e desativar som

Para ativar ou desativar o mudo do ponto de extremidade local, você pode usar as APIs assíncronas e unmute assíncronasmute.

call!.mute { (error) in
    if error == nil {
        print("Successfully muted")
    } else {
        print("Failed to mute")
    }
}

Use o código a seguir para ativar o mudo do ponto de extremidade local de forma assíncrona.

call!.unmute { (error) in
    if error == nil {
        print("Successfully un-muted")
    } else {
        print("Failed to unmute")
    }
}

Gerenciar participantes remotos

Todos os participantes remotos são representados pelo RemoteParticipant tipo e estão disponíveis através da remoteParticipants coleção em uma instância de chamada.

Listar 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 addParticipant. Este comando retornará de forma síncrona uma instância de 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 a removeParticipant API. Isso será resolvido de forma assíncrona.

call!.remove(participant: remoteParticipantAdded) { (error) in
    if (error == nil) {
        print("Successfully removed participant")
    } else {
        print("Failed to remove participant")
    }
}

Obter propriedades de participantes remotos

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

Silenciar outros participantes

Nota

Para usar essa API, use o SDK do iOS do Azure Communication Services Calling versão 2.13.0 ou superior.

Para silenciar todos os outros participantes de uma chamada, use a muteAllRemoteParticipants API na chamada.

call!.muteAllRemoteParticipants { (error) in
    if error == nil {
        print("Successfully muted all remote participants.")
    } else {
        print("Failed to mute remote participants.")
    }
}

Para silenciar um participante remoto específico, use a mute API 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 foi silenciado por outros, inscreva-se no onMutedByOthers evento.

Configure o seu sistema

Siga estes passos para configurar o seu sistema.

Criar o projeto do Visual Studio

Para um aplicativo da Plataforma Universal do Windows, no Visual Studio 2022, crie um novo projeto Aplicativo em Branco (Universal Windows). Depois de inserir o nome do projeto, sinta-se à 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. É necessário o SDK de Aplicativos Windows versão 1.3 ou posterior.

Instalar o pacote e as dependências usando o Gerenciador de Pacotes NuGet

As APIs e bibliotecas 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:

  1. Abra o Gerenciador de Pacotes NuGet selecionando Ferramentas>Gerenciador>de Pacotes NuGet Gerenciar Pacotes NuGet para Solução.
  2. Selecione Procurar e digite 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, em seguida, selecione Azure.Communication.Calling.WindowsClient 1.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 do Azure no painel direito.
  6. Selecione Instalar.

Solicitar acesso ao microfone

O aplicativo requer acesso ao microfone para funcionar corretamente. Em aplicativos UWP, o recurso de microfone deve ser declarado no arquivo de manifesto do aplicativo.

As etapas a seguir exemplificam como conseguir isso.

  1. Solution Explorer No painel, clique duas vezes no arquivo com .appxmanifest extensão.
  2. Clique na Capabilities guia.
  3. Marque a Microphone caixa de seleção na lista de recursos.

Criar botões da interface do usuário para fazer e desligar a chamada

Este aplicativo de exemplo simples contém dois botões. Um para fazer a chamada e outro para desligar uma chamada feita. As etapas a seguir exemplificam como adicionar esses botões ao aplicativo.

  1. Solution Explorer No painel, 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 visualização da interface do usuário.
  3. Modifique o código XAML pelo seguinte trecho:
<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>

Configurando o aplicativo com APIs do SDK chamando

As APIs do SDK de chamada estão em dois namespaces diferentes. As etapas a seguir informam o compilador C# sobre esses namespaces, permitindo que o Intellisense do Visual Studio ajude no desenvolvimento de código.

  1. Solution Explorer No painel, clique na seta no lado esquerdo do arquivo nomeado MainPage.xaml para UWP ou MainWindows.xaml para WinUI 3.
  2. Clique duas vezes no arquivo nomeado MainPage.xaml.cs ou MainWindows.xaml.cs.
  3. Adicione os seguintes comandos na parte inferior das instruções atuais using .
using Azure.Communication.Calling.WindowsClient;

Manter MainPage.xaml.cs ou MainWindows.xaml.cs abrir. As próximas etapas adicionarão mais código a ele.

Permitir interações com aplicativos

Os botões da interface do usuário adicionados anteriormente precisam operar em cima de um arquivo CommunicationCall. Isso significa que um CommunicationCall membro de dados deve ser adicionado à MainPage classe ou MainWindow . Além disso, para permitir que a criação CallAgent da operação assíncrona seja bem-sucedida, um CallAgent membro de dados também deve ser adicionado à mesma classe.

Adicione os seguintes membros de dados à MainPage classe pr MainWindow :

CallAgent callAgent;
CommunicationCall call;

Criar manipuladores de botão

Anteriormente, dois botões da interface do usuário eram 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 após os 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 interfaces a seguir lidam com alguns dos principais recursos da biblioteca de cliente de Chamada dos Serviços de Comunicação do Azure para UWP.

Nome Descrição
CallClient O CallClient é o principal ponto de entrada para a biblioteca de cliente de chamada.
CallAgent O CallAgent é usado para iniciar e participar de chamadas.
CommunicationCall O CommunicationCall é usado para gerenciar chamadas feitas ou associadas.
CommunicationTokenCredential O CommunicationTokenCredential é usado como a credencial de token para instanciar o 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 seus participantes.

Inicializar o CallAgent

Para criar uma CallAgent instância a partir do CallClient, você deve usar CallClient.CreateCallAgentAsync um método que retorna de forma assíncrona um CallAgent objeto depois que ele é inicializado.

Para criar CallAgento , você deve passar um CallTokenCredential objeto e um CallAgentOptions objeto. Tenha em mente que CallTokenCredential lança se um token malformado for passado.

O código a seguir deve ser adicionado dentro e a função auxiliar deve 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 seu 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 e fazer uma chamada de forma assíncrona.

O código a seguir deve ser adicionado depois de manipular a 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;

Sinta-se à vontade para usar 8:echo123 para falar com o bot de eco dos Serviços de Comunicação do Azure.

Ativar e desativar som

Para ativar ou desativar o mudo do áudio de saída, você pode usar as APIs assíncronas MuteOutgoingAudioAsync UnmuteOutgoingAudioAsync :

// mute outgoing audio
await this.call.MuteOutgoingAudioAsync();

// unmute outgoing audio
await this.call.UnmuteOutgoingAudioAsync();

Silenciar outros participantes

Nota

Para usar essa API, use o SDK do Windows do Azure Communication Services Calling Windows versão 1.9.0 ou superior.

Para silenciar todos os outros participantes ou silenciar um participante específico, você pode usar 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 foi silenciado por outros, inscreva-se no MutedByOthers evento.

Terminar uma chamada

Uma vez que uma chamada é feita, o HangupAsync método do CommunicationCall objeto deve ser usado para desligar a chamada.

Uma instância de também deve ser usada para informar se a chamada deve ser encerrada HangupOptions para todos os seus participantes.

O seguinte código deve ser adicionado dentro de HangupButton_Click.

this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions() { ForEveryone = false });

Executar o código

Certifique-se de que o Visual Studio cria o aplicativo para x64, x86 ou ARM64, em seguida, pressione F5 para começar a executar o aplicativo. Depois disso, clique no Call botão para fazer uma chamada para o destinatário definido.

Lembre-se de que, na primeira vez que o aplicativo for executado, o sistema solicitará que o usuário conceda acesso ao microfone.

Próximos passos