Partage via


Gérer les appels

Cet article explique comment gérer les appels à l’aide du Kit de développement logiciel (SDK) Azure Communication Services Calling. Les rubriques incluent la façon de passer des appels, de gérer les participants et de gérer les propriétés.

Prérequis

Soutien

Les tableaux suivants définissent la prise en charge des salles de répartition dans Azure Communication Services.

Identités et types d’appels

Le tableau suivant présente la prise en charge des fonctionnalités pour un type d'appel et une identité spécifiques.

Identities Réunion Teams Salle Appel 1:1 Appel de groupe Appel d’interopérabilité Teams 1:1 Appel d’interopérabilité Teams de groupe
Utilisateur de Communication Services ✔️ ✔️ ✔️ ✔️ ✔️ ✔️
Utilisateur Microsoft 365 ✔️ ✔️ ✔️

Opérations

Le tableau suivant présente la prise en charge des API individuelles dans le SDK d'appel, en lien avec les types d'identité individuels.

Opérations Utilisateur de Communication Services Utilisateur Microsoft 365
Démarrer un appel vers l'utilisateur d’Azure Communication Services ✔️
Démarrer un appel vers un utilisateur Microsoft 365 ✔️ ✔️
Démarrer un appel vers un numéro de téléphone ✔️ ✔️
Rejoindre une salle ✔️
Participer à une réunion Teams ✔️ ✔️
Rejoindre un appel en fonction de l'identifiant de groupe ✔️
Accepter ou rejeter l'appel entrant ✔️ ✔️
Maintenez et reprenez l’appel ✔️ ✔️
Obtenir des participants ✔️ ✔️
Ajouter un utilisateur des services de communication ✔️
Supprimer l'utilisateur Azure Communication Services ✔️ ✔️
Ajouter ou supprimer un utilisateur Microsoft 365 ✔️ ✔️
Ajouter ou supprimer un numéro de téléphone ✔️ ✔️
Activer ou désactiver le son d'un participant distant ✔️ [1] ✔️ [1]
Raccrocher ✔️ ✔️
Mettre fin à l'appel pour tout le monde ✔️ [2] ✔️

[1] L'API n'est prise en charge que dans les appels de groupe, les salles et les réunions Teams. [2] L'API n'est pas prise en charge dans les salles.

SDK

Les tableaux suivants présentent la prise en charge des fonctionnalités dans les kits SDK Azure Communication Services individuels.

État de la prise en charge Le Web Interface utilisateur web Ios Interface utilisateur iOS Android Interface utilisateur Android Fenêtres
Est pris en charge ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️

Installer le SDK

Utilisez la commande npm install pour installer le SDK Azure Communication Services Common et le SDK Azure Communication Services Calling pour JavaScript :

npm install @azure/communication-common --save
npm install @azure/communication-calling --save

Initialiser les objets nécessaires

Une instance CallClient est requise pour la plupart des opérations d’appel. Lorsque vous créez une instance CallClient, vous pouvez la configurer avec des options personnalisées comme une instance Logger.

Avec l’instance CallClient, vous pouvez créer une instance CallAgent en appelant createCallAgent. Cette méthode renvoie un objet d’instance CallAgent de manière asynchrone.

La méthode createCallAgent utilise CommunicationTokenCredential comme argument. Elle accepte un jeton d’accès utilisateur.

Vous pouvez utiliser la méthode getDeviceManager sur l’instance CallClient pour accéder à deviceManager.

const { CallClient } = require('@azure/communication-calling');
const { AzureCommunicationTokenCredential} = require('@azure/communication-common');
const { AzureLogger, setLogLevel } = require("@azure/logger");

// Set the logger's log level
setLogLevel('verbose');

// Redirect log output to console, file, buffer, REST API, or whatever location you want
AzureLogger.log = (...args) => {
    console.log(...args); // Redirect log output to console
};

const userToken = '<USER_TOKEN>';
callClient = new CallClient(options);
const tokenCredential = new AzureCommunicationTokenCredential(userToken);
const callAgent = await callClient.createCallAgent(tokenCredential, {displayName: 'optional Azure Communication Services user name'});
const deviceManager = await callClient.getDeviceManager()

Gérer la connectivité du Kit de développement logiciel (SDK) à l’infrastructure Microsoft

L’instance Call Agent vous aide à gérer les appels (pour rejoindre ou démarrer des appels). Pour fonctionner, votre SDK d’appel doit se connecter à l’infrastructure Microsoft pour recevoir des notifications d’appels entrants et coordonner d’autres détails de l’appel. Votre Call Agent a deux états possibles :

Connecté : un Call Agent dont la valeur connectionStatue est égale à Connected signifie que le SDK client est connecté et capable de recevoir des notifications de l’infrastructure Microsoft.

Déconnecté : un Call Agent dont la valeur connectionStatue est égale à Disconnected indique qu’un problème empêche le SDK de se connecter correctement. Call Agent doit être recréé.

  • invalidToken : si un jeton a expiré ou n’est pas valide, l’instance Call Agent se déconnecte avec cette erreur.
  • connectionIssue : en cas de problème de connexion du client à l’infrastructure Microsoft, après plusieurs tentatives, Call Agent lève l’erreur connectionIssue.

Vous pouvez vérifier si votre Call Agent local est connecté à l’infrastructure Microsoft en inspectant la valeur actuelle de la propriété connectionState. Pendant un appel actif, vous pouvez écouter l’événement connectionStateChanged pour déterminer si Call Agent passe de l’état connecté à l’état déconnecté.

const connectionState = callAgentInstance.connectionState;
console.log(connectionState); // it may return either of 'Connected' | 'Disconnected'

const connectionStateCallback = (args) => {
    console.log(args); // it will return an object with oldState and newState, each of having a value of either of 'Connected' | 'Disconnected'
    // it will also return reason, either of 'invalidToken' | 'connectionIssue'
}
callAgentInstance.on('connectionStateChanged', connectionStateCallback);

Passer un appel

Pour créer et démarrer un appel, utilisez l’une des API sur callAgent et fournissez un utilisateur que vous avez créé par le biais du SDK Identité Communication Services.

La création et le démarrage de l’appel sont synchrones. L’instance call vous permet de vous abonner à des événements d’appel.

Passer un appel 1:n à un utilisateur ou à un RTC

Pour appeler un autre utilisateur de Communication Services, utilisez la méthode startCall sur callAgent et transmettez le CommunicationUserIdentifier du destinataire que vous avez créé avec la bibliothèque d’administration de Communication Services.

Pour un appel 1:1 à un utilisateur, utilisez le code suivant :

const userCallee = { communicationUserId: '<ACS_USER_ID>' }
const oneToOneCall = callAgent.startCall([userCallee]);

Pour passer un appel à un réseau téléphonique commuté (RTC) public, utilisez la méthode startCall sur callAgent et transmettez le PhoneNumberIdentifier du destinataire. Votre ressource Communication Services doit être configurée pour autoriser l’appel RTC.

