Partilhar via


Inscrever-se em eventos do SDK

Os SDKs dos Serviços de Comunicação do Azure são dinâmicos e contêm muitas propriedades. Quando isso mudar, como desenvolvedor, você pode querer saber quando e, mais importante, o que muda. Veja como!

Eventos no SDK de Chamada de Comunicação do Azure

Este guia descreve os vários eventos ou alterações de propriedades que seu aplicativo pode assinar. A assinatura desses eventos permite que seu aplicativo seja informado sobre a alteração de estado no SDK de chamada e reaja de acordo.

O rastreamento de eventos é crucial porque permite que o estado do seu aplicativo permaneça sincronizado com o estado da estrutura ACSCalling, tudo sem exigir que você implemente um mecanismo de pull nos objetos SDK.

Este guia pressupõe que você passou pelo QuickStart ou que implementou um aplicativo capaz de fazer e receber chamadas. Se você não completou o guia de introdução, consulte nosso Guia de início rápido.

Cada objeto no SDK de chamada JavaScript tem properties e collections. Seus valores mudam ao longo da vida útil do objeto. Use o on() método para assinar eventos de objetos e use o método para cancelar a off() assinatura de eventos de objetos.

Propriedades

Pode subscrever o evento para ouvir as '<property>Changed' alterações de valor na propriedade.

Exemplo de subscrição numa propriedade

Neste exemplo, subscrevemos alterações no valor do isLocalVideoStarted imóvel.

call.on('isLocalVideoStartedChanged', () => {
    // At that point the value call.isLocalVideoStarted is updated
    console.log(`isLocalVideoStarted changed: ${call.isLocalVideoStarted}`);
});

Coleções

Você pode se inscrever no evento '<coleção>atualizada' para receber notificações sobre alterações em uma coleção de objetos. O evento '<coleção>atualizada' é acionado sempre que elementos são adicionados ou removidos da coleção que você está monitorando.

  • A '<collection>Updated' carga útil do evento tem uma added matriz que contém valores que foram adicionados à coleção.
  • A '<collection>Updated' carga útil do evento também tem uma removed matriz que contém valores que foram removidos da coleção.

Exemplo de assinatura em uma coleção

Neste exemplo, subscrevemos as alterações nos valores do objeto LocalVideoStreamCall .

call.on('localVideoStreamsUpdated', updateEvent => {
    updateEvent.added.forEach(async (localVideoStream) => {
        // Contains an array of LocalVideoStream that were added to the call
        // Add a preview and start any processing if needed
        handleAddedLocalVideoStream(localVideoStream )
    });
    updateEvent.removed.forEach(localVideoStream => {
        // Contains an array of LocalVideoStream that were removed from the call
        // Remove the preview and stop any processing if needed
        handleRemovedLocalVideoStream(localVideoStream ) 
    });
});

Eventos no CallAgent objeto

Nome do evento: incomingCall

O incomingCall evento é acionado quando o cliente está recebendo uma chamada de entrada.

Como deve a sua candidatura reagir ao evento?

Seu aplicativo deve notificar o usuário sobre a chamada recebida. O prompt de notificação deve propor ao usuário que aceite ou recuse a chamada.

Exemplo de código:

