Inscrever-se para eventos de SDK
Serviços de Comunicação do Azure SDKs são dinâmicos e contêm muitas propriedades. Quando elas mudam, você, como desenvolvedor, talvez queira 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. Assinar esses eventos permite que seu aplicativo seja informado sobre a alteração de estado no SDK de chamada e reaja adequadamente.
O acompanhamento de eventos é crucial porque permite que o estado do aplicativo permaneça sincronizado com o estado da estrutura ACSCalling, tudo sem exigir que você implemente um mecanismo de pull nos objetos do SDK.
Este guia pressupõe que você passou pelo Início Rápido ou que implementou um aplicativo capaz de fazer e receber chamadas. Se você não concluiu o guia de início, consulte nosso Início Rápido.
Cada objeto no SDK de chamada JavaScript tem properties
e collections
. Os valores deles mudam durante o tempo de vida do objeto.
Use o método on()
para assinar eventos de objetos, e use o método off()
para cancelar a assinatura de eventos de objetos.
Propriedades
Você pode assinar o evento '<property>Changed'
para ouvir as alterações de valor na propriedade.
Exemplo de assinatura em uma propriedade
Neste exemplo, assinamos alterações no valor da propriedade isLocalVideoStarted
.
call.on('isLocalVideoStartedChanged', () => {
// At that point the value call.isLocalVideoStarted is updated
console.log(`isLocalVideoStarted changed: ${call.isLocalVideoStarted}`);
});
Coleções
Você pode assinar o evento '<collection>Updated' para receber notificações sobre alterações em uma coleção de objetos. O evento '<collection>Updated' é disparado sempre que os elementos são adicionados ou removidos da coleção que você está monitorando.
- O conteúdo do evento
'<collection>Updated'
tem uma matrizadded
que contém valores que foram adicionados à coleção. - O conteúdo do evento
'<collection>Updated'
também tem uma matrizremoved
que contém valores que foram removidos da coleção.
Assinatura de exemplo em uma coleção
Neste exemplo, assinamos alterações nos valores do objeto Call LocalVideoStream
.
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 objeto CallAgent
Nome do evento: incomingCall
O evento incomingCall
é acionado quando o cliente está recebendo uma chamada de entrada.
Como seu aplicativo deve reagir ao evento?
Seu aplicativo deve notificar o usuário sobre a chamada de entrada. O prompt de notificação deve propor que o usuário 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 evento callsUpdated
atualizado é acionado quando uma chamada é removida ou adicionada ao agente de chamada. Esse evento ocorre quando o usuário faz, recebe ou encerra a chamada.
Como seu aplicativo deve 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 evento connectionStateChanged
é acionado quando o estado de sinalização do CallAgent
é atualizado.
Como seu aplicativo deve reagir ao evento?
Seu aplicativo deve atualizar sua interface do usuário com base no novo estado. Os valores de estado de conexão possíveis 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 objeto Call
Nome do evento: stateChanged
O evento stateChanged
é acionado quando o estado da chamada é alterado. Por exemplo, quando uma chamada vai de connected
para disconnected
.
Como seu aplicativo deve reagir ao evento?
Seu aplicativo deve atualizar a interface do usuário adequadamente. Desabilitando ou habilitando botões apropriados e outros elementos de interface do usuário com base no novo estado de 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 evento idChanged
é acionado quando a ID de uma chamada é alterada. A ID de uma chamada é alterada quando a chamada passa do estado connecting
para connected
. Depois que a chamada estiver conectada, a ID da chamada permanecerá idêntica.
Como seu aplicativo pode reagir ao evento?
Seu aplicativo deve salvar a nova ID de chamada, mas também pode ser recuperada 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 evento isMutedChanged
é acionado quando o áudio local é silenciado ou desativado.
Como seu aplicativo pode reagir ao evento?
Seu aplicativo deve atualizar o botão de ativar/desativar mudo para o estado adequado.
Exemplo de código:
call.on('isMutedChanged', (async (isMutedChangedEvent) => {
microphoneButton.disabled = call.isMuted;
});
Evento: isScreenSharingOnChanged
O evento isScreenSharingOnChanged
é acionado quando o compartilhamento de tela para o usuário local está habilitado ou desabilitado.
Como seu aplicativo pode reagir ao evento?
Seu aplicativo deve mostrar uma visualização e/ou um aviso para o usuário se o compartilhamento de tela estiver ativado. Se o compartilhamento de tela tiver desativado, o aplicativo deverá remover a visualização e o aviso.
Exemplo de código:
call.on('isScreenSharingOnChanged', () => {
if (!this.call.isScreenSharing) {
displayStartScreenSharingButton();
hideScreenSharingWarning()
removeScreenSharingPreview();
} else {
displayScreenSharingWarning()
displayStopScreenSharingButton();
renderScreenSharingPreview();
}
});
Evento: isLocalVideoStartedChanged
O evento isLocalVideoStartedChanged
é acionado quando o usuário habilita nosso vídeo local desabilitado.
Como seu aplicativo pode reagir ao evento?
Seu aplicativo deve mostrar uma visualização do vídeo local e habilitar ou desabilitar o botão de ativação da câmera.
Exemplo de código:
call.on('isLocalVideoStartedChanged', () => {
showdDisableCameraButton(call.isLocalVideoStarted);
});
Evento: remoteParticipantsUpdated
Seu aplicativo deve assinar o evento para cada evento adicionado a RemoteParticipants
e cancelar a assinatura de eventos para participantes que saíram da chamada.
Como seu aplicativo pode reagir ao evento? Seu aplicativo deve mostrar uma visualização do vídeo local e habilitar ou desabilitar 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 evento localVideoStreamsUpdated
é acionado quando a lista de fluxo de vídeo local é alterada. Essas alterações ocorrem quando o usuário inicia ou remove um fluxo de vídeo.
Como seu aplicativo pode 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 de 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 evento remoteAudioStreamsUpdated
é acionado quando a lista de fluxo de áudio remoto muda. Essas alterações ocorrem quando os participantes remotos adicionam ou removem fluxos de áudio à chamada.
Como seu aplicativo pode 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 recepção do evento será um bom local para iniciar o processamento do novo fluxo de áudio.
Evento: totalParticipantCountChanged
O totalParticipantCountChanged
aciona quando o número de totalParticipant foi alterado em uma chamada.
Como seu aplicativo pode reagir ao evento?
Se o aplicativo estiver exibindo um contador de participantes, 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 participante roleChanged
é acionado quando as funções localParticipant são alteradas na chamada. Um exemplo seria quando o participante local se tornar apresentador ACSCallParticipantRolePresenter
em uma chamada.
Como seu aplicativo pode reagir ao evento? Seu aplicativo deve habilitar ou desabilitar a base de botões na nova função do usuário.
Exemplo de código:
call.on('roleChanged', () => {
this.roleElement = call.role;
});
Evento: mutedByOthers
O evento mutedByOthers
ocorre quando o participante local ativou o mudo para outros participantes da chamada.
Como seu aplicativo pode reagir ao evento? Seu aplicativo deve exibir uma mensagem para o usuário notificando que o mudo dele foi ativado.
Exemplo de código:
call.on('mutedByOthers', () => {
messageBanner.innerText = "You have been muted by other participant in this call";
});
Evento: callerInfoChanged
O evento callerInfoChanged
ocorre quando as informações do chamador foram atualizadas.
Como seu aplicativo pode 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 evento transferorInfoChanged
ocorre quando as informações do transferidor foram atualizadas.
Como seu aplicativo pode reagir ao evento? O aplicativo pode atualizar as informações do transferidor.
Exemplo de código:
call.on('transferorInfoChanged', () => {
showTransferorInfo(call.transferorInfo)
});
Eventos no objeto RemoteParticipant
Evento: roleChanged
O evento roleChanged
é acionado quando a função RemotePartipant
é alterada na chamada. Um exemplo seria quando o RemoteParticipant se tornar apresentador ACSCallParticipantRolePresenter
em uma chamada.
Como seu aplicativo pode reagir ao evento?
Seu aplicativo deve atualizar sua interface do usuário com base na nova função do RemoteParticipant
.
Exemplo de código:
remoteParticipant.on('roleChanged', () => {
updateRole(remoteParticipant);
});
Evento: isMutedChanged
O evento isMutedChanged
é acionado quando um dos RemoteParticipant
ativa ou desativa o mudo do microfone.
Como seu aplicativo pode reagir ao evento?
Seu aplicativo pode exibir um ícone próximo à exibição que exibe 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 seu aplicativo pode reagir ao evento?
Seu aplicativo deverá 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
quando o alto-falante dominante em uma chamada é alterado.
Como seu aplicativo pode reagir ao evento?
A interface do usuário do aplicativo deve dar prioridade para exibir o RemotePartipant
que se tornou o orador dominante.
Exemplo de código:
remoteParticipant.on('isSpeakingChanged', () => {
showAsRemoteSpeaker(remoteParticipant) // Display a speaking icon near the participant
});
Evento: videoStreamsUpdated
O videoStreamsUpdated
quando um participante remoto adiciona ou remove um VideoStream de/para a chamada.
Como seu aplicativo pode reagir ao evento?
Se o aplicativo estava processando um fluxo que foi removido. Seu aplicativo deve interromper 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 objeto AudioEffectsFeature
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, o effectsStarted
será acionado.
Como seu aplicativo pode reagir ao evento?
Seu aplicativo pode exibir ou habilitar um botão que permite ao usuário desabilitar 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á acionado.
Como seu aplicativo pode reagir ao evento?
Seu aplicativo pode exibir ou habilitar um botão que permite que o usuário habilite o efeito de áudio.
Exemplo de código:
audioEffectsFeature.on('effectsStopped', (effects) => {
startEffectButton.style.visibility = "visible";
});
Evento: effectsError
Esse evento ocorre quando acontece um erro enquanto um efeito de áudio é iniciado ou aplicado.
Como seu aplicativo pode reagir ao evento?
Seu aplicativo deve exibir um alerta ou uma mensagem de erro informando 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`);
});
Instalar o SDK
Localize o arquivo build.gradle
de nível do projeto e adicione mavenCentral()
à lista de repositórios em buildscript
e allprojects
:
buildscript {
repositories {
...
mavenCentral()
...
}
}
allprojects {
repositories {
...
mavenCentral()
...
}
}
Em seguida, no arquivo build.gradle
no nível do módulo, adicione as seguintes linhas à seção dependencies
:
dependencies {
...
implementation 'com.azure.android:azure-communication-calling:1.0.0'
...
}
Inicializar objetos necessários
Para criar uma instância CallAgent
, você precisa chamar o método createCallAgent
em uma instância CallClient
. Essa chamada retorna de forma assíncrona um objeto de instância CallAgent
.
O método createCallAgent
usa CommunicationUserCredential
como argumento, que encapsula um token de acesso.
Para acessar DeviceManager
, você deverá criar uma instância callAgent
primeiro. Em seguida, você poderá usar o método CallClient.getDeviceManager
para obter DeviceManager
.
String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an activity, for instance
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential).get();
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
Para definir um nome de exibição para o chamador, use este método alternativo:
String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an activity, for instance
CallAgentOptions callAgentOptions = new CallAgentOptions();
callAgentOptions.setDisplayName("Alice Bob");
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential, callAgentOptions).get();
Com o nosso SDK do Android, você pode assinar a maioria das propriedades e coleções para ser notificado quando os valores forem alterados.
Propriedades
Para assinar eventos property changed
:
// 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, associe-os 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. O Java está criando instâncias desses ouvintes e não referenciando aquelas criadas anteriormente. Eles ainda serão disparados corretamente, mas não será possível removê-los devido à ausência de referência a eles.
Coleções
Para assinar eventos collection updated
:
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);
Configurar o backup do sistema
Siga essas etapas para configurar seu sistema.
Criar o projeto do Xcode
No Xcode, crie um projeto do iOS e selecione o modelo Aplicativo de Modo de Exibição Único. Como este artigo usa a estrutura SwiftUI, defina Linguagem como Swift e Interface como SwiftUI.
Você não criará testes neste artigo. Fique à vontade para limpar a caixa de seleção Incluir Testes.
Instalar o pacote e as dependências usando o CocoaPods
Crie um Podfile para seu aplicativo, como este exemplo:
platform :ios, '13.0' use_frameworks! target 'AzureCommunicationCallingSample' do pod 'AzureCommunicationCalling', '~> 1.0.0' end
Execute
pod install
.Abra o
.xcworkspace
usando o Xcode.
Solicitar acesso ao microfone
Para acessar o microfone do dispositivo, você precisa atualizar a lista de propriedades de informações do aplicativo usando NSMicrophoneUsageDescription
. Defina o valor associado como uma cadeia de caracteres incluída na caixa de diálogo que é usada pelo sistema para solicitar o acesso do usuário.
Clique com o botão direito do mouse na entrada Info.plist da árvore de projeto e selecione Abrir Como>Código-Fonte. Adicione as linhas a seguir na seção do nível superior<dict>
e, em seguida, salve o arquivo.
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>
Configurar o framework de aplicativos
Abra o arquivo ContentView.swift
do projeto. Adicione uma declaração import
à parte superior do arquivo para importar a biblioteca AzureCommunicationCalling
. Além disso, importeAVFoundation
. Você precisa dele para solicitações de permissão de áudio no código.
import AzureCommunicationCalling
import AVFoundation
Inicialização do CallAgent
Para criar umaCallAgent
instânciaCallClient
,você precisa usar um método callClient.createCallAgent
que retorne de modo assíncrono um objetoCallAgent
depois que ele for inicializado.
Para criar um cliente de chamada, passe um objeto CommunicationTokenCredential
:
import AzureCommunication
let tokenString = "token_string"
var userCredential: CommunicationTokenCredential?
do {
let options = CommunicationTokenRefreshOptions(initialToken: token, refreshProactively: true, tokenRefresher: self.fetchTokenSync)
userCredential = try CommunicationTokenCredential(withOptions: options)
} catch {
updates("Couldn't created Credential object", false)
initializationDispatchGroup!.leave()
return
}
// tokenProvider needs to be implemented by Contoso, which fetches a new token
public func fetchTokenSync(then onCompletion: TokenRefreshOnCompletion) {
let newToken = self.tokenProvider!.fetchNewToken()
onCompletion(newToken, nil)
}
Passe o objeto CommunicationTokenCredential
que você criou para CallClient
e defina o nome de exibição:
self.callClient = CallClient()
let callAgentOptions = CallAgentOptions()
options.displayName = " iOS Azure Communication Services User"
self.callClient!.createCallAgent(userCredential: userCredential!,
options: callAgentOptions) { (callAgent, error) in
if error == nil {
print("Create agent succeeded")
self.callAgent = callAgent
} else {
print("Create agent failed")
}
})
Com o nosso SDK do iOS, você pode assinar a maioria das propriedades e coleções para ser notificado quando os valores forem alterados.
Propriedades
Para assinarproperty changed
os 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 assinarcollection updated
os 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