Quand vous appelez un numéro RTC, spécifiez votre ID d’appelant de substitution. Un ID d’appelant de substitution est un numéro de téléphone (basé sur la norme E.164) qui identifie l’appelant dans un appel RTPC. Il s’agit du numéro de téléphone que le destinataire de l’appel voit en tant qu’appel entrant.

Remarque

Consultez les détails de l’offre d’appels PSTN. Pour l’accès au programme en préversion, faites une demande d’inscription au programme Utilisateur précoce.

Pour un appel individuel à un numéro de téléphone, utilisez le code suivant :

const pstnCallee = { phoneNumber: '<ACS_USER_ID>' }
const alternateCallerId = {phoneNumber: '<ALTERNATE_CALLER_ID>'};
const oneToOneCall = callAgent.startCall([pstnCallee], { alternateCallerId });

Pour un appel 1:n à un utilisateur et un numéro PSTN, utilisez le code suivant :

const userCallee = { communicationUserId: '<ACS_USER_ID>' }
const pstnCallee = { phoneNumber: '<PHONE_NUMBER>'};
const alternateCallerId = {phoneNumber: '<ALTERNATE_CALLER_ID>'};
const groupCall = callAgent.startCall([userCallee, pstnCallee], { alternateCallerId });

Joindre un appel de salle

Pour joindre un appel room, vous pouvez instancier un objet de contexte avec la propriété roomId comme l’identificateur room. Pour joindre l’appel, utilisez la méthode join et transmettez l’instance de contexte.

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

room offre aux développeurs d’applications un meilleur contrôle sur qui peut participer à un appel, quand ces personnes se rencontrent et comment elles collaborent. Pour plus d’informations sur les salles, consultez l’API Salles pour les réunions structurées et participer à un appel de salle.

Rejoindre un appel de groupe

Remarque

Le groupId paramètre est les métadonnées système utilisées par Microsoft pour les opérations requises pour exécuter le système. N’incluez pas de données personnelles dans la valeur groupId. Microsoft ne traite pas ce paramètre comme des données personnelles et son contenu peut être visible pour les employés de Microsoft ou stocké à long terme.

Le paramètre groupId exige que les données soient au format GUID. Nous vous recommandons d’utiliser des GUID générés de manière aléatoire qui ne sont pas considérés comme des données personnelles dans vos systèmes.

Pour démarrer un nouvel appel de groupe ou rejoindre un appel de groupe, utilisez la méthode join et transmettez un objet avec une propriété groupId. La valeur groupId doit être un GUID

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

Recevoir un appel entrant

L’instance de callAgent émet un événement incomingCall quand l’identité connectée reçoit un appel entrant. Pour écouter cet événement, abonnez-vous en utilisant l’une des options suivantes :

const incomingCallHandler = async (args: { incomingCall: IncomingCall }) => {
    const incomingCall = args.incomingCall;

    // Get incoming call ID
    var incomingCallId = incomingCall.id

    // Get information about this Call. This API is provided as a preview for developers
    // and may change based on feedback that we receive. Do not use this API in a production environment.
    // To use this api please use 'beta' release of Azure Communication Services Calling Web SDK
    var callInfo = incomingCall.info;

    // Get information about caller
    var callerInfo = incomingCall.callerInfo

    // Accept the call
    var call = await incomingCall.accept();

    // Reject the call
    incomingCall.reject();

    // Subscribe to callEnded event and get the call end reason
     incomingCall.on('callEnded', args => {
        console.log(args.callEndReason);
    });

    // callEndReason is also a property of IncomingCall
    var callEndReason = incomingCall.callEndReason;
};
callAgentInstance.on('incomingCall', incomingCallHandler);

L’événement incomingCall comprend une instance incomingCall que vous pouvez accepter ou rejeter.

Le Kit de développement logiciel (SDK) Azure Communication Calling déclenche un diagnostic d’appel cameraStartFailed: true si l’appareil photo n’est pas disponible lors du démarrage, de l’acceptation ou de la jonction d’un appel avec une vidéo activée. Dans ce cas, l’appel commence par la vidéo désactivée. La caméra peut ne pas être disponible, car elle est utilisée par un autre processus ou est désactivée dans le système d’exploitation.

Maintenez et reprenez l’appel

Remarque

À un moment donné, il ne doit y avoir qu’un seul (1) appel actif, dans l'état Connected, avec des médias actifs. Tous les autres appels doivent être mis en attente par un utilisateur ou par le biais d'une application. Ce scénario est courant dans les scénarios tels que les centres de contacts, où un utilisateur peut avoir besoin de gérer plusieurs appels sortants et entrants. Dans ce cas, tous les appels inactifs doivent être mis en attente, et l’utilisateur doit interagir avec d’autres uniquement dans l’appel actif

Pour conserver ou reprendre l’appel, utilisez les API asynchrones hold et resume.

Pour maintenir l’appel :

await call.hold();

Lorsque hold l’opération est résolue, l’état de l’appel est défini sur LocalHold. Dans un appel de 1:1, l’autre participant est également mis en attente, et l’état de l’appel du point de vue de ce participant est défini sur RemoteHold. Plus tard, l’autre participant(e) pourrait mettre son appel en attente, ce qui entraînerait un changement d’état en LocalHold.

Dans un appel de groupe ou une réunion : le hold est une opération locale, elle ne tient pas l’appel pour d’autres participants à l’appel.

Pour reprendre l’appel, tous les utilisateurs qui ont lancé la mise en attente doivent la reprendre.

Pour reprendre l’appel en attente :

await call.resume();

Lorsque l’opération resume est résolue, l’état d’appel est à nouveau réglé sur Connected.

Activer et désactiver le son d’un appel

Pour désactiver ou réactiver le point de terminaison local, utilisez les API asynchrones mute et unmute :

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

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

Désactiver et désactiver le son entrant

Désactiver le son entrant définit le volume d’appel sur 0. Pour désactiver ou réactiver le son entrant, utilisez les opérations asynchrones muteIncomingAudio et unmuteIncomingAudio.

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

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

Lorsque l’audio entrant est désactivé, le ou la participant(e) client SDK reçoit toujours l’audio de l’appel (audio du participant distant). L’audio de l’appel n’est pas entendu dans le haut-parleur et le participant n’est pas en mesure d’écouter jusqu’à ce que call.unmuteIncomingAudio() soit appelé. Toutefois, nous pouvons appliquer un filtre sur l’audio d’appel et lire l’audio filtré.

Gérer les participants distants

Tous les participants distants sont inclus dans l’objet RemoteParticipant et disponibles via la remoteParticipants collection sur une instance d’appel. L’objet remoteParticipants est accessible à partir d’une Call instance.

Lister les participants à un appel

La collection remoteParticipants retourne une liste de participants distants à un appel :

call.remoteParticipants; // [remoteParticipant, remoteParticipant....]

Ajouter un participant à un appel

Pour ajouter un participant (un utilisateur ou un numéro de téléphone) à un appel, utilisez l’opération addParticipant . Fournissez l’un des types Identifier. Il renvoie l’instance remoteParticipant de manière synchrone. Lorsqu'un(e) participant(e) est ajouté(e) avec succès à l'appel, il déclenche l'événement remoteParticipantsUpdated de Call.