callClient.on('incomingCall', (async (incomimgCallEvent) => {
    try {
        // Store a reference to the call object
        incomingCall = incomimgCallEvent.incomingCall; 
        // Update your UI to allow
        acceptCallButton.disabled = false; 
        callButton.disabled = true;
    } catch (error) {
        console.error(error);
    }
});

Nome do evento: callsUpdated

O callsUpdated evento updated é disparado quando uma chamada é removida ou adicionada ao agente de chamada. Esse evento acontece quando o usuário faz, recebe ou encerra uma chamada.

Como deve a sua candidatura reagir ao evento? Seu aplicativo deve atualizar sua interface do usuário com base no número de chamadas ativas para a instância do CallAgent.

Nome do evento: connectionStateChanged

O connectionStateChanged evento disparado quando o estado de sinalização do CallAgent é atualizado.

Como deve a sua candidatura reagir ao evento?

Seu aplicativo deve atualizar sua interface do usuário com base no novo estado. Os possíveis valores de estado de conexão são Connected e Disconnected

Exemplo de código:

callClient.on('connectionStateChanged', (async (connectionStateChangedEvent) => {
    if (connectionStateChangedEvent.newState === "Connected") {
        enableCallControls() // Enable all UI element that allow user to make a call
    }

    if (connectionStateChangedEvent.newState === 'Disconnected') {
        if (typeof connectionStateChangedEvent.reason !== 'undefined') {
            alert(`Disconnected reason: ${connectionStateChangedEvent.reason}`)
        } 
        disableCallControls() // Disable all the UI element that allows the user to make a call
    }
});

Eventos no Call objeto

Nome do evento: stateChanged

O stateChanged evento é acionado quando o estado da chamada muda. Por exemplo, quando uma chamada vai de connected para disconnected.

Como deve a sua candidatura reagir ao evento?

Seu aplicativo deve atualizar sua interface do usuário de acordo. Desativando ou habilitando botões apropriados e outros elementos da interface do usuário com base no novo estado da chamada.

Exemplo de código:

call.on('stateChanged', (async (connectionStateChangedEvent) => {
  if(call.state === 'Connected') {
      connectedLabel.hidden = false;
      acceptCallButton.disabled = true;
      startCallButton.disabled = true;
      startVideoButton.disabled = false;
      stopVideoButton.disabled = false
  } else if (call.state === 'Disconnected') {
      connectedLabel.hidden = true;
      startCallButton.disabled = false;
      console.log(`Call ended, call end reason={code=${call.callEndReason.code}, subCode=${call.callEndReason.subCode}}`);
  }
});

Evento: idChanged

O idChanged evento é acionado quando a ID de uma chamada é alterada. A ID de uma chamada muda quando a chamada passa de connecting estado para connected. Uma vez que a chamada é conectada, o ID da chamada permanece idêntico.

Como pode a sua candidatura reagir ao evento?

Seu aplicativo deve salvar o novo ID de chamada, mas ele também pode ser recuperado do objeto de chamada mais tarde, quando necessário.

Exemplo de código:

let callId = "";
call.on('idChanged', (async (callIdChangedEvent) => {
  callId = call.id; // You can log it as the call ID is useful for debugging call issues
});

Evento: isMutedChanged

O isMutedChanged evento é disparado quando o áudio local é silenciado ou desativado.

Como pode a sua candidatura reagir ao evento?

Seu aplicativo deve atualizar o botão mute / unmute para o estado adequado.

Exemplo de código:

call.on('isMutedChanged', (async (isMutedChangedEvent) => {
    microphoneButton.disabled = call.isMuted;       
});

Evento: isScreenSharingOnChanged

O isScreenSharingOnChanged evento é disparado quando o compartilhamento de tela para o usuário local está habilitado ou desabilitado.

Como pode a sua candidatura reagir ao evento?

Seu aplicativo deve mostrar uma visualização e/ou um aviso para o usuário se o compartilhamento de tela ficou ativado. Se o compartilhamento de tela foi desligado, então o aplicativo deve remover a visualização e aviso.

Exemplo de código:

call.on('isScreenSharingOnChanged', () => {
  if (!this.call.isScreenSharing) {
      displayStartScreenSharingButton();
      hideScreenSharingWarning()
      removeScreenSharingPreview();    
  } else {
      displayScreenSharingWarning()
      displayStopScreenSharingButton();
      renderScreenSharingPreview(); 
  }
});

Evento: isLocalVideoStartedChanged

O isLocalVideoStartedChanged evento é disparado quando o usuário ativou nosso vídeo local desativado.

Como pode a sua candidatura reagir ao evento?

Seu aplicativo deve mostrar uma visualização do vídeo local e ativar ou desativar o botão de ativação da câmera.

Exemplo de código:

call.on('isLocalVideoStartedChanged', () => {
    showdDisableCameraButton(call.isLocalVideoStarted);
});

Evento: remoteParticipantsUpdated

Sua inscrição deve se inscrever no evento para cada evento adicionado RemoteParticipants e cancelar a inscrição para os participantes que deixaram a chamada.

Como pode a sua candidatura reagir ao evento? Seu aplicativo deve mostrar uma visualização do vídeo local e ativar ou desativar o botão de ativação da câmera.

Exemplo de código:

call.on('remoteParticipantsUpdated', (remoteParticipantsUpdatedEvent) => {
    remoteParticipantsUpdatedEvent.added.forEach(participant => {
        // handleParticipant should
        //   - subscribe to the remote participants events 
        //   - update the UI 
        handleParticipant(participant);
    });
    
    remoteParticipantsUpdatedEvent.removed.forEach(participant => {
        // removeParticipant should
        //   - unsubcribe from the remote participants events 
        //   - update the UI  
        removeParticipant(participant);
    });
});

Evento: localVideoStreamsUpdated

O localVideoStreamsUpdated evento é disparado quando a lista de fluxo de vídeo local muda. Essas alterações acontecem quando o usuário inicia ou remove um fluxo de vídeo.

Como pode a sua candidatura reagir ao evento?

Seu aplicativo deve mostrar visualizações para cada um dos LocalVideoStream adicionados. Seu aplicativo deve remover a visualização e interromper o processamento para cada LocalVideoStream removido.

Exemplo de código:

call.on('localVideoStreamsUpdated', (localVideoStreamUpdatedEvent) => {
    localVideoStreamUpdatedEvent.added.forEach(addedLocalVideoStream => { 
        // Add a preview and start any processing if needed
        handleAddedLocalVideoStream(addedLocalVideoStream) 
    });

    localVideoStreamUpdatedEvent.removed.forEach(removedLocalVideoStream => {
         // Remove the preview and stop any processing if needed
        this.handleRemovedLocalVideoStream(removedLocalVideoStream) 
    });
});

Evento: remoteAudioStreamsUpdated

O remoteAudioStreamsUpdated evento é disparado quando a lista de fluxo de áudio remoto muda. Essas alterações acontecem quando participantes remotos adicionam ou removem fluxos de áudio à chamada.

Como pode a sua candidatura reagir ao evento?

Se um fluxo estava sendo processado e agora é removido, o processamento deve ser interrompido. Por outro lado, se um fluxo for adicionado, a receção do evento é um bom lugar para iniciar o processamento do novo fluxo de áudio.

Evento: totalParticipantCountChanged

O totalParticipantCountChanged é acionado quando o número de totalParticipant é alterado em uma chamada.

Como pode a sua candidatura reagir ao evento?

Se o seu aplicativo estiver exibindo um contador de participante, seu aplicativo poderá atualizar o contador de participantes quando o evento for recebido.

Exemplo de código:

call.on('totalParticipantCountChanged', () => {
    participantCounterElement.innerText = call.totalParticipantCount;
});

Evento: roleChanged

O roleChanged participante é acionado quando as funções localParticipant são alteradas na chamada. Um exemplo seria quando o participante local se tornasse ACSCallParticipantRolePresenter apresentador de uma chamada.

Como pode a sua candidatura reagir ao evento? Seu aplicativo deve habilitar ou desabilitar a base do botão na nova função do usuário.

Exemplo de código:

call.on('roleChanged', () => {
    this.roleElement = call.role;
});

Evento: mutedByOthers

O mutedByOthers evento acontece quando outros participantes da chamada são silenciados pelo participante local.

Como pode a sua candidatura reagir ao evento? Seu aplicativo deve exibir uma mensagem para o usuário notificando que foi silenciado.

Exemplo de código:

call.on('mutedByOthers', () => {
    messageBanner.innerText = "You have been muted by other participant in this call";
});

Evento: callerInfoChanged

O callerInfoChanged evento acontece quando as informações do chamador foram atualizadas.

Como pode a sua candidatura reagir ao evento? O aplicativo pode atualizar as informações do chamador.

Exemplo de código:

call.on('callerInfoChanged', () => {
    showCallerInfo(call.callerInfo)
});

Evento: transferorInfoChanged

O transferorInfoChanged evento acontece quando as informações do cedente foram atualizadas.

Como pode a sua candidatura reagir ao evento? O aplicativo pode atualizar as informações do transferidor.

Exemplo de código:

call.on('transferorInfoChanged', () => {
    showTransferorInfo(call.transferorInfo)
});

Eventos no RemoteParticipant objeto

Evento: roleChanged

O roleChanged evento é acionado quando a RemotePartipant função é alterada na chamada. Um exemplo seria quando o RemoteParticipant se tornasse apresentador ACSCallParticipantRolePresenter em uma chamada.

Como pode a sua candidatura reagir ao evento? Seu aplicativo deve atualizar sua interface do usuário com base na RemoteParticipant nova função.

Exemplo de código:

remoteParticipant.on('roleChanged', () => {
    updateRole(remoteParticipant);
});

Evento: isMutedChanged

O isMutedChanged evento é acionado quando um dos RemoteParticipant mudos ou desativa o som do microfone.

Como pode a sua candidatura reagir ao evento?

A sua candidatura pode apresentar um ícone junto à vista que apresenta o participante.

Exemplo de código:

remoteParticipant.on('isMutedChanged', () => {
    updateMuteStatus(remoteParticipant); // Update the UI based on the mute state of the participant
});

Evento: displayNameChanged

O displayNameChanged quando o nome do RemoteParticipant é atualizado.

Como pode a sua candidatura reagir ao evento?

Seu aplicativo deve atualizar o nome do participante se ele estiver sendo exibido na interface do usuário.

Exemplo de código:

remoteParticipant.on('displayNameChanged', () => {
    remoteParticipant.nameLabel.innerText = remoteParticipant.displayName;
});

Evento: isSpeakingChanged

O isSpeakingChanged momento em que o orador dominante em uma chamada muda.

Como pode a sua candidatura reagir ao evento?

A interface do usuário do aplicativo deve dar prioridade para exibir quem se tornou o RemotePartipant orador dominante.

Exemplo de código:

remoteParticipant.on('isSpeakingChanged', () => {
    showAsRemoteSpeaker(remoteParticipant) // Display a speaking icon near the participant
});

Evento: videoStreamsUpdated

Quando videoStreamsUpdated um participante remoto adiciona ou remove um VideoStream de/para a chamada.

Como pode a sua candidatura reagir ao evento?

Se o seu aplicativo estava processando um fluxo que foi removido. O seu pedido deve parar o processamento. Quando um novo fluxo é adicionado, seu aplicativo pode querer renderizá-lo ou processá-lo.

Exemplo de código:

remoteParticipant.on('videoStreamsUpdated', (videoStreamsUpdatedEvent) => {

     videoStreamsUpdatedEvent.added.forEach(addedRemoteVideoStream => { 
       // Remove a renderer and start processing the stream if any processing is needed
        handleAddedRemoteVideoStream(addedRemoteVideoStream) 
    });

    videoStreamsUpdatedEvent.removed.forEach(removedRemoteVideoStream => {
        // Remove the renderer and stop processing the stream if any processing is ongoing
        this.handleRemovedRemoteVideoStream(removedRemoteVideoStream) 
    });
});

Evento no AudioEffectsFeature objeto

Evento: effectsStarted

Esse evento ocorre quando o efeito de áudio selecionado é aplicado ao fluxo de áudio. Por exemplo, quando alguém ativa a Supressão de Ruído, a effectsStarted pessoa será acionada.

Como pode a sua candidatura reagir ao evento?

Seu aplicativo pode exibir ou ativar um botão que permite ao usuário desativar o efeito de áudio.

Exemplo de código:

audioEffectsFeature.on('effectsStarted', (effects) => {
    stopEffectButton.style.visibility = "visible"; 
});

Evento: effectsStopped

Esse evento ocorre quando o efeito de áudio selecionado é aplicado ao fluxo de áudio. Por exemplo, quando alguém desativa a Supressão de Ruído, o effectsStopped será demitido.

Como pode a sua candidatura reagir ao evento?

Seu aplicativo pode exibir ou ativar um botão que permite ao usuário ativar o efeito de áudio.

Exemplo de código:

audioEffectsFeature.on('effectsStopped', (effects) => {
    startEffectButton.style.visibility = "visible"; 
});

Evento: effectsError

Esse evento ocorre quando um erro acontece enquanto um efeito de áudio é iniciado ou aplicado.

Como pode a sua candidatura reagir ao evento?

Seu aplicativo deve exibir um alerta ou uma mensagem de erro de que o efeito de áudio não está funcionando conforme o esperado.

Exemplo de código:

audioEffectsFeature.on('effectsError', (error) => {
    console.log(`Error with the audio effect ${error}`);
    alert(`Error with the audio effect`);
});

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

Com o nosso Android SDK, pode subscrever a maioria das propriedades e coleções para ser notificado quando os valores mudarem.

Propriedades

Para subscrever property changed eventos:

// subscribe
PropertyChangedListener callStateChangeListener = new PropertyChangedListener()
{
    @Override
    public void onPropertyChanged(PropertyChangedEvent args)
    {
        Log.d("The call state has changed.");
    }
}
call.addOnStateChangedListener(callStateChangeListener);

//unsubscribe
call.removeOnStateChangedListener(callStateChangeListener);

Quando você usa ouvintes de eventos definidos dentro da mesma classe, vincule o ouvinte a uma variável. Passe a variável como um argumento para adicionar e remover métodos de ouvinte.

Se você tentar passar o ouvinte diretamente como um argumento, perderá a referência a esse ouvinte. Java está criando novas instâncias desses ouvintes e não fazendo referência a instâncias criadas anteriormente. Eles ainda dispararão corretamente, mas não poderão ser removidos porque você não terá mais uma referência a eles.

Coleções

Para subscrever collection updated eventos:

LocalVideoStreamsChangedListener localVideoStreamsChangedListener = new LocalVideoStreamsChangedListener()
{
    @Override
    public void onLocalVideoStreamsUpdated(LocalVideoStreamsEvent localVideoStreamsEventArgs) {
        Log.d(localVideoStreamsEventArgs.getAddedStreams().size());
        Log.d(localVideoStreamsEventArgs.getRemovedStreams().size());
    }
}
call.addOnLocalVideoStreamsChangedListener(localVideoStreamsChangedListener);
// To unsubscribe
call.removeOnLocalVideoStreamsChangedListener(localVideoStreamsChangedListener);

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

Com o nosso iOS SDK, pode subscrever a maioria das propriedades e coleções para ser notificado quando os valores mudam.

Propriedades

Para se inscrever em property changed eventos, use o código a seguir.

call.delegate = self
// Get the property of the call state by getting on the call's state member
public func call(_ call: Call, didChangeState args: PropertyChangedEventArgs) {
{
    print("Callback from SDK when the call state changes, current state: " + call.state.rawValue)
}

// to unsubscribe
self.call.delegate = nil

Coleções

Para se inscrever em collection updated eventos, use o código a seguir.

call.delegate = self
// Collection contains the streams that were added or removed only
public func call(_ call: Call, didUpdateLocalVideoStreams args: LocalVideoStreamsUpdatedEventArgs) {
{
    print(args.addedStreams.count)
    print(args.removedStreams.count)
}
// to unsubscribe
self.call.delegate = nil

Próximos passos