Partager via


Gérer les appels

Découvrez comment gérer les appels avec les kits de développement logiciel (SDK) Azure Communication Services. Nous allons apprendre à passer des appels, ainsi qu’à gérer leurs participants et leurs propriétés.

Prérequis

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

Comment gérer au mieux la connectivité du 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 « individuel » à un(e) utilisateur(-trice), 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 RTC. Pour l’accès au programme en préversion, faites une demande d’inscription au programme Utilisateur précoce.

Pour un appel 1:1 à un numéro de réseau téléphonique commuté, 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 de réseau téléphonique commuté, 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 en savoir plus sur rooms, vous pouvez lire la documentation conceptuelle ou suivre le guide de démarrage rapide.

Rejoindre un appel de groupe

Remarque

Considéré comme des métadonnées système, le paramètre groupId peut être utilisé par Microsoft pour les opérations nécessaires à l’exécution du 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 cameraStartFailed : diagnostic d’appel vrai si la caméra n’est pas disponible lors du démarrage, de l’acceptation ou de la jonction d’un appel avec la 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 parce qu’elle 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 appel actif (dans un état Connected, avec un média actif). Tous les autres appels doivent être mis en attente par un utilisateur ou programmatiquement par application. Cela 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, tous les appels inactifs doivent être mis en attente, et l’utilisateur doit interagir avec d’autres utilisateurs uniquement dans l’appel actif

Pour conserver ou reprendre l’appel, vous pouvez utiliser les API asynchrones hold et resume :

Pour maintenir l’appel

await call.hold();

Lorsque hold API est résolue, l’état de l’appel est défini sur LocalHold. Dans un appel individuel, l’autre participant(e) est également mis(e) en attente et l’état de l’appel du point de vue de ce(tte) participant(e) 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’API resume est résolue, l’état de l’appel est à nouveau défini sur Connected.

Activer et désactiver le son d’un appel

Pour activer ou désactiver le son du point de terminaison local, vous pouvez utiliser 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 activer ou désactiver le son entrant, vous pouvez utiliser les API 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). Le son de l’appel n’est pas entendu dans le haut-parleur et le participant ou la participante ne peut pas l’écouter tant que la fonction « call.unmuteIncomingAudio() » n’est pas appelée. Toutefois, nous pouvons appliquer un filtre sur l’audio d’appel et lire l’audio filtré.

Gérer les participants distants

Tous les participants à distance sont détaillés dans RemoteParticipantl’objet et sont disponibles par le biais deremoteParticipants la collection sur une instance d’appel. Le remoteParticipants est accessible à partir d’une instance de Call.

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 (que ce soit un utilisateur ou un numéro de téléphone) à un appel, vous pouvez utiliser l’API addParticipant. Fournissez l’un des types Identifier. Il renvoie l’instance remoteParticipant de manière synchrone. L’événement remoteParticipantsUpdated à partir de l’appel est déclenché lorsqu’un participant est correctement ajouté à l’appel.

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 résout le problème de façon asynchrone une fois le participant supprimé 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 : sonnerie en cours chez le participant.
    • 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 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(e) participant(e) distant(e) peut être dans l’appel à partir de nombreux points de terminaison, et chaque point de terminaison a son propre participantId unique. participantId est différent de l’ID brut de RemoteParticipant.identifier.

Désactiver le son des autres participants

Remarque

Pour utiliser cette API, utilisez la version du kit de développement logiciel (SDK) Web d’appel à Azure Communication Services version 1.26.1 ou ultérieure.

Pour désactiver le son de tous les autres participants ou désactiver le son d’un participant en particulier qui est 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 a été désactivé par d’autres personnes.

Remarque : les scénarios consistant à désactiver le son des participants RTC (numéro de téléphone) ou des participants d’appel 1:1 ne sont pas pris en charge.

//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 SDK d’appel web dans de nombreux points de terminaison, et chaque point de terminaison a ses propres participantIduniques. 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 examinant la collection remoteParticipants sur 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’API localVideoStreams renvoie des objets LocalVideoStream ou tape Video, ScreenSharing ou 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;

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 méthode CallAgent.startCall() et fournir le Identifier du ou des appelé(s). Pour rejoindre un appel de groupe, vous devez appeler la méthode CallAgent.join() et fournir l’ID de groupe. 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 RTC. 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 RTC, vous devez spécifier le numéro de téléphone de l’appelé. Votre ressource Communication Services doit être configurée de manière à autoriser 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 méthode « accept » sur un objet call.

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