const userIdentifier = { communicationUserId: '<ACS_USER_ID>' };
const pstnIdentifier = { phoneNumber: '<PHONE_NUMBER>' }
const remoteParticipant = call.addParticipant(userIdentifier);
const alternateCallerId = {  phoneNumber: '<ALTERNATE_CALLER_ID>' };
const remoteParticipant = call.addParticipant(pstnIdentifier, { alternateCallerId });

Supprimer un participant d’un appel

Pour supprimer un participant (un utilisateur ou un numéro de téléphone) d’un appel, vous pouvez appeler removeParticipant. Vous devez passer l’un des types Identifier. Cette méthode se résout de façon asynchrone après avoir supprimé le participant de l’appel. Le participant est également supprimé de la collection remoteParticipants.

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

Accéder aux propriétés des participants distants

Un ensemble de propriétés et de collections sont associées aux participants distants :

  • CommunicationIdentifier : obtenez l’identificateur d’un participant distant. L’identité correspond à l’un des types CommunicationIdentifier :

    const identifier = remoteParticipant.identifier;
    
  • Les types CommunicationIdentifier possibles sont les suivants :

    • { communicationUserId: '<ACS_USER_ID'> } : Objet représentant l’utilisateur Azure Communication Services.
    • { phoneNumber: '<E.164>' } : objet représentant le numéro de téléphone au format E.164.
    • { microsoftTeamsUserId: '<TEAMS_USER_ID>', isAnonymous?: boolean; cloud?: "public" | "dod" | "gcch" } : objet représentant l’utilisateur de Teams.
    • { id: string } : objet représentant un identificateur qui ne correspond à aucun autre type d’identificateur
  • state : obtenez l’état d’un participant distant.

    const state = remoteParticipant.state;
    
  • L’état peut être :

    • Idle : état initial.
    • Connecting : état transitoire pendant qu’un participant se connecte à l’appel.
    • Ringing : Le participant est en train de recevoir un appel.
    • Connected : le participant est connecté à l’appel.
    • Hold : le participant est en attente.
    • EarlyMedia : annonce qui est lue avant qu’un participant ne se connecte à l’appel.
    • InLobby : indique que le participant distant est en salle d’attente.
    • Disconnected : état final. Le participant est déconnecté de l’appel. Si le participant distant perd sa connectivité réseau, son état passe à Disconnected au bout de deux minutes.
  • callEndReason : pour savoir pourquoi un participant a quitté l’appel, vérifiez la propriété callEndReason :

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

    Remarque

    Cette propriété est définie uniquement lors de l’ajout d’un participant distant via l’API Call.addParticipant() et le participant distant refuse par exemple.

    Dans le scénario, où UserB lance UserC, du point de vue de UserA, UserA ne voit pas cet indicateur être défini pour UserC. En d’autres termes, UserA ne voit pas la propriété callEndReason de UserC définie.

  • État isMuted : pour savoir si le son d’un participant est désactivé, vérifiez la propriété isMuted. Elle retourne Boolean.

    const isMuted = remoteParticipant.isMuted;
    
  • État isSpeaking : pour savoir si un participant à distance parle, vérifiez la propriété isSpeaking. Elle retourne Boolean.

    const isSpeaking = remoteParticipant.isSpeaking;
    
  • videoStreams : pour inspecter tous les flux vidéo qu’un participant donné envoie dans cet appel, vérifiez la collection videoStreams. Elle contient des objets RemoteVideoStream.

    const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
    
  • displayName : pour obtenir le nom complet de ce participant distant, inspectez la propriété displayName. Elle retourne une chaîne.

    const displayName = remoteParticipant.displayName;
    
  • endpointDetails: obtenir les détails de tous les points de terminaison pour ce participant distant

    const endpointDetails: EndpointDetails[] = remoteParticipant.endpointDetails;
    

    Remarque

    Un participant à distance peut être dans l’appel à partir de nombreux points de terminaison possibles, et chaque point de terminaison a son propre participantId unique. participantId est différent de l’ID brut de l’identificateur RemoteParticipant .

Désactiver le son des autres participants

Remarque

Pour désactiver le son d’autres participants VoIP, vous devez utiliser azure Communication Services Calling Web SDK version 1.26.1 ga ou ultérieure. Pour désactiver le son des points de terminaison PSTN, vous devez utiliser la version GA 1.33.1 du WebJS (ou version ultérieure).

Remarque

La mise en sourdine des autres participants lors d'un appel en tête-à-tête n'est pas prise en charge.

Pour couper le son de tous les autres participants ou d'un participant spécifique connecté à un appel, vous pouvez utiliser les API asynchrones muteAllRemoteParticipants sur l'appel et mute sur le participant distant. L’événement mutedByOthers de l’appel est déclenché lorsque le participant local est désactivé par d’autres personnes.

La mise en sourdine d'un point de terminaison PSTN avec le SDK WebJS de téléphonie est actuellement en disponibilité générale et disponible dans la version 1.34.1 1.34.1 et les versions ultérieures.

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

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

Vérifier les propriétés de l’appel

Obtenez l’ID unique (string) d’un appel :

const callId: string = call.id;

Obtenez l’ID du participant ou de la participante local(e) :

const participantId: string = call.info.participantId;

Remarque

Une identité Azure Communication Services peut utiliser le Kit de développement logiciel (SDK) d’appel web dans de nombreux points de terminaison, et chaque point de terminaison a sa propre identité unique participantId. participantId diffère de l’ID brut de l’identité Azure Communication Services.

Récupérez l’ID de thread si vous participez à une réunion Teams :

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

Obtenir des informations sur l’appel :

const callInfo = call.info;

Découvrez les autres participants à l’appel en inspectant la collection remoteParticipants de l’instance call :

const remoteParticipants = call.remoteParticipants;

Identifiez l’appelant d’un appel entrant :

const callerIdentity = call.callerInfo.identifier;

identifier correspond à l’un des types CommunicationIdentifier.

Obtenez l’état d’un appel :

const callState = call.state;

Retourne une chaîne représentant l’état actuel d’un appel :

  • None : état initial de l’appel.
  • Connecting : état de transition initial quand un appel est passé ou accepté.
  • Ringing : pour un appel sortant, indique qu’il sonne pour les participants distants. Il s’agit Incoming de leur côté.
  • EarlyMedia : indique un état dans lequel une annonce est lue avant la connexion de l’appel.
  • Connected : indique que l’appel est connecté.
  • LocalHold : Indique qu’un(e) participant(e) local(e) a mis l’appel en attente. Aucun média ne circule entre le point de terminaison local et les participants distants.
  • RemoteHold : Indique qu’un(e) participant(e) distant(e) a mis l’appel en attente. Aucun média ne circule entre le point de terminaison local et les participants distants.
  • InLobby : indique que l’utilisateur est en salle d’attente.
  • Disconnecting : état de transition avant que l’appel ne passe à l’état Disconnected.
  • Disconnected : état d’appel final. Si la connexion réseau est perdue, l’état passe à Disconnected au bout de deux minutes.

Découvrez pourquoi un appel s’est terminé en examinant la propriété callEndReason :

