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 umaadded
matriz que contém valores que foram adicionados à coleção. - A
'<collection>Updated'
carga útil do evento também tem umaremoved
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 LocalVideoStream
Call .
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 DeviceManager
o , 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 .
Instale 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 o
pod install
.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 CallClient
e 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