L’appel entrant peut être obtenu en s’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 méthode CallAgent.join retourne un seul objet Call :

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 en savoir plus sur rooms, vous pouvez lire la documentation conceptuelle ou suivre le guide de démarrage rapide.

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 méthode « join » et transmettre un objet avec une propriété groupId. 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 représentant l’état actuel d’un appel :

  • « NONE » : État initial de l’appel
  • « 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 passé ou accepté
  • « RINGING » : Pour un appel sortant, indique que l’appel sonne pour les participants distants
  • « CONNECTED » : L’appel est connecté
  • « LOCAL_HOLD »  L’appel est mis en attente par un participant local, aucun média ne circule entre le point de terminaison local et les participants distants
  • « REMOTE_HOLD » : L’appel est mis en attente par un participant distant, aucun média ne circule entre le point de terminaison local et les participants distants
  • « DISCONNECTING » : État de transition avant que l’appel passe à l’état « Déconnecté »
  • « 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 de l’arrêt de l’appel, examinez 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 vous êtes en communication, les clés de volume matériel sur le téléphone doivent autoriser l’utilisateur à modifier le volume d’appel. Cette opération est effectuée en utilisant la méthode setVolumeControlStream avec le type de flux AudioManager.STREAM_VOICE_CALL sur l’Activité d’où est passé l’appel. Cela 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 une valeur similaire sur le curseur de volume), empêchant ainsi de modifier le volume pour d’autres profils audio, comme les alarmes, les médias ou le volume pour l’ensemble du système. Pour plus d’informations, vous pouvez vérifier la 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 sont représentés par le type RemoteParticipant et sont disponibles via la collection remoteParticipants 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 addParticipant. Cette opération renvoie 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 removeParticipant. Le problème sera résolu de façon asynchrone une fois le participant supprimé de l’appel. Le participant sera également supprimé de la collection remoteParticipants.

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é dispose d’un ensemble de propriétés et de collections qui lui sont associées :

  • Obtenez l’identificateur de ce participant distant. L’identité est l’un des types d’identificateurs

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

    ParticipantState state = remoteParticipant.getState();
    

Il peut s’agir de l’un des états suivants :

  • « IDLE » : État initial

  • « EARLY_MEDIA » : Une annonce est lue avant que le participant soit connecté à l’appel

  • « RINGING » : Sonnerie en cours chez le participant

  • « CONNECTING » : État transitoire 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 est en salle d’attente et attend son éventuelle admission. 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, inspectez 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 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

Pour utiliser cette API, utilisez la version du kit de développement logiciel (SDK) Android d’appel à Azure Communication Services version 2.11.0 ou ultérieure.

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

call.muteAllRemoteParticipants();

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

remoteParticipant.mute();

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

Utilisation de services de premier plan

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

Grâce aux services de premier plan, vous pouvez, par exemple, conserver une notification visible par l’utilisateur lorsque un appel est actif sur votre application. Ainsi, même si l’utilisateur accède à l’écran d’accueil ou supprime l’application de l’écran des applications récentes, l’appel restera 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 lorsque vous démarrez ou joignez un appel, par exemple :

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

Et arrêtez le service de premier plan lorsque vous raccrochez l’appel ou que l’état de l’appel est Déconnecté, par exemple :

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

Notes sur l’utilisation de services de premier plan

Gardez à l’esprit que des scénarios tels que l’arrêt d’un service de premier plan déjà en cours d’exécution lorsque l’application est supprimée de la liste des applications récentes supprimeront la notification visible par l’utilisateur et que le système d’exploitation Android peut maintenir le processus de votre application en vie pendant une période supplémentaire, ce qui signifie que l’appel peut encore être actif pendant cette période.

Si votre application arrête le service de premier plan sur la méthode onTaskRemoved du service, par exemple, votre application peut démarrer ou arrêter l’audio et la vidéo en fonction du cycle de vie de votre activité, comme en arrêtant l’audio et la vidéo lorsque votre activité est détruite avec le remplacement 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 complet :

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

Quand l’application implémente les 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, lorsqu’un objet RemoteParticipant est retourné lors de l’appel de la méthode call.addParticipant et que l’application définit le délégué pour l’écoute du trafic sur RemoteParticipantDelegate, l’application doit contenir une référence forte à l’objet RemoteParticipant. Sinon, si cet objet est collecté, le délégué 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 recevrez 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 plusieurs 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 RTC. Pour l’accès au programme en préversion, faites une demande d’inscription au programme Utilisateur précoce.