const callEndReason = call.callEndReason;
const callEndReasonMessage = callEndReason.message // (string) user friendly message
const callEndReasonCode = callEndReason.code // (number) code associated with the reason
const callEndReasonSubCode = callEndReason.subCode // (number) subCode associated with the reason

Découvrez si l’appel en cours est entrant ou sortant en inspectant la propriété direction. Elle retourne CallDirection.

const isIncoming = call.direction == 'Incoming';
const isOutgoing = call.direction == 'Outgoing';

Inspectez les flux vidéo actifs et les flux de partage d’écran actifs en vérifiant la collection localVideoStreams. L’opération localVideoStreams retourne LocalVideoStream des objets de type Video, ScreenSharingou RawMedia.

const localVideoStreams = call.localVideoStreams;

Vérifiez si le microphone actuel est désactivé. Elle retourne Boolean.

const muted = call.isMuted;

Vérifiez si l’audio entrant actuel (haut-parleur) est désactivé. Elle retourne Boolean.

const incomingAudioMuted = call.isIncomingAudioMuted;

Vérifiez si la vidéo est activée. Elle retourne Boolean.

const isLocalVideoStarted = call.isLocalVideoStarted;

Vérifiez que le partage d’écran est activé. Elle retourne Boolean.

const isScreenSharingOn = call.isScreenSharingOn;

Raccrocher

Il existe deux façons de raccrocher l’appel.

  • L’appelant initial peut quitter l’appel et les autres participants restent dans l’appel.
  • Lorsque l’appelant initial quitte, l’appel s’arrête pour tous les participants.

Pour quitter l’appel, utilisez :

call.hangUp();

Termine l’appel pour tous les participants en fournissant HangUpOptions.

Remarque

Cette opération n’est pas disponible dans les salles.

call.hangUp( forEveryone: true);

Installer le SDK

Recherchez votre fichier build.gradle au niveau du projet et ajoutez mavenCentral() à la liste des référentiels sous buildscript et allprojects :

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

Ensuite, dans votre fichier build.gradle au niveau du module, ajoutez les lignes suivantes à la section dependencies :

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

Initialiser les objets nécessaires

Pour créer une instance CallAgent, vous devez appeler la méthode createCallAgent sur une instance CallClient. Cet appel retourne de façon asynchrone un objet d’instance CallAgent.

La méthode createCallAgent prend CommunicationUserCredential en tant qu’argument, qui encapsule un jeton d’accès.

Pour accéder à DeviceManager, vous devez d’abord créer une instance callAgent. Vous pouvez ensuite utiliser la méthode CallClient.getDeviceManager pour obtenir 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();

Pour définir un nom d’affichage pour l’appelant, utilisez cette autre méthode :

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

Passer un appel

Pour créer et démarrer un appel, vous devez appeler la CallAgent.startCall() méthode et fournir le Identifier destinataire ou les destinataires.

Pour joindre un appel de groupe, vous devez appeler la CallAgent.join() méthode et fournir le groupId. Les ID de groupe doivent être au format GUID ou UUID.

La création et le démarrage de l’appel sont synchrones. L’instance d’appel vous permet de vous abonner à tous les événements de l’appel.

Passer un appel 1:1 à un utilisateur

Pour passer un appel à un autre utilisateur de Communication Services, appelez la méthode call sur callAgent et transmettez un objet avec la clé communicationUserId.

StartCallOptions startCallOptions = new StartCallOptions();
Context appContext = this.getApplicationContext();
CommunicationUserIdentifier acsUserId = new CommunicationUserIdentifier(<USER_ID>);
CommunicationUserIdentifier participants[] = new CommunicationUserIdentifier[]{ acsUserId };
call oneToOneCall = callAgent.startCall(appContext, participants, startCallOptions);

Passer un appel 1:n avec des utilisateurs et un RTC

Remarque

Consultez les détails de l’offre d’appels PSTN. Pour l’accès au programme en préversion, faites une demande d’inscription au programme Utilisateur précoce.

Pour passer un appel 1 :n à un utilisateur et un numéro de réseau téléphonique commuté (PSTN), vous devez spécifier le numéro de téléphone du destinataire ou des destinataires.

Votre ressource Communication Services doit être configurée pour activer l’appel RTC :

CommunicationUserIdentifier acsUser1 = new CommunicationUserIdentifier(<USER_ID>);
PhoneNumberIdentifier acsUser2 = new PhoneNumberIdentifier("<PHONE_NUMBER>");
CommunicationIdentifier participants[] = new CommunicationIdentifier[]{ acsUser1, acsUser2 };
StartCallOptions startCallOptions = new StartCallOptions();
Context appContext = this.getApplicationContext();
Call groupCall = callAgent.startCall(participants, startCallOptions);

Accepter un appel

Pour accepter un appel, appelez la accept méthode sur un objet d’appel.

Context appContext = this.getApplicationContext();
IncomingCall incomingCall = retrieveIncomingCall();
Call call = incomingCall.accept(context).get();

Pour accepter un appel avec la caméra vidéo activée, procédez comme suit :

Context appContext = this.getApplicationContext();
IncomingCall incomingCall = retrieveIncomingCall();
AcceptCallOptions acceptCallOptions = new AcceptCallOptions();
VideoDeviceInfo desiredCamera = callClient.getDeviceManager().get().getCameraList().get(0);
acceptCallOptions.setVideoOptions(new VideoOptions(new LocalVideoStream(desiredCamera, appContext)));
Call call = incomingCall.accept(context, acceptCallOptions).get();

Obtenez l’appel entrant en vous abonnant à l’événement onIncomingCall sur l’objet callAgent.

// Assuming "callAgent" is an instance property obtained by calling the 'createCallAgent' method on CallClient instance 
public Call retrieveIncomingCall() {
    IncomingCall incomingCall;
    callAgent.addOnIncomingCallListener(new IncomingCallListener() {
        void onIncomingCall(IncomingCall inboundCall) {
            // Look for incoming call
            incomingCall = inboundCall;
        }
    });
    return incomingCall;
}

Joindre un appel de salle

Utilisez CallAgent et RoomCallLocator pour joindre un appel de salle en spécifiant un roomId. La CallAgent.join méthode retourne un Call objet :

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

room offre aux développeurs d’applications un meilleur contrôle sur qui peut participer à un appel, quand ces personnes se rencontrent et comment elles collaborent. Pour plus d’informations sur les salles, consultez l’API Salles pour les réunions structurées et participer à un appel de salle.

Rejoindre un appel de groupe

Pour démarrer un nouvel appel de groupe ou rejoindre un appel de groupe en cours, vous devez appeler la join méthode et passer un objet avec une groupId propriété. La valeur doit être un GUID.

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

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

Propriétés d’appel

Obtenir l’ID unique de cet appel :

String callId = call.getId();

Pour en savoir plus sur les autres participants de l’appel, examinez la collection remoteParticipant sur l’instance call :

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

L’identité de l’appelant si l’appel est entrant :

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

Obtenir l’état de l’appel :

CallState callState = call.getState();

