Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Recomendamos assinar os eventos do SDK de chamadas. Os SDKs dos Serviços de Comunicação do Azure são dinâmicos e contêm propriedades que podem ser alteradas ao longo do tempo. Você pode assinar esses eventos para ser notificado antes de qualquer alteração. Siga as instruções neste artigo para assinar eventos do SDK dos Serviços de Comunicação do Azure.
Eventos no SDK de Chamada de Comunicação do Azure
Esta seção descreve os eventos e as alterações de propriedade aos quais seu aplicativo pode se inscrever. 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 de Chamada dos Serviços de Comunicação do Azure. O acompanhamento de eventos ajuda você a realizar alterações sem implementar um mecanismo de pull nos objetos do SDK.
Esta seção 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 Adicionar chamada de voz ao seu aplicativo.
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 inscrever-se em eventos de objeto. Use o método off() para cancelar a inscrição em 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 \<collection>Updated evento para receber notificações sobre alterações em uma coleção de objetos. O \<collection>Updated evento é 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 matrizaddedque contém valores que foram adicionados à coleção. - O conteúdo do evento
'<collection>Updated'também tem uma matrizremovedque 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 incomingCall evento é acionado quando o cliente recebe uma chamada de entrada.
Como seu aplicativo reage ao evento?
Seu aplicativo deve notificar o destinatário da chamada de entrada. O prompt de notificação precisa permitir que o destinatário aceite ou recuse a chamada.
Exemplo de código:
callClient.on('incomingCall', (async (incomingCallEvent) => {
try {
// Store a reference to the call object
incomingCall = incomingCallEvent.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 operador de chamadas. Esse evento ocorre quando o usuário faz, recebe ou encerra a chamada.
Como seu aplicativo reage 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 reage 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 stateChanged evento é acionado quando o estado da chamada é alterado. Por exemplo, quando uma chamada vai de connected para disconnected.
Como seu aplicativo reage 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 idChanged evento é 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 reage ao evento?
Seu aplicativo pode salvar a nova ID de chamada ou recuperá-la do objeto de chamada posteriormente, 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 é acionado quando o áudio local é mudo ou desativado.
Como seu aplicativo reage ao evento?
Seu aplicativo deve atualizar o botão desativar notificação/ativar notificação para o estado correto.
Exemplo de código:
call.on('isMutedChanged', (async (isMutedChangedEvent) => {
microphoneButton.disabled = call.isMuted;
});
Evento: isScreenSharingOnChanged
O isScreenSharingOnChanged evento é acionado quando o compartilhamento de tela para o usuário local está habilitado ou desabilitado.
Como seu aplicativo reage ao evento?
Seu aplicativo deve mostrar uma visualização e/ou um aviso ao usuário se o compartilhamento de tela estiver ativado.
Se o compartilhamento de tela estiver 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 ou desabilita seu vídeo local.
Como seu aplicativo reage 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', () => {
showDisableCameraButton(call.isLocalVideoStarted);
});
Evento: remoteParticipantsUpdated
Seu aplicativo deve assinar os eventos para cada RemoteParticipants adicionado e cancelar a assinatura dos eventos dos participantes que saírem da chamada.
Como seu aplicativo reage 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
// - unsubscribe from the remote participants events
// - update the UI
removeParticipant(participant);
});
});
Evento: localVideoStreamsUpdated
O localVideoStreamsUpdated evento é 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 reage 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 remoteAudioStreamsUpdated evento é acionado quando a lista do fluxo de áudio remoto é alterada. Essas alterações ocorrem quando os participantes remotos adicionam ou removem fluxos de áudio à chamada.
Como seu aplicativo reage 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 reage 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 reage ao evento?
Seu aplicativo deve habilitar ou desabilitar o botão com base na nova função do usuário.
Exemplo de código:
call.on('roleChanged', () => {
this.roleElement = call.role;
});
Evento: mutedByOthers
O mutedByOthers evento ocorre quando o participante local silencia outros participantes na chamada.
Como seu aplicativo reage ao evento?
Seu aplicativo deve exibir uma mensagem para o usuário informando que ele está no modo silencioso.
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. Isso ocorre quando um chamador altera o nome de exibição.
Como seu aplicativo reage 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. Isso ocorre quando um remetente altera seu nome de exibição.
Como seu aplicativo reage 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 RemoteParticipant é alterada na chamada. Um exemplo seria quando o RemoteParticipant se tornar apresentador ACSCallParticipantRolePresenter em uma chamada.
Como seu aplicativo reage 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 evento isMutedChanged é acionado quando um dos RemoteParticipant ativa ou desativa o mudo do microfone.
Como seu aplicativo reage 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 reage 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;
});
remoteParticipant.on('displayNameChanged', (args: {newValue?: string, oldValue?: string, reason?: DisplayNameChangedReason}) => {
remoteParticipant.nameLabel.innerText = remoteParticipant.displayName;
console.log(`Display name changed from ${oldValue} to ${newValue} due to ${reason}`);
});
Evento: isSpeakingChanged
O isSpeakingChanged quando o alto-falante dominante em uma chamada é alterado.
Como seu aplicativo reage ao evento?
A interface do seu aplicativo deve priorizar a exibição do RemoteParticipant 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 reage ao evento?
Se o aplicativo estava processando um fluxo que foi removido, seu aplicativo deve interromper o processamento. Quando um novo fluxo é adicionado, recomendamos que seu aplicativo comece a 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 é acionado.
Como seu aplicativo reage 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 é acionado.
Como seu aplicativo reage 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 reage 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();
Agora que você instalou o SDK do Android, você pode assinar a maioria das propriedades e coleções a serem notificadas 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. Para adicionar e remover métodos de ouvinte, passe a variável como um argumento.
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 disparam corretamente, mas não podem ser removidos porque você não tem mais uma 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' endExecute
pod install.Abra o
.xcworkspaceusando 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 umaCallAgentinstânciaCallClient,você precisa usar um método callClient.createCallAgentque retorne de modo assíncrono um objetoCallAgentdepois que ele for inicializado.
Para criar um cliente de chamada, passe um objeto CommunicationTokenCredential:
import AzureCommunication
let tokenString = "token_string"
var userCredential: CommunicationTokenCredential?
do {
let options = CommunicationTokenRefreshOptions(initialToken: token, refreshProactively: true, tokenRefresher: self.fetchTokenSync)
userCredential = try CommunicationTokenCredential(withOptions: options)
} catch {
updates("Couldn't created Credential object", false)
initializationDispatchGroup!.leave()
return
}
// tokenProvider needs to be implemented by Contoso, which fetches a new token
public func fetchTokenSync(then onCompletion: TokenRefreshOnCompletion) {
let newToken = self.tokenProvider!.fetchNewToken()
onCompletion(newToken, nil)
}
Passe o objeto CommunicationTokenCredential que você criou para CallClient e defina o nome de exibição:
self.callClient = CallClient()
let callAgentOptions = CallAgentOptions()
options.displayName = " iOS Azure Communication Services User"
self.callClient!.createCallAgent(userCredential: userCredential!,
options: callAgentOptions) { (callAgent, error) in
if error == nil {
print("Create agent succeeded")
self.callAgent = callAgent
} else {
print("Create agent failed")
}
})
Agora que você instalou o SDK do iOS, você pode assinar a maioria das propriedades e coleções a serem notificadas 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