Pour passer l’appel RTC, vous devez spécifier un numéro de téléphone acquis avec les services Azure Communication Services.

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 en savoir plus sur rooms, vous pouvez lire la documentation conceptuelle ou suivre le guide de démarrage rapide.

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 différentes opérations lors d’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

Tous les participants distants sont représentés par le type RemoteParticipant et sont disponibles via la collection remoteParticipants sur une instance d’appel.

Lister les participants d’un appel

call.remoteParticipants

Ajouter un participant à un appel

Pour ajouter un participant à un appel (un utilisateur ou un numéro de téléphone), vous pouvez appeler addParticipant. Cette commande retourne une instance de participant distant de façon synchrone.

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

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’API removeParticipant. Cela est résolu 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

Pour utiliser cette API, utilisez la version du kit de développement logiciel (SDK) iOS d’appel à Azure Communication Services version 2.13.0 ou ultérieure.

Pour désactiver le son de tous les autres participants dans un appel, utilisez l’API 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’API 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 participant local qu’il a été désactivé 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 d’application Windows 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 (SDK) Appel sont accessibles au public via un package NuGet.

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

  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.WindowsClient 1.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.

Demander l’accès au microphone

L’application nécessite l’accès au microphone pour qu’elle s’exécute correctement. Dans les applications UWP, la capacité du micro doit être déclarée dans le fichier manifeste de l’application.

Les étapes suivantes illustrent comment y parvenir.

  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 d’interface utilisateur pour passer et raccrocher l’appel

Cet exemple d’application simple contient deux boutons. Un pour passer l’appel et une autre pour raccrocher un appel passé. Les étapes suivantes illustrent comment ajouter ces 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>

Configuration de l’application avec les API du Kit de développement logiciel (SDK) 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# de ces espaces de noms, ce qui permet à IntelliSense de Visual Studio de faciliter le développement du 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 y ajouteront du code.

Autoriser les interactions avec l’application

Les boutons d’interface utilisateur précédemment ajoutés doivent fonctionner en même temps qu’un CommunicationCall passé. 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 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 Description
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 HangupOptions informe si un appel doit être arrêté à tous ses participants.

Initialiser 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.

Vous devez ajouter le code suivant dans une fonction d’assistance à appeler au cours de l’initialisation de l’application.

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’informations d’identification valide pour votre ressource. Référez-vous à la documentation relative aux jetons d’accès utilisateur si un jeton d’informations d’identification doit être sourcé.

Créer CallAgent et passer un appel

Les objets nécessaires à la création d’un objet CallAgent sont maintenant prêts. Il est temps de créer de façon asynchrone CallAgent et de passer un appel.

Le code suivant doit être ajouté après avoir traité 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;

N’hésitez pas à utiliser 8:echo123 pour parler au bot d’écho Azure Communication Services.

Activer et désactiver le son

Pour désactiver ou désactiver le son sortant, vous pouvez utiliser l’API MuteOutgoingAudioAsync et UnmuteOutgoingAudioAsync asynchrones :

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

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

Désactiver le son des autres participants

Remarque

Pour utiliser cette API, utilisez la version du kit de développement logiciel (SDK) Windows d’appel à Azure Communication Services version 1.9.0 ou ultérieure.

Pour désactiver le son de tous les autres participants ou désactiver le son d’un participant en particulier, vous pouvez utiliser les API asynchrones MuteAllRemoteParticipantsAsync 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 participant local qu’il a été désactivé par d’autres personnes, abonnez-vous à l’événement MutedByOthers.

Terminer un appel

Une fois qu’un appel est passé, la méthode HangupAsync de l’objet CommunicationCall doit être utilisée pour raccrocher l’appel.

Une instance HangupOptions doit également être utilisée pour indiquer à tous les participants si l’appel doit être interrompu.

Le code suivant doit être ajouté dans HangupButton_Click.

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

Exécuter le code

Vérifiez que Visual Studio génère l’application pour x64, x86 ou ARM64, puis appuyez sur F5 pour commencer à exécuter l’application. Après cela, cliquez sur le bouton Call pour passer un appel à l’appelé défini.

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

Étapes suivantes