Retourne une chaîne de caractères représentant l’état actuel d’un appel.

  • NONE - état d’appel initial
  • EARLY_MEDIA – indique un état dans lequel une annonce est lue avant la connexion de l’appel
  • CONNECTING - État de transition initial une fois l’appel placé ou accepté
  • RINGING - pour un appel sortant - indique que l’appel sonne pour les participants distants
  • CONNECTED – appel connecté
  • LOCAL_HOLD - appel placé en attente par le participant local sans flux multimédia entre le point de terminaison local et les participants distants
  • REMOTE_HOLD - appel placé en attente par un participant distant sans flux multimédia entre le point de terminaison local et les participants distants
  • DISCONNECTING - état de transition avant que l’appel ne passe à Disconnected l’état
  • DISCONNECTED – état d’appel final
  • IN_LOBBY : En salle d’attente pour l’interopérabilité d’une réunion Teams

Pour connaître la raison pour laquelle l'appel s'est terminé, inspectez la propriété callEndReason. Il contient le code/sous-code :

CallEndReason callEndReason = call.getCallEndReason();
int code = callEndReason.getCode();
int subCode = callEndReason.getSubCode();

Pour voir si l’appel en cours est un appel entrant ou sortant, inspectez la propriété callDirection :

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

Pour voir si le microphone actuel est désactivé, inspectez la propriété muted :

boolean muted = call.isMuted();

Pour inspecter les flux vidéo actifs, vérifiez la collection localVideoStreams :

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

Activer et désactiver le son

Pour activer ou désactiver le son du point de terminaison local, vous pouvez utiliser les API asynchrones mute et unmute :

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

Modifier le volume de l’appel

Pendant que les participants sont dans un appel, les clés de volume matériel sur le téléphone doivent permettre à l’utilisateur de modifier le volume d’appel.

Utilisez la méthode setVolumeControlStream avec le type AudioManager.STREAM_VOICE_CALL de flux sur l’activité où l’appel se produit.

Cette méthode permet aux clés de volume matériel de modifier le volume de l’appel, indiqué par une icône de téléphone ou quelque chose de similaire sur le curseur de volume. Il empêche également les modifications apportées au volume par d’autres profils sonores, tels que les alarmes, les médias ou le volume à l’échelle du système. Pour plus d’informations, consultez Gestion des modifications dans la sortie audio | Développeurs Android.

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

Gestion des participants distants

Tous les participants distants ont le RemoteParticipant type et sont disponibles via la remoteParticipants collection sur une instance d’appel.

Lister les participants d’un appel

La collection remoteParticipants renvoie une liste de participants distants dans un appel donné :

List<RemoteParticipant> remoteParticipants = call.getRemoteParticipants(); // [remoteParticipant, remoteParticipant....]

Ajouter un participant à un appel

Pour ajouter un participant à un appel (un utilisateur ou un numéro de téléphone), vous pouvez appeler l’opération addParticipant .

Cette opération retourne de façon synchrone l’instance de participant distant.

const acsUser = new CommunicationUserIdentifier("<acs user id>");
const acsPhone = new PhoneNumberIdentifier("<phone number>");
RemoteParticipant remoteParticipant1 = call.addParticipant(acsUser);
AddPhoneNumberOptions addPhoneNumberOptions = new AddPhoneNumberOptions(new PhoneNumberIdentifier("<alternate phone number>"));
RemoteParticipant remoteParticipant2 = call.addParticipant(acsPhone, addPhoneNumberOptions);

Supprimer un participant d’un appel

Pour supprimer un participant d’un appel (un utilisateur ou un numéro de téléphone), vous pouvez appeler l’opération removeParticipant .

Cette opération se résout de façon asynchrone une fois que le participant est supprimé de l’appel.

Le participant est également supprimé de la remoteParticipants collection.

RemoteParticipant acsUserRemoteParticipant = call.getParticipants().get(0);
RemoteParticipant acsPhoneRemoteParticipant = call.getParticipants().get(1);
call.removeParticipant(acsUserRemoteParticipant).get();
call.removeParticipant(acsPhoneRemoteParticipant).get();

Propriétés du participant distant

Tout participant distant donné a un ensemble de propriétés et de collections associées :

  • Obtenez l’identificateur de ce participant distant.

L’identité correspond à l’un des types Identifier :

CommunicationIdentifier participantIdentifier = remoteParticipant.getIdentifier();
  • Obtenez l’état de ce participant distant.

    ParticipantState state = remoteParticipant.getState();
    

L’état peut être l’un des suivants :

  • IDLE - état initial

  • EARLY_MEDIA - l’annonce est jouée avant que le participant soit connecté à l’appel

  • RINGING - l’appel du participant sonne

  • CONNECTING - État de transition pendant que le participant se connecte à l’appel

  • CONNECTED - le participant est connecté à l’appel

  • HOLD - le participant est en attente

  • IN_LOBBY - le participant attend dans la salle d’attente pour être admis. Actuellement utilisé uniquement dans le scénario d’interopération Teams

  • DISCONNECTED - état final - le participant est déconnecté de l’appel

  • Pour savoir pourquoi un participant a quitté l’appel, vérifiez la propriété callEndReason :

    CallEndReason callEndReason = remoteParticipant.getCallEndReason();
    
  • Pour vérifier si le son de ce participant distant est activé ou non, inspectez la propriété isMuted :

    boolean isParticipantMuted = remoteParticipant.isMuted();
    
  • Pour vérifier si ce participant à distance parle ou non, inspectez la propriété isSpeaking :

    boolean isParticipantSpeaking = remoteParticipant.isSpeaking();
    
  • Pour inspecter tous les flux vidéo qu’un participant donné envoie dans cet appel, vérifiez la collection videoStreams :

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

Désactiver le son des autres participants

Remarque

Utilisez le Kit de développement logiciel (SDK) Android d’appel d’Azure Communication Services version 2.11.0 ou ultérieure.

Lorsqu’un participant RTC est désactivé, il reçoit une annonce indiquant qu’il est désactivé et qu’il peut appuyer sur une combinaison de touches (par exemple * 6) pour se désactiver. Quand ils appuient sur *6, leur micro est réactivé.

Pour désactiver le son de tous les autres participants dans un appel, utilisez l’opération d’API muteAllRemoteParticipants .

call.muteAllRemoteParticipants();

Pour désactiver le son d’un participant distant spécifique, utilisez l’opération mute d’API sur un participant distant donné.

remoteParticipant.mute();

Pour avertir le ou la participant(e) local(e) qu’il ou elle a été désactivé(e) par d’autres personnes, abonnez-vous à l’événement onMutedByOthers.

Utilisation de services de premier plan

Si vous souhaitez exécuter une tâche visible par l’utilisateur même lorsque votre application est en arrière-plan, vous pouvez utiliser les services de premier plan.

Utilisez les services de premier plan, par exemple, pour fournir aux utilisateurs une notification visible lorsque votre application a un appel actif. De cette façon, même si l’utilisateur accède à l’écran d’accueil ou supprime l’application de l’écran récent, l’appel continue d’être actif.

Si vous n’utilisez pas de service de premier plan pendant un appel, le fait de naviguer vers l’écran d’accueil peut maintenir l’appel actif, mais le fait de supprimer l’application de l’écran des applications récentes peut arrêter l’appel si le système d’exploitation Android tue le processus de votre application.

Vous devez démarrer le service de premier plan lorsqu’un utilisateur démarre ou rejoint un appel, par exemple :

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

Vous devez également arrêter le service de premier plan lorsque vous raccrochez l'appel ou lorsque l'appel est déconnecté, par exemple :

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

Détails du service de premier plan

N’oubliez pas que les scénarios comme l’arrêt d’un service de premier plan déjà actif lorsque l’application est supprimée par la liste des applications récentes suppriment la notification visible par l’utilisateur(-trice). Dans ce cas, le système d’exploitation Android peut maintenir le processus de votre application actif pendant une période supplémentaire, ce qui signifie que l’appel peut rester actif pendant cette période.

Si votre application arrête le service de premier plan sur la méthode de service onTaskRemoved , par exemple, votre application peut démarrer ou arrêter l’audio et la vidéo en fonction de votre cycle de vie d’activité. Par exemple, l’arrêt de l’audio et de la vidéo lorsque votre activité est détruite avec la redéfinition de la méthode onDestroy.

Configurer votre système

Effectuez les étapes suivantes pour configurer votre système.

Créer le projet Xcode

Dans Xcode, créez un projet iOS et sélectionnez le modèle Single View App. Cet article utilise l’infrastructure SwiftUI. Vous devez donc définir Langage sur Swift et Interface sur SwiftUI.

Vous n’allez pas créer de tests dans cet article. N’hésitez pas à désactiver la case Inclure des tests.

Capture d’écran montrant la fenêtre de création d’un projet dans Xcode.

Installer le package et les dépendances à l’aide de CocoaPods

  1. Créez un Podfile pour votre application, comme cet exemple :

    platform :ios, '13.0'
    use_frameworks!
    target 'AzureCommunicationCallingSample' do
        pod 'AzureCommunicationCalling', '~> 1.0.0'
    end
    
  2. Exécutez pod install.

  3. Ouvrez .xcworkspace en utilisant Xcode.

Demander l’accès au microphone

Pour accéder au microphone de l’appareil, vous devez mettre à jour la liste des propriétés d’informations de votre application à l’aide de NSMicrophoneUsageDescription. Définissez la valeur associée à une chaîne qui est incluse dans la boîte de dialogue utilisée par le système pour demander l’accès à l’utilisateur.

Cliquez avec le bouton droit sur l’entrée Info.plist de l’arborescence du projet, puis sélectionnez Ouvrir en tant que>Code source. Ajoutez les lignes suivantes à la section <dict> tout en haut, puis enregistrez le fichier.

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

Configurer le framework d’application

Ouvrez le fichier ContentView.swift de votre projet. Ajoutez une déclaration import en haut du fichier pour importer la bibliothèque AzureCommunicationCalling. En outre, importez AVFoundation. Vous en avez besoin pour les demandes d’autorisations audio dans le code.

import AzureCommunicationCalling
import AVFoundation

Initialiser CallAgent

Pour créer une instance de CallAgent à partir de CallClient, vous devez utiliser une méthode callClient.createCallAgent qui retourne de manière asynchrone un objet CallAgent après qu’il a été initialisé.

Pour créer un client d’appel, transmettez un objet 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)
}

Transmettez l’objet CommunicationTokenCredential que vous avez créé à CallClient, et définissez le nom d'affichage :

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

Remarque

Lorsque l’application implémente des délégués d’événements, elle doit contenir une référence forte aux objets qui nécessitent des abonnements aux événements. Par exemple, lorsque vous appelez la call.addParticipant méthode et qu’elle retourne un RemoteParticipant objet. Ensuite, l’application définit le ou la délégué(e) à écouter RemoteParticipantDelegate et l’application doit contenir une référence forte à l’objet RemoteParticipant. Sinon, si cet objet est collecté, le ou la délégué(e) génère une exception irrécupérable quand le SDK Calling tente d’appeler l’objet.

Passer un appel sortant

Pour créer et démarrer un appel, vous devez appeler l’une des API sur CallAgent et fournir l’identité Azure Communication Services d’un utilisateur que vous avez provisionné en utilisant le SDK de management des services de communication.

La création et le démarrage de l’appel sont synchrones. Vous recevez une instance d’appel qui vous permet de vous abonner à tous les événements de l’appel.

Passer un appel 1:1 à un utilisateur ou un appel 1:n avec des utilisateurs et RTC

let callees = [CommunicationUser(identifier: 'UserId')]
self.callAgent?.startCall(participants: callees, options: StartCallOptions()) { (call, error) in
     if error == nil {
         print("Successfully started outgoing call")
         self.call = call
     } else {
         print("Failed to start outgoing call")
     }
}

Passer un appel 1:n avec des utilisateurs et un RTC

Remarque

Consultez les détails de l’offre d’appels PSTN. Pour l’accès au programme en préversion, faites une demande d’inscription au programme Utilisateur précoce.

Pour passer un appel 1 :n impliquant un utilisateur et un réseau téléphonique commuté public (PSTN), vous devez spécifier un numéro de téléphone obtenu via les services de communication.

let pstnCallee = PhoneNumberIdentifier(phoneNumber: '+1999999999')
let callee = CommunicationUserIdentifier('UserId')
self.callAgent?.startCall(participants: [pstnCallee, callee], options: StartCallOptions()) { (groupCall, error) in
     if error == nil {
         print("Successfully started outgoing call to multiple participants")
         self.call = groupCall
     } else {
         print("Failed to start outgoing call to multiple participants")
     }
}

Joindre un appel de salle

Pour joindre un appel room, spécifiez la propriété roomId comme l’identificateur room. Pour joindre l’appel, utilisez la méthode join et transmettez roomCallLocator.

func joinRoomCall() {
    if self.callAgent == nil {
        print("CallAgent not initialized")
        return
    }
    
    if (self.roomId.isEmpty) {
        print("Room ID not set")
        return
    }
    
    // Join a call with a Room ID
    let options = JoinCallOptions()
    let audioOptions = AudioOptions()
    audioOptions.muted = self.muted
    
    options.audioOptions = audioOptions
    
    let roomCallLocator = RoomCallLocator(roomId: roomId)
    self.callAgent!.join(with: roomCallLocator, joinCallOptions: options) { (call, error) in
        self.setCallAndObserver(call: call, error: error)
    }
}

room offre aux développeurs d’applications un meilleur contrôle sur qui peut participer à un appel, quand ces personnes se rencontrent et comment elles collaborent. Pour plus d’informations sur les salles, consultez l’API Salles pour les réunions structurées et participer à un appel de salle.

Rejoindre un appel de groupe

Pour rejoindre un appel, vous devez appeler l’une des API sur CallAgent.

let groupCallLocator = GroupCallLocator(groupId: UUID(uuidString: "uuid_string")!)
self.callAgent?.join(with: groupCallLocator, joinCallOptions: JoinCallOptions()) { (call, error) in
    if error == nil {
        print("Successfully joined group call")
        self.call = call
    } else {
        print("Failed to join group call")
    }
}

S’abonner à un appel entrant

Abonnez-vous à un événement d’appel entrant.

final class IncomingCallHandler: NSObject, CallAgentDelegate, IncomingCallDelegate
{
    // Event raised when there is an incoming call
    public func callAgent(_ callAgent: CallAgent, didReceiveIncomingCall incomingcall: IncomingCall) {
        self.incomingCall = incomingcall
        // Subscribe to get OnCallEnded event
        self.incomingCall?.delegate = self
    }

    // Event raised when incoming call was not answered
    public func incomingCall(_ incomingCall: IncomingCall, didEnd args: PropertyChangedEventArgs) {
        print("Incoming call was not answered")
        self.incomingCall = nil
    }
}

Acceptation d’un appel entrant

Pour accepter un appel, appelez la méthode accept sur un objet IncomingCall.

self.incomingCall!.accept(options: AcceptCallOptions()) { (call, error) in
   if (error == nil) {
       print("Successfully accepted incoming call")
       self.call = call
   } else {
       print("Failed to accept incoming call")
   }
}

let firstCamera: VideoDeviceInfo? = self.deviceManager!.cameras.first
localVideoStreams = [LocalVideoStream]()
localVideoStreams!.append(LocalVideoStream(camera: firstCamera!))
let acceptCallOptions = AcceptCallOptions()
acceptCallOptions.videoOptions = VideoOptions(localVideoStreams: localVideoStreams!)
if let incomingCall = self.incomingCall {
    incomingCall.accept(options: acceptCallOptions) { (call, error) in
        if error == nil {
            print("Incoming call accepted")
        } else {
            print("Failed to accept incoming call")
        }
    }
} else {
  print("No incoming call found to accept")
}

Effectuer des opérations durant l’appel

Vous pouvez effectuer des opérations pendant un appel pour gérer les paramètres liés à la vidéo et à l’audio.

Activer et désactiver le son

Pour activer ou désactiver le son du point de terminaison local, vous pouvez utiliser les API asynchrones mute et unmute.

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

Utilisez le code suivant pour désactiver le point de terminaison local de manière asynchrone.

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

Gérer les participants distants

Le RemoteParticipant type représente tous les participants distants. Ils sont disponibles via la remoteParticipants collection sur une instance d’appel.

Lister les participants d’un appel

call.remoteParticipants

Ajouter un participant à un appel

Pour ajouter un participant à un appel en tant qu’utilisateur ou numéro de téléphone, appelez l’opération addParticipant . Cette opération retourne de façon synchrone une instance de participant distant.

let remoteParticipantAdded: RemoteParticipant = call.add(participant: CommunicationUserIdentifier(identifier: "userId"))

Supprimer un participant d’un appel

Pour supprimer un participant d’un appel en tant qu’utilisateur ou numéro de téléphone, appelez l’opération removeParticipant . Cette opération se résout de façon asynchrone.

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

Obtenir les propriétés du participant distant

// [RemoteParticipantDelegate] delegate - an object you provide to receive events from this RemoteParticipant instance
var remoteParticipantDelegate = remoteParticipant.delegate

// [CommunicationIdentifier] identity - same as the one used to provision a token for another user
var identity = remoteParticipant.identifier

// ParticipantStateIdle = 0, ParticipantStateEarlyMedia = 1, ParticipantStateConnecting = 2, ParticipantStateConnected = 3, ParticipantStateOnHold = 4, ParticipantStateInLobby = 5, ParticipantStateDisconnected = 6
var state = remoteParticipant.state

// [Error] callEndReason - reason why participant left the call, contains code/subcode/message
var callEndReason = remoteParticipant.callEndReason

// [Bool] isMuted - indicating if participant is muted
var isMuted = remoteParticipant.isMuted

// [Bool] isSpeaking - indicating if participant is currently speaking
var isSpeaking = remoteParticipant.isSpeaking

// RemoteVideoStream[] - collection of video streams this participants has
var videoStreams = remoteParticipant.videoStreams // [RemoteVideoStream, RemoteVideoStream, ...]

Désactiver le son des autres participants

Remarque

Utilisez le SDK d'appels iOS d'Azure Communication Services, version 2.13.0 ou ultérieure.

Lorsqu’un participant RTC est désactivé, il reçoit une annonce indiquant qu’il est désactivé et qu’il peut appuyer sur une combinaison de touches (par exemple * 6) pour se désactiver. Quand ils appuient sur *6, leur micro est réactivé.

Pour désactiver le son de tous les autres participants d’un appel, utilisez l’opération muteAllRemoteParticipants sur l’appel.

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

Pour désactiver le son d’un participant distant spécifique, utilisez l’opération mute sur un participant distant donné.

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

Pour avertir le ou la participant(e) local(e) qu’il ou elle a été désactivé(e) par d’autres personnes, abonnez-vous à l’événement onMutedByOthers.

Configurer votre système

Effectuez les étapes suivantes pour configurer votre système.

Créer le projet Visual Studio

Pour une application de plateforme Windows universelle, dans Visual Studio 2022, créez un projet Application vide (Windows universel). Après avoir entré le nom du projet, n’hésitez pas à choisir un kit de développement logiciel (SDK) Windows d’une version ultérieure à 10.0.17763.0.

Pour une application WinUI 3, créez un projet avec le modèle Application vide, Empaquetée (WinUI 3 dans Desktop) pour configurer une application WinUI 3 monopage. Le SDK Windows App version 1.3 ou ultérieure est nécessaire.

Installer le package et les dépendances à l’aide du Gestionnaire de package NuGet

Les API et les bibliothèques du Kit de développement logiciel d'Appel (SDK) sont accessibles au public via un package NuGet.

Pour rechercher, télécharger et installer le package NuGet du SDK d'appels :

  1. Ouvrez le Gestionnaire de package NuGet en sélectionnant Outils>Gestionnaire de package NuGet>Gérer les packages NuGet pour la solution.
  2. Sélectionnez Parcourir, puis entrez Azure.Communication.Calling.WindowsClient dans la zone de recherche.
  3. Vérifiez que la case Inclure la préversion est cochée.
  4. Sélectionnez le package Azure.Communication.Calling.WindowsClient, puis Azure.Communication.Calling.WindowsClient1.4.0-beta.1 ou une version plus récente.
  5. Cochez la case qui correspond au projet Azure Communication Services dans le volet de droite.
  6. Sélectionnez Installer.

Implémenter l’exemple d’application dans Visual Studio

Cette section explique comment développer l’application pour gérer les appels fonctionnant dans Visual Studio.

Demander l’accès au microphone

L’application nécessite l’accès au microphone. Dans les applications de plateforme Windows universelle (UWP), la fonctionnalité de microphone doit être déclarée dans le fichier manifeste de l’application.

Pour accéder au microphone :

  1. Dans le panneau Solution Explorer, double-cliquez sur le fichier avec l’extension .appxmanifest.
  2. Cliquez sur l’onglet Capabilities.
  3. Cochez la case Microphone dans la liste des capacités.

Créer des boutons UI pour initier et raccrocher l’appel

Cet exemple d’application contient deux boutons. Un pour passer l’appel et une autre pour raccrocher un appel passé.

Ajoutez deux boutons à l’application.

  1. Dans le panneau Solution Explorer, double-cliquez sur le fichier nommé MainPage.xaml pour UWP, ou MainWindows.xaml pour WinUI 3.
  2. Dans le panneau central, recherchez le code XAML sous l’aperçu de l’interface utilisateur.
  3. Modifiez le code XAML en le remplaçant par l’extrait suivant :
<TextBox x:Name="CalleeTextBox" PlaceholderText="Who would you like to call?" />
<StackPanel>
    <Button x:Name="CallButton" Content="Start/Join call" Click="CallButton_Click" />
    <Button x:Name="HangupButton" Content="Hang up" Click="HangupButton_Click" />
</StackPanel>

Configurer l’application avec les API du Kit de développement logiciel (SDK) d’appel

Les API du Kit de développement logiciel (SDK) Appel se trouvent dans deux espaces de noms différents.

Les étapes suivantes informent le compilateur C# sur ces espaces de noms, ce qui permet à IntelliSense de Visual Studio d’aider au développement de code.

  1. Dans le panneau Solution Explorer, cliquez sur la flèche située sur le côté gauche du fichier nommé MainPage.xaml pour UWP, ou MainWindows.xaml pour WinUI 3.
  2. Double-cliquez sur le fichier nommé MainPage.xaml.cs ou MainWindows.xaml.cs.
  3. Ajoutez les commandes suivantes au bas des instructions using actuelles.
using Azure.Communication.Calling.WindowsClient;

Conservez MainPage.xaml.cs ou MainWindows.xaml.cs ouvert. Les étapes suivantes ajoutent du code.

Activer les interactions d’application

Les boutons d'interface utilisateur précédemment ajoutés doivent fonctionner au-dessus d'un CommunicationCall placé. Cela signifie qu’un membre de données CommunicationCall doit être ajouté à la classe MainPage ou MainWindow. En outre, pour permettre à l’opération asynchrone qui crée CallAgent de réussir, un membre de données CallAgent doit également être ajouté à la même classe.

Ajoutez les membres de données suivants à la classe MainPage pr MainWindow :

CallAgent callAgent;
CommunicationCall call;

Créer des gestionnaires de bouton

Précédemment, deux boutons d’interface utilisateur ont été ajoutés au code XAML. Le code suivant ajoute les gestionnaires à exécuter lorsqu’un utilisateur sélectionne le bouton. Le code suivant doit être ajouté après les membres de données de la section précédente.

private async void CallButton_Click(object sender, RoutedEventArgs e)
{
    // Start call
}

private async void HangupButton_Click(object sender, RoutedEventArgs e)
{
    // End the current call
}

Modèle d'objet

Les classes et les interfaces suivantes gèrent certaines des principales fonctionnalités de la bibliothèque de client Appel Azure Communication Services pour UWP.

Nom Descriptif
CallClient CallClient est le point d’entrée principal de la bibliothèque d’appels de client.
CallAgent CallAgent sert à lancer et à joindre des appels.
CommunicationCall CommunicationCall sert à gérer les appels passés ou rejoints.
CommunicationTokenCredential CommunicationTokenCredential sert de jeton d’informations d'identification pour initier le CallAgent.
CallAgentOptions Le CallAgentOptions contient des informations pour identifier l’appelant.
HangupOptions Le HangupOptions informe si un appel doit être arrêté à tous ses participants.

Initialiser le CallAgent

Pour créer une instance CallAgent à partir de CallClient, vous devez utiliser la méthode CallClient.CreateCallAgentAsync qui retourne de façon asynchrone un objet CallAgent une fois qu’il est initialisé.

Pour créer CallAgent, vous devez transmettre un objet CallTokenCredential et un objet CallAgentOptions. Gardez à l’esprit que CallTokenCredential lève une exception si un jeton malformé est transmis.

Pour appeler pendant l'initialisation de l'application, ajoutez le code suivant à l'intérieur d'une fonction d'assistance.

var callClient = new CallClient();
this.deviceManager = await callClient.GetDeviceManagerAsync();

var tokenCredential = new CallTokenCredential("<AUTHENTICATION_TOKEN>");
var callAgentOptions = new CallAgentOptions()
{
    DisplayName = "<DISPLAY_NAME>"
};

this.callAgent = await callClient.CreateCallAgentAsync(tokenCredential, callAgentOptions);

Modifiez le <AUTHENTICATION_TOKEN> avec un jeton d'accès valide pour votre ressource. Si vous devez obtenir un jeton d'authentification, consultez le jeton d'accès utilisateur.

Créer CallAgent et passer un appel

Les objets dont vous avez besoin pour créer un CallAgent sont maintenant prêts. Il est temps de créer de façon asynchrone CallAgent et de passer un appel.

Ajoutez le code suivant après avoir géré l’exception de l’étape précédente.

var startCallOptions = new StartCallOptions();
var callees = new [] { new UserCallIdentifier(CalleeTextBox.Text.Trim()) };

this.call = await this.callAgent.StartCallAsync(callees, startCallOptions);
this.call.OnStateChanged += Call_OnStateChangedAsync;

Utilisez cette option 8:echo123 pour communiquer avec le bot d’écho Azure Communication Services.

Activer et désactiver le son

Pour désactiver ou activer le son sortant, utilisez les opérations asynchrones MuteOutgoingAudioAsync et UnmuteOutgoingAudioAsync.

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

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

Désactiver le son des autres participants

Remarque

Utilisez le Kit de développement logiciel (SDK) Windows Azure Communication Services Calling version 1.9.0 ou ultérieure.

Lorsqu’un participant RTC est désactivé, il doit recevoir une annonce indiquant qu’il a été désactivé et qu’il peut appuyer sur une combinaison de touches (par exemple * 6) pour se désactiver. Lorsqu’ils appuient sur *6, ils doivent être activés.

Pour désactiver le son de tous les autres participants ou désactiver le son d’un participant spécifique, utilisez les opérations MuteAllRemoteParticipantsAsync asynchrones sur l’appel et MuteAsync sur le participant distant :

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

// mute specific participant in the call
await this.call.RemoteParticipants.FirstOrDefault().MuteAsync();

Pour avertir le ou la participant(e) local(e) qu’il ou elle a été désactivé(e) par d’autres personnes, abonnez-vous à l’événement MutedByOthers.

Terminer un appel

Une fois qu’un appel est placé, utilisez la HangupAsync méthode de l’objet CommunicationCall pour raccrocher l’appel.

Utilisez une instance de HangupOptions pour informer tous les participants si l’appel doit être terminé.

Ajoutez le code suivant à l’intérieur HangupButton_Click:

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

Exécuter le code

  1. Vérifiez que Visual Studio génère l’application pour x64, x86 ou ARM64.
  2. Appuyez sur F5 pour démarrer l’exécution de l’application.
  3. Une fois l’application en cours d’exécution, cliquez sur le bouton Appeler pour passer un appel au destinataire défini.

La première fois que l’application s’exécute, le système invite l’utilisateur à accorder l’accès au microphone.

Étapes suivantes