Verwalten von Anrufen

Lernen Sie, wie Sie Anrufe mit den Azure Communication Services SDKS verwalten können. Wir erfahren, wie Sie Anrufe tätigen sowie ihre Teilnehmer und Eigenschaften verwalten.

Voraussetzungen

Das SDK installieren

Verwenden Sie den Befehl npm install, um die Azure Communication Services Common und Calling SDKs für JavaScript zu installieren:

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

Initialisieren erforderlicher Objekte

Für die meisten Anrufvorgänge ist eine CallClient-Instanz erforderlich. Hier erstellen Sie eine neue CallClient-Instanz. Sie können sie mit benutzerdefinierten Optionen, etwa einer Logger-Instanz, konfigurieren.

Wenn Sie eine CallClient-Instanz verwenden, können Sie eine CallAgent-Instanz erstellen, indem Sie die Methode createCallAgent für die CallClient-Instanz aufrufen. Durch diese Methode wird ein CallAgent-Instanzobjekt asynchron zurückgegeben.

Die Methode createCallAgent verwendet CommunicationTokenCredential als Argument, welches ein Benutzerzugriffstoken akzeptiert.

Sie können die Methode getDeviceManager für die Instanz CallClient verwenden, um auf deviceManager zuzugreifen.

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

Tätigen eines Anrufs

Um einen Anruf zu erstellen und zu starten, verwenden Sie eine der APIs für callAgent, und geben Sie ein Benutzerkonto an, das Sie über das Communication Services Identity SDK erstellt haben.

Erstellung und Start des Anrufs erfolgen synchron. Die call-Instanz ermöglicht Ihnen das Abonnieren von Anrufereignissen.

Tätigen eines 1:n-Anrufs an einen Benutzer oder ein Telefonfestnetz

Um einen anderen Communication Services-Benutzer anzurufen, verwenden Sie die Methode startCall für callAgent, und übergeben Sie den CommunicationUserIdentifier, den Sie mit der Communication Services-Verwaltungsbibliothek erstellt haben.

Verwenden Sie für einen 1:1-Anruf bei einem Benutzer den folgenden Code:

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

Um einen Anruf an ein PSTN (Public Switched Telephone Network) zu tätigen, verwenden Sie die Methode startCall für callAgent, und übergeben Sie den PhoneNumberIdentifier des Empfängers. Die Communication Services-Ressource muss so konfiguriert werden, dass Anrufe über das Telefonfestnetz möglich sind.

Wenn Sie eine Telefonfestnetznummer anrufen, geben Sie Ihre alternative Anrufer-ID an. Eine alternative Anrufer-ID bezieht sich auf eine Telefonnummer (basierend auf dem E.164-Standard), die den Anrufer in einem PSTN-Anruf identifiziert. Dies ist die Telefonnummer, die dem Anrufempfänger bei einem eingehenden Anruf angezeigt wird.

Hinweis

Überprüfen Sie die Details des Telefonfestnetz-Anrufangebots. Um Zugriff auf das Vorschauprogramm zu erhalten, bewerben Sie sich für das Early Adopter-Programm.

Verwenden Sie für einen 1:1-Anruf einer PSTN-Nummer den folgenden Code:

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

Verwenden Sie für einen 1:N-Aufruf eines Benutzers und einer PSTN-Nummer den folgenden Code:

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

Teilnehmen an einem Raumanruf

Um einem room-Anruf beizutreten, können Sie ein Kontextobjekt mit der roomId-Eigenschaft als room-Bezeichner instanziieren. Wenn Sie an dem Anruf teilnehmen möchten, verwenden Sie die join-Methode und übergeben die Kontextinstanz.

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

Ein room bietet Anwendungsentwicklern bessere Kontrolle darüber, wer an einem Anruf teilnehmen kann, wann die Teilnehmer sich „treffen“ und wie sie zusammenarbeiten. Weitere Informationen zu rooms finden Sie in der konzeptionellen Dokumentation oder in der Schnellstartanleitung.

An einem Gruppenanruf teilnehmen

Hinweis

Der groupId-Parameter wird als Systemmetadaten angesehen und kann von Microsoft für Vorgänge verwendet werden, die zum Ausführen des Systems erforderlich sind. Fügen Sie keine personenbezogenen Daten in den groupId-Wert ein. Microsoft behandelt diesen Parameter nicht wie personenbezogene Daten. Seine Inhalte sind möglicherweise für Microsoft-Mitarbeiter sichtbar oder werden langfristig gespeichert.

Der groupId-Parameter erfordert, dass Daten im GUID-Format vorliegen. Es wird empfohlen, zufällig generierte GUIDs zu verwenden, die in Ihren Systemen nicht als personenbezogene Daten betrachtet werden.

Um einen neuen Gruppenanruf zu starten oder an einem aktuellen Gruppenanruf teilzunehmen, müssen Sie die Methode join aufrufen und ein Objekt mit einer groupId-Eigenschaft übergeben. Der groupId-Wert muss eine GUID sein.

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

Eingehenden Anruf entgegennehmen

Die callAgent-Instanz gibt das Ereignis incomingCall aus, wenn die angemeldete Identität einen eingehenden Anruf empfängt. Um auf dieses Ereignis zu lauschen, abonnieren Sie es mithilfe einer der folgenden Optionen:

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

Das incomingCall-Ereignis umfasst eine incomingCall-Instanz, die Sie akzeptieren oder ablehnen können.

Wird beim Starten, Beitreten oder Annehmen eines Anrufs mit eingeschaltetem Video die Kamera von einem anderen Prozess verwendet wird oder im System deaktiviert ist, wird der Anruf mit deaktiviertem Video gestartet und die Anrufdiagnose „cameraStartFailed: true“ ausgelöst.

Halten und Fortsetzen eines Anrufs

Hinweis

Zu einer Zeit sollte nur ein aktiver Anruf (im Connected-Zustand, mit aktiven Medien) vorhanden sein. Alle anderen Aufrufe sollten von einem Benutzer oder programmgesteuert von der Anwendung gehalten werden. Dies ist in Szenarien wie Call-Centern üblich, in denen ein Benutzer möglicherweise mehrere ausgehende und eingehende Anrufe verarbeiten muss, alle inaktiven Anrufe in die Warteschleife gesetzt werden sollen, und der Benutzer nur mit Personen im aktiven Anruf interagieren sollte.

Zum Halten oder Fortsetzen des Aufrufs können Sie die asynchronen hold- und resume-APIs verwenden:

So halten Sie den Anruf

await call.hold();

Beim Auslösen der hold-API wird der Anrufstatus auf LocalHold festgelegt, und wenn es sich um einen 1:1-Anruf handelt, wird der andere Teilnehmer ebenfalls gehalten, und der Status des Anrufs aus der Sicht dieses Teilnehmers wird auf „RemoteHold“ festgelegt. Der andere Teilnehmer kann seinen Anruf weiter halten, wodurch der Status in LocalHold geändert würde. Wenn es sich um einen Gruppenanruf handelt, ist hold lediglich ein lokaler Vorgang, und der Anruf für andere Teilnehmer dieses Anrufs nicht gehalten. Um diesen Anruf vollständig fortzusetzen, müssen alle Benutzer, die den Halteraum initiiert haben, ihn wieder aufnehmen.

So setzen Sie den Anruf aus dem Halteraum fort:

await call.resume();

Wenn die resume-API ausgelöst wird, wird der Aufrufstatus erneut auf Connected festgelegt.

Stummschalten und Aufheben der Stummschaltung für einen Anruf

Zum Stummschalten oder Aufheben der Stummschaltung des lokalen Endpunkts können Sie die asynchronen APIs mute und unmute verwenden:

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

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

Stummschalten und Aufheben der Stummschaltung eingehender Audiodaten

Das Stummschalten eingehender Audio legt die Anruflautstärke auf 0 fest. Zum Stummschalten oder Aufheben der Stummschaltung des eingehenden Tons können Sie die muteIncomingAudio und unmuteIncomingAudio asynchronen APIs verwenden:

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

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

Wenn das eingehende Audiosignal stummgeschaltet wird, empfängt das Client-SDK des Teilnehmers weiterhin das Anrufaudiosignal (Audio des Remoteteilnehmers). Das Audiosignal des Anrufs wird nicht im Lautsprecher wiedergegeben, und der Teilnehmer kann es erst hören, wenn „call.unmuteIncomingAudio()“ aufgerufen wird. Wir können jedoch Filter auf Anrufaudio anwenden und das gefilterte Audio wiedergeben.

Andere Teilnehmer stummschalten

Hinweis

Diese API wird als Vorschau für Entwickler bereitgestellt. Je nachdem, welches Feedback wir dazu erhalten, werden möglicherweise Änderungen vorgenommen. Verwenden Sie zum Verwenden dieser API die Betaversion des Azure Communication Services Calling Web SDK, Version 1.18.1 oder höher.

Um alle anderen Teilnehmer stummzuschalten oder einen bestimmten Teilnehmer stummzuschalten, können Sie die asynchronen APIs muteAllRemoteParticipants für den Anruf und mute für den Remote-Teilnehmer verwenden:

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

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

Verwalten von Remoteteilnehmern

Alle Remoteteilnehmer werden in der RemoteParticipant-API detailliert beschrieben und sind über die remoteParticipants-Sammlung in einer Anrufinstanz verfügbar.

Auflisten der Teilnehmer an einem Anruf

Die remoteParticipants-Sammlung gibt eine Liste der Remoteteilnehmer eines Anrufs zurück:

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

Hinzufügen eines Teilnehmers zu einem Anruf

Wenn Sie einem Anruf einen Teilnehmer (einen Benutzer oder eine Benutzerin oder eine Telefonnummer) hinzufügen möchten, können Sie die addParticipant-API verwenden. Geben Sie einen der Identifier-Typen an. Dadurch wird die Instanz remoteParticipant synchron zurückgegeben. Das Ereignis remoteParticipantsUpdated des Anrufs wird ausgelöst, wenn ein Teilnehmer erfolgreich dem Aufruf hinzugefügt wurde.

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

Entfernen eines Teilnehmers aus einem Anruf

Um einen Teilnehmer (einen Benutzer oder eine Telefonnummer) aus einem Anruf zu entfernen, können Sie removeParticipant aufrufen. Sie müssen einen der Identifier-Typen übergeben. Diese Methode wird asynchron aufgelöst, nachdem der Teilnehmer aus dem Anruf entfernt wurde. Der Teilnehmer wird auch aus der remoteParticipants-Sammlung entfernt.

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

Zugreifen auf Eigenschaften von Remoteteilnehmern

Remoteteilnehmern ist ein Satz von Eigenschaften und Sammlungen zugeordnet:

  • CommunicationIdentifier: Ruft den Bezeichner eines Remoteteilnehmers ab. „Identity“ ist einer der CommunicationIdentifier-Typen:
const identifier = remoteParticipant.identifier;
  • Mögliche CommunicationIdentifier-Typen:

    • { communicationUserId: '<ACS_USER_ID'> }: Objekt, das den Azure Communication Services-Benutzer darstellt.
    • { phoneNumber: '<E.164>' }: Objekt, das die Telefonnummer im E.164-Format darstellt.
    • { microsoftTeamsUserId: '<TEAMS_USER_ID>', isAnonymous?: boolean; cloud?: "public" | "dod" | "gcch" }: Objekt, das den Teams-Benutzer darstellt.
    • { id: string }: Objekt, das den Bezeichner darstellt, der keinem der anderen Bezeichnertypen entspricht.
  • state: Ruft den Zustand eines Remoteteilnehmers ab.

const state = remoteParticipant.state;
  • Mögliche Zustände:

    • Idle: Anfangszustand.
    • Connecting: Übergangszustand, während sich der Teilnehmer mit dem Anruf verbindet.
    • Ringing: Für den Teilnehmeranruf ertönt ein Klingeln.
    • Connected: Der Teilnehmer ist mit dem Anruf verbunden.
    • Hold: Der Teilnehmer wird gehalten.
    • EarlyMedia: Ansage, die vor dem Verbinden eines Teilnehmers mit dem Anruf wiedergegeben wird.
    • InLobby: Gibt an, dass sich der Remoteteilnehmer im Wartebereich befindet.
    • Disconnected: Abschließender Zustand. Der Teilnehmer wird vom Anruf getrennt. Wenn der Remoteteilnehmer seine Netzwerkkonnektivität verliert, ändert sich der Zustand nach zwei Minuten in Disconnected.
  • callEndReason: Um zu erfahren, warum ein Teilnehmer den Anruf verlassen hat, prüfen Sie die Eigenschaft 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
    

    Hinweis:

    • Diese Eigenschaft wird nur festgelegt, wenn sie einen Remoteteilnehmer über die Call.addParticipant()-API hinzufügen und der Remoteteilnehmer beispielsweise abgelehnt wird.
    • Wenn beispielsweise UserC von UserB gekickt wird, sieht UserA nicht, dass dieser Flag für UserC gesetzt wird. UserA bekommt vom Festlegen der callEndReason-Eigenschaft von UserC also überhaupt nichts mit.
  • isMuted-Status: Um herauszufinden, ob ein Remoteteilnehmer stummgeschaltet wurde, überprüfen Sie die Eigenschaft isMuted. Er gibt Boolean zurück.

    const isMuted = remoteParticipant.isMuted;
    
  • isSpeaking-Status: Um herauszufinden, ob ein Remoteteilnehmer gerade spricht, überprüfen Sie die Eigenschaft isSpeaking. Er gibt Boolean zurück.

    const isSpeaking = remoteParticipant.isSpeaking;
    
  • videoStreams: Um alle Videostreams zu prüfen, die ein bestimmter Teilnehmer im Rahmen dieses Anrufs sendet, sehen Sie sich die videoStreams-Sammlung an. Sie enthält RemoteVideoStream-Objekte.

    const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
    
  • displayName: Um den Anzeigenamen für diesen Remoteteilnehmer zu erhalten, überprüfen Sie die zurückgegebene Zeichenfolge der Eigenschaft displayName.

    const displayName = remoteParticipant.displayName;
    
  • endpointDetails: Abrufen der Details aller Endpunkte für diesen Remoteteilnehmer

        const endpointDetails: EndpointDetails[] = remoteParticipant.endpointDetails;
    

    Hinweis: Ein Remoteteilnehmer könnte sich von vielen Endpunkten aus im Anruf befinden, und jeder Endpunkt verfügt über einen eigenen eindeutigen participantId. participantId unterscheidet sich von der Raw-ID des RemoteParticipant.identifier.

Überprüfen von Anrufeigenschaften

Abrufen der eindeutigen ID (Zeichenfolge) für einen Anruf:

const callId: string = call.id;

Abrufen der lokalen Teilnehmer-ID:

const participantId: string = call.info.participantId;

Hinweis: Eine Azure Communication Services-Identität kann das Web Calling SDK in vielen Endpunkten verwenden, und jeder Endpunkt verfügt über einen eigenen eindeutigen participantId. participantId unterscheidet sich von der Raw-ID der Azure Communication Services-Identität.

Rufen Sie die Thread-ID ab, wenn Sie an einer Teams-Besprechung teilnehmen:

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

Abrufen von Informationen zum Anruf:

const callInfo = call.info;

Erhalten Sie Informationen zu anderen Anrufteilnehmern, indem Sie sich die remoteParticipants-Sammlung für die call-Instanz ansehen:

const remoteParticipants = call.remoteParticipants;

Identifizieren des Anrufers eines eingehenden Anrufs:

const callerIdentity = call.callerInfo.identifier;

identifier ist einer der CommunicationIdentifier-Typen.

Abrufen des Anrufzustands:

const callState = call.state;

Gibt eine Zeichenfolge zurück, die den aktuellen Zustand eines Anrufs darstellt:

  • None: anfänglicher Anrufzustand.
  • Connecting: anfänglicher Übergangszustand, wenn ein Anruf getätigt oder angenommen wird.
  • Ringing: Weist bei einem ausgehenden Anruf darauf hin, dass für den Anruf Remoteteilnehmer ein Klingeln ertönt. Auf deren Seite lautet der Status Incoming.
  • EarlyMedia: Gibt einen Zustand an, in dem vor dem Verbinden des Anrufs eine Ansage wiedergegeben wird.
  • Connected: Gibt an, dass der Anruf verbunden wurde.
  • LocalHold: Gibt an, dass der Anruf von einem lokalen Teilnehmer gehalten wird. Zwischen dem lokalen Endpunkt und den Remoteteilnehmern werden keine Medien übertragen.
  • RemoteHold: Gibt an, dass der Anruf von einem Remoteteilnehmer gehalten wird. Zwischen dem lokalen Endpunkt und den Remoteteilnehmern werden keine Medien übertragen.
  • InLobby: Gibt an, dass sich der Benutzer im Wartebereich befindet.
  • Disconnecting: Übergangszustand, bevor der Anruf in einen Disconnected-Zustand wechselt.
  • Disconnected: Abschließender Anrufzustand. Wenn die Netzwerkverbindung unterbrochen wird, ändert sich der Zustand nach zwei Minuten in Disconnected.

Ermitteln Sie, warum der Anruf beendet wurde, indem Sie die Eigenschaft callEndReason überprüfen:

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

Erfahren Sie, ob der aktuelle Anruf ein- oder ausgeht, indem Sie die Eigenschaft direction überprüfen. Er gibt CallDirection zurück.

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

Überprüfen Sie die aktiven Videodatenströme und Bildschirmfreigabe-Datenströme, indem Sie die localVideoStreams-Sammlung überprüfen. DielocalVideoStreams-API gibt LocalVideoStream,Objekte oder den Typ Video, ScreenSharing oder RawMedia zurück.

const localVideoStreams = call.localVideoStreams;

Stellen Sie fest, ob das aktuelle Mikrofon stummgeschaltet ist. Er gibt Boolean zurück.

const muted = call.isMuted;

Überprüfen Sie, ob das aktuelle eingehende Audio (Lautsprecher) stummgeschaltet ist. Er gibt Boolean zurück.

const incomingAudioMuted = call._isIncomingAudioMuted;

Überprüfen Sie, ob das Video aktiviert ist. Er gibt Boolean zurück.

const isLocalVideoStarted = call.isLocalVideoStarted;

Überprüfen Sie, ob die Bildschirmfreigabe aktiviert ist. Er gibt Boolean zurück.

const isScreenSharingOn = call.isScreenSharingOn;

Das SDK installieren

Wählen Sie Ihre Datei build.gradle auf Projektebene aus, und fügen Sie mavenCentral() zur Liste der Repositorys unter buildscript und allprojects hinzu:

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

Fügen Sie dann in der Datei build.gradle auf Modulebene die folgenden Zeilen zum Abschnitt dependencies hinzu:

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

Initialisieren der erforderlichen Objekte

Zum Erstellen einer CallAgent-Instanz müssen Sie die createCallAgent-Methode für eine CallClient-Instanz aufrufen. Dieser Aufruf gibt asynchron ein CallAgent-Instanzobjekt zurück.

Die createCallAgent-Methode verwendet CommunicationUserCredential als Argument, womit ein Zugriffstoken gekapselt wird.

Um auf DeviceManager zuzugreifen, müssen Sie zuerst eine callAgent-Instanz erstellen. Anschließend können Sie die CallClient.getDeviceManager-Methode zum Abrufen von DeviceManager verwenden.

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

Zum Festlegen eines Anzeigenamens für den Anrufer verwenden Sie diese alternative Methode:

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

Tätigen eines Anrufs

Um einen Anruf zu erstellen und zu starten, müssen Sie die CallAgent.startCall()-Methode aufrufen und den Identifier des/der Angerufenen angeben. Um an einem Gruppenanruf teilzunehmen, müssen Sie die CallAgent.join()-Methode aufrufen und die groupId angeben. Gruppen-IDs müssen das GUID- oder UUID-Format haben.

Erstellung und Start des Anrufs erfolgen synchron. Die Anrufinstanz ermöglicht Ihnen das Abonnieren aller Ereignisse im Rahmen des Anrufs.

Tätigen eines 1:1-Anrufs eines Benutzers

Um einen Anruf eines anderen Communication Services-Benutzers zu tätigen, rufen Sie die call-Methode für callAgent auf und übergeben ein Objekt mit communicationUserId-Schlüssel.

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

1:n-Anruf mit Benutzern und Festnetznummern

Hinweis

Überprüfen Sie die Details des Telefonfestnetz-Anrufangebots. Um Zugriff auf das Vorschauprogramm zu erhalten, bewerben Sie sich für das Early Adopter-Programm.

Für einen 1:n-Anruf eines Benutzers und einer Festnetznummer müssen Sie die Telefonnummer des Angerufenen angeben. Die Communication Services-Ressource muss so konfiguriert sein, dass Anrufe über das Telefonfestnetz möglich sind:

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

Einen Anruf annehmen

Zum Annehmen eines Anrufs rufen Sie die Methode „accept“ für ein Anrufobjekt auf.

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

Annehmen eines Anrufs mit eingeschalteter Videokamera:

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

Der eingehende Anruf kann durch Abonnieren des onIncomingCall-Ereignisses auf dem callAgent-Objekt abgerufen werden:

// 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;
}

Teilnehmen an einem Raumanruf

Verwenden Sie CallAgent und RoomCallLocator, an um einem Raumanruf teilzunehmen, indem Sie eine roomId angeben. Die CallAgent.join-Methode gibt ein Call-Objekt zurück:

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

Ein room bietet Anwendungsentwicklern bessere Kontrolle darüber, wer an einem Anruf teilnehmen kann, wann die Teilnehmer sich „treffen“ und wie sie zusammenarbeiten. Weitere Informationen zu rooms finden Sie in der konzeptionellen Dokumentation oder in der Schnellstartanleitung.

An einem Gruppenanruf teilnehmen

Um einen neuen Gruppenanruf zu starten oder an einem laufenden Gruppenanruf teilzunehmen, müssen Sie die „join“-Methode aufrufen und ein Objekt mit einer groupId-Eigenschaft übergeben. Der -Wert muss eine GUID sein.

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

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

Anrufeigenschaften

Ruft die eindeutige ID für diesen Anruf ab:

String callId = call.getId();

Um mehr über andere Anrufteilnehmer zu erfahren, sehen Sie sich die remoteParticipant-Sammlung für die call-Instanz an:

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

Die Identität des Anrufers bei einem eingehenden Anruf:

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

Ruft den Zustand des Anrufs ab:

CallState callState = call.getState();

Gibt eine Zeichenfolge zurück, die den aktuellen Zustand eines Anrufs darstellt:

  • „NONE“: ursprünglicher Anrufzustand
  • „EARLY_MEDIA“: gibt einen Zustand an, bei dem eine Ansage wiedergegeben wird, bevor der Anruf verbunden wird
  • „CONNECTING“: anfänglicher Übergangszustand, sobald ein Anruf getätigt oder angenommen wird
  • „RINGING“: für einen ausgehenden Anruf; gibt an, dass für den Anruf bei Remoteteilnehmern ein Klingeln ertönt
  • „CONNECTED“: der Anruf wurde verbunden
  • „LOCAL_HOLD“: Der Anruf wird vom lokalen Teilnehmer gehalten; es werden keine Medien zwischen lokalem Endpunkt und Remoteteilnehmern übertragen.
  • „REMOTE_HOLD“: Der Anruf wird von einem Remoteteilnehmer gehalten; es werden keine Medien zwischen lokalem Endpunkt und Remoteteilnehmern übertragen.
  • „DISCONNECTING“: Übergangsstatus, ehe der Anruf in den Zustand „Disconnected“ wechselt
  • „DISCONNECTED“: der Endzustand des Anrufs
  • „IN_LOBBY“: im Gespräch für eine Teams-Besprechungsinteroperabilität

Um zu erfahren, warum ein Anruf beendet wurde, überprüfen Sie die callEndReason-Eigenschaft. Sie enthält Code/Subcode:

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

Um festzustellen, ob der aktuelle Anruf ein- oder ausgehend ist, untersuchen Sie die callDirection-Eigenschaft:

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

Um festzustellen, ob das aktuelle Mikrofon stummgeschaltet ist, prüfen Sie die muted-Eigenschaft:

boolean muted = call.isMuted();

Um aktive Videostreams zu prüfen, sehen Sie sich die localVideoStreams-Sammlung an:

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

Stumm schalten aktiveren und deaktivieren

Zum Stummschalten oder Aufheben der Stummschaltung des lokalen Endpunkts können Sie die asynchronen APIs mute und unmute verwenden:

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

Andere Teilnehmer stummschalten

Hinweis

Diese API wird als öffentliche Vorschau für Entwickler bereitgestellt. Je nachdem, welches Feedback wir dazu erhalten, werden möglicherweise Änderungen vorgenommen. Um diese API zu verwenden, verwenden Sie bitte die Betaversion von Azure Communication Services Calling Android SDK, Version 2.6.0-beta.5 oder höher.

Um alle anderen Teilnehmer in einem Aufruf stummzuschalten, verwenden Sie die muteAllRemoteParticipants-API für den Aufruf.

call.muteAllRemoteParticipants();

Verwenden Sie die mute-API für einen bestimmten Remoteteilnehmer, um ihn stummzuschalten.

remoteParticipant.mute();

Ändern der Lautstärke des Anrufs

Während eines Anrufs sollten die Lautstärketasten des Telefons dem Benutzer die Möglichkeit geben, die Anruflautstärke zu ändern. Dies geschieht mithilfe der Methode setVolumeControlStream mit dem Streamtyp AudioManager.STREAM_VOICE_CALL für die Aktivität, bei der der Aufruf getätigt wird. Damit können Sie mit den Hardwarelautstärketasten die Lautstärke des Anrufs ändern (gekennzeichnet durch ein Telefonsymbol oder etwas Ähnliches auf dem Lautstärkeregler) und verhindern, dass Sie die Lautstärke für andere Klangprofile wie Alarme, Medien oder die systemweite Lautstärke ändern. Weitere Informationen finden Sie unter Behandeln von Änderungen an der Audioausgabe | Android-Entwickler.

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

Verwaltung von Remoteteilnehmern

Alle Remoteteilnehmer werden durch den Typ RemoteParticipant dargestellt und sind über die remoteParticipants-Sammlung für eine Anrufinstanz verfügbar.

Auflisten der Teilnehmer an einem Anruf

Die remoteParticipants-Sammlung gibt eine Liste der Remoteteilnehmer an einem angegebenen Anruf zurück:

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

Hinzufügen eines Teilnehmers zu einem Anruf

Um einen Teilnehmer einem Anruf hinzuzufügen (entweder als Benutzer oder Telefonnummer), können Sie addParticipant aufrufen. Dadurch wird die Instanz des Remoteteilnehmers synchron zurückgegeben.

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

Entfernen eines Teilnehmers aus einem Anruf

Um einen Teilnehmer aus einem Anruf zu entfernen (entweder als Benutzer oder Telefonnummer), können Sie removeParticipant aufrufen. Dieser Vorgang wird asynchron aufgelöst, sobald der Teilnehmer aus dem Anruf entfernt wurde. Der Teilnehmer wird auch aus der remoteParticipants-Sammlung entfernt.

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

Eigenschaften von Remoteteilnehmern

Einem Remoteteilnehmer sind eine Reihe von Eigenschaften und Sammlungen zugeordnet:

  • Ruft den Bezeichner dieses Remoteteilnehmers ab. „Identity“ ist einer der „Identifier“-Typen

    CommunicationIdentifier participantIdentifier = remoteParticipant.getIdentifier();
    
  • Ruft den Zustand dieses Remoteteilnehmers ab.

    ParticipantState state = remoteParticipant.getState();
    

Folgende Werte sind hierfür möglich:

  • „IDLE“: Anfangszustand

  • „EARLY_MEDIA“: Ansage wird wiedergegeben, bevor der Teilnehmer mit dem Anruf verbunden ist

  • „RINGING“: Der Teilnehmeranruf klingelt.

  • „CONNECTING“: Übergangszustand, während sich der Teilnehmer mit dem Anruf verbindet

  • „CONNECTED“: Teilnehmer ist mit dem Anruf verbunden

  • „HOLD“: Teilnehmer wird gehalten

  • „IN_LOBBY“: Der Teilnehmer wartet im Wartebereich darauf, zugelassen zu werden. Wird derzeit nur in Teams-Interoperabilitätsszenarien verwendet.

  • „DISCONNECTED“: In diesem Endzustand wird der Teilnehmer vom Anruf getrennt.

  • Um zu erfahren, warum ein Teilnehmer den Anruf verlassen hat, prüfen Sie die callEndReason-Eigenschaft:

    CallEndReason callEndReason = remoteParticipant.getCallEndReason();
    
  • Um zu prüfen, ob dieser Remoteteilnehmer stummgeschaltet ist oder nicht, prüfen Sie die isMuted-Eigenschaft:

    boolean isParticipantMuted = remoteParticipant.isMuted();
    
  • Um zu prüfen, ob dieser Remoteteilnehmer spricht oder nicht, prüfen Sie die isSpeaking-Eigenschaft:

    boolean isParticipantSpeaking = remoteParticipant.isSpeaking();
    
  • Um alle Videostreams zu prüfen, die ein bestimmter Teilnehmer im Rahmen dieses Anrufs sendet, sehen Sie sich die videoStreams-Sammlung an:

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

Verwenden von Vordergrunddiensten

Wenn Sie einen für Benutzer sichtbaren Task auch dann ausführen möchten, wenn Ihre Anwendung im Hintergrund ausgeführt wird, können Sie Vordergrunddienste verwenden.

Mithilfe von Vordergrunddiensten können Sie z. B. eine für Benutzer sichtbare Benachrichtigung beibehalten, wenn Ihre Anwendung über einen aktiven Anruf verfügt. Auf diese Weise ist der Anruf auch dann aktiv, wenn der Benutzer auf den Startbildschirm wechselt oder die Anwendung vom Bildschirm „Zuletzt verwendet“ entfernt.

Wenn Sie während eines Anrufs keinen Vordergrunddienst verwenden, kann die Navigation zum Startbildschirm den Anruf aktiv halten. Wenn Sie die Anwendung jedoch aus dem Bildschirm „Zuletzt verwendet“ entfernen, kann der Anruf beendet werden, wenn das Android-Betriebssystem den Prozess Ihrer Anwendung beendet.

Sie sollten den Vordergrunddienst starten, wenn Sie einen Anruf starten/ihm beitreten, z. B.:

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

Beenden Sie den Vordergrunddienst, wenn Sie den Anruf beenden oder der Status des Anrufs „Getrennt“ lautet, z. B.:

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

Hinweise zum Verwenden von Vordergrunddiensten

Beachten Sie, dass Szenarien wie das Beenden eines bereits ausgeführten Vordergrunddiensts, wenn die App aus der „Zuletzt verwendet“-Liste entfernt wird, die für den Benutzer sichtbare Benachrichtigung entfernen, und das Android-Betriebssystem kann Ihren Anwendungsprozess für einen zusätzlichen Zeitraum aktiv halten, was bedeutet, dass der Anruf während dieses Zeitraums weiterhin aktiv sein kann.

Wenn Ihre Anwendung beispielsweise den Vordergrunddienst für die Dienstmethode onTaskRemoved beendet, kann Ihre Anwendung Audio- und Videodaten gemäß Ihrem Aktivitätslebenszyklus starten/beenden, z. B. Audio und Video beenden, wenn Ihre Aktivität mit Außerkraftsetzung durch die onDestroy-Methode zerstört wird.

Einrichten des Systems

Erstellen des Xcode-Projekts

Erstellen Sie in Xcode ein neues iOS-Projekt, und wählen Sie die Vorlage Single View App (Einzelansicht-App) aus. In diesem Schnellstart wird das SwiftUI-Framework verwendet. Legen Sie daher Sprache auf Swift und Schnittstelle auf SwiftUI fest.

Im Rahmen dieser Schnellstartanleitung werden keine Tests erstellt. Sie können das Kontrollkästchen Tests einschließen deaktivieren.

Screenshot: Fenster zum Erstellen eines Projekts in Xcode

Installieren des Pakets und der Abhängigkeiten mithilfe von CocoaPods

  1. Erstellen Sie eine Podfile-Datei für die Anwendung, wie in diesem Beispiel:

    platform :ios, '13.0'
    use_frameworks!
    target 'AzureCommunicationCallingSample' do
        pod 'AzureCommunicationCalling', '~> 1.0.0'
    end
    
  2. Führen Sie pod install aus.

  3. Öffnen Sie .xcworkspace mithilfe von Xcode.

Anfordern des Zugriffs auf das Mikrofon

Um auf das Mikrofon des Geräts zuzugreifen, müssen Sie die Liste der Informationseigenschaften Ihrer App mithilfe von NSMicrophoneUsageDescription aktualisieren. Legen Sie den zugehörigen Wert auf eine Zeichenfolge fest. Diese wird in das Dialogfeld eingeschlossen, mit dem das System Zugriff vom Benutzer anfordert.

Klicken Sie mit der rechten Maustaste auf den Eintrag info.plist in der Projektstruktur, und wählen Sie dann Öffnen als>Quellcode aus. Fügen Sie im Abschnitt <dict> der obersten Ebene die folgenden Zeilen hinzu, und speichern Sie dann die Datei.

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

Einrichten des App-Frameworks

Öffnen Sie die Datei ContentView.swift Ihres Projekts. Fügen Sie am Anfang der Datei eine import-Deklaration hinzu, um die AzureCommunicationCalling-Bibliothek zu importieren. Importieren Sie außerdem AVFoundation. Dies ist für Audioberechtigungsanforderungen im Code erforderlich.

import AzureCommunicationCalling
import AVFoundation

Initialisieren von „CallAgent“

Um eine CallAgent-Instanz auf der Grundlage von CallClient zu erstellen, müssen Sie eine Methode vom Typ callClient.createCallAgent verwenden, die asynchron ein Objekt vom Typ CallAgent zurückgibt, nachdem es initialisiert wurde.

Übergeben Sie für die Erstellung eines Anrufclients ein Objekt vom Typ 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)
}

Übergeben Sie das von Ihnen erstellte Objekt vom Typ CommunicationTokenCredential an CallClient, und legen Sie den Anzeigenamen fest:

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

Hinweis

Bei Implementierung von Ereignisdelegaten muss die Anwendung einen eindeutigen Verweis auf die Objekte enthalten, die Ereignisabonnements erfordern. Wenn beispielsweise ein RemoteParticipant-Objekt beim Aufrufen der call.addParticipant-Methode zurückgegeben wird und die Anwendung den Delegaten auf das Lauschen auf RemoteParticipantDelegate festlegt, muss die Anwendung einen eindeutigen Verweis auf das RemoteParticipant-Objekt enthalten. Andernfalls löst der Delegat, wenn dieses Objekt erfasst wird, eine schwerwiegende Ausnahme aus, sobald das Calling SDK versucht, das Objekt aufzurufen.

Tätigen eines ausgehenden Anrufs

Um einen Anruf zu erstellen und zu starten, müssen Sie eine der APIs für CallAgent aufrufen und die Communication Services-Identität eines Benutzers angeben, den Sie unter Verwendung des Verwaltungs-SDK von Communication Services bereitgestellt haben.

Erstellung und Start des Anrufs erfolgen synchron. Sie erhalten eine Anrufinstanz, die es Ihnen ermöglicht, alle Ereignisse im Zusammenhang mit dem Anruf zu abonnieren.

Tätigen eines 1:1-Anrufs eines Benutzers oder eines 1:n-Anrufs mit Benutzern und Festnetznummern

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

1:n-Anruf mit Benutzern und Festnetznummern

Hinweis

Überprüfen Sie die Details des Telefonfestnetz-Anrufangebots. Um Zugriff auf das Vorschauprogramm zu erhalten, bewerben Sie sich für das Early Adopter-Programm.

Um den Anruf über das Telefonfestnetz zu tätigen, müssen Sie die Telefonnummer angeben, die Sie mit Communication Services bezogen haben.

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

Teilnehmen an einem Raumanruf

Um einem room-Anruf beizutreten, geben Sie die roomId-Eigenschaft als room-Bezeichner an. Um an dem Anruf teilzunehmen, verwenden Sie die join-Methode, und übergeben Sie den 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)
    }
}

Ein room bietet Anwendungsentwicklern bessere Kontrolle darüber, wer an einem Anruf teilnehmen kann, wann die Teilnehmer sich „treffen“ und wie sie zusammenarbeiten. Weitere Informationen zu rooms finden Sie in der konzeptionellen Dokumentation oder in der Schnellstartanleitung.

An einem Gruppenanruf teilnehmen

Um an einem Anruf teilzunehmen, müssen Sie eine der APIs für CallAgent aufrufen.

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

Abonnieren eines eingehenden Anrufs

Abonnieren Sie ein Ereignis für einen eingehenden Anruf.

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

Annehmen eines eingehenden Anrufs

Rufen Sie zum Annehmen eines Anrufs die Methode accept für ein IncomingCall-Objekt auf.

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

Ausführen von Vorgängen während eines Anrufs

Sie können während eines Anrufs verschiedene Vorgänge ausführen, um Einstellungen für Video und Audio zu verwalten.

Stumm schalten aktiveren und deaktivieren

Zum Stummschalten oder Aufheben der Stummschaltung des lokalen Endpunkts können Sie die asynchronen APIs mute und unmute verwenden.

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

Verwenden Sie den folgenden Code, um die Stummschaltung des lokalen Endpunkts asynchron aufzuheben:

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

Andere Teilnehmer stummschalten

Hinweis

Diese API wird als öffentliche Vorschau für Entwickler bereitgestellt. Je nachdem, welches Feedback wir dazu erhalten, werden möglicherweise Änderungen vorgenommen. Um diese API zu verwenden, verwenden Sie bitte die Betaversion von Azure Communication Services Calling iOS SDK, Version 2.7.0-beta.3 oder höher.

Um alle anderen Teilnehmer in einem Aufruf stummzuschalten, verwenden Sie die muteAllRemoteParticipants-API für den Aufruf.

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

Verwenden Sie die mute-API für einen bestimmten Remoteteilnehmer, um ihn stummzuschalten.

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

Verwalten von Remoteteilnehmern

Alle Remoteteilnehmer werden durch den Typ RemoteParticipant dargestellt und sind über die Sammlung remoteParticipants für eine Anrufinstanz verfügbar.

Auflisten der Teilnehmer an einem Anruf

call.remoteParticipants

Hinzufügen eines Teilnehmers zu einem Anruf

Wenn Sie einen Teilnehmer einem Anruf hinzufügen möchten (entweder als Benutzer oder Telefonnummer), können Sie addParticipant aufrufen. Durch diesen Befehl wird synchron die Instanz eines Remoteteilnehmers zurückgegeben.

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

Entfernen eines Teilnehmers aus einem Anruf

Wenn Sie einen Teilnehmer aus einem Anruf entfernen möchten (entweder als Benutzer oder Telefonnummer), können Sie die API removeParticipant aufrufen. Dieser Vorgang wird asynchron aufgelöst.

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

Abrufen von Eigenschaften von Remoteteilnehmern

// [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, ...]

Einrichten des Systems

Erstellen des Visual Studio-Projekts

Erstellen Sie für eine UWP-App in Visual Studio 2022 ein neues Projekt vom Typ Leere App (universelles Windows). Nachdem Sie den Projektnamen eingegeben haben, können Sie ein beliebiges Windows SDK höher als Version 10.0.17763.0 auswählen.

Für eine WinUI 3-App erstellen Sie ein neues Projekt mit der Vorlage Leere App, Gepackt (WinUI 3 in Desktop), um eine WinUI 3-Single-Page-Webanwendung einzurichten. Windows-App SDK-Version 1.3 oder höher ist erforderlich.

Installieren Sie das Paket und die Abhängigkeiten mit dem NuGet-Paket-Manager

Die Calling SDK-APIs und -Bibliotheken sind über ein NuGet-Paket öffentlich verfügbar.

In den folgenden Schritten wird veranschaulicht, wie Sie das NuGet-Paket für das Calling SDK suchen, herunterladen und installieren:

  1. Öffnen Sie den NuGet-Paket-Manager, indem Sie Tools>NuGet-Paket-Manager>NuGet-Pakete für Lösung verwalten auswählen.
  2. Wählen Sie Durchsuchen aus, und geben Sie dann Azure.Communication.Calling.WindowsClient in das Suchfeld ein.
  3. Stellen Sie sicher, dass das Kontrollkästchen Vorabversion einbeziehen aktiviert ist.
  4. Wählen Sie das Azure.Communication.Calling.WindowsClient-Paket und dann Azure.Communication.Calling.WindowsClient1.4.0-beta.1 oder eine neuere Version aus.
  5. Aktivieren Sie das Kontrollkästchen, das dem Communication Services-Projekt auf der rechten Registerkarte entspricht.
  6. Wählen Sie die Schaltfläche Installieren aus.

Anfordern des Zugriffs auf das Mikrofon

Die App benötigt Zugriff auf das Mikrofon, um ordnungsgemäß ausgeführt zu werden. In UWP-Apps sollte die Mikrofonfunktion in der App-Manifestdatei deklariert werden.

Mit den folgenden Schritten wird veranschaulicht, wie dies erreicht werden kann.

  1. Doppelklicken Sie im Panel Solution Explorer auf die Datei mit der Erweiterung .appxmanifest.
  2. Klicken Sie auf die Registerkarte Capabilities.
  3. Aktivieren Sie in der Liste der Funktionen das Kontrollkästchen Microphone.

Erstellen von Benutzeroberflächenschaltflächen zum Tätigen und Beenden des Anrufs

Diese einfache Beispiel-App enthält zwei Schaltflächen. eine zum Tätigen und eine weitere zum Beenden des Anrufs. In den folgenden Schritten wird veranschaulicht, wie Sie diese Schaltflächen zur App hinzufügen.

  1. Doppelklicken Sie im Bereich Solution Explorer für UWP auf die Datei namens MainPage.xaml bzw. für WinUI 3 auf MainWindows.xaml.
  2. Suchen Sie im zentralen Panel in der Vorschau der Benutzeroberfläche nach dem XAML-Code.
  3. Ersetzen Sie den XAML-Code durch den folgenden Auszug:
<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>

Einrichten der App mit Calling SDK-APIs

Die Calling SDK-APIs befinden sich in zwei verschiedenen Namespaces. Mit den folgenden Schritten wird der C#-Compiler über diese Namespaces informiert, damit das IntelliSense-Feature von Visual Studio verwendet werden kann.

  1. Klicken Sie im Bereich Solution Explorer für UWP auf den Pfeil links neben der Datei mit dem Namen MainPage.xaml bzw. für WinUI 3 auf MainWindows.xaml.
  2. Doppelklicken Sie auf die Datei namens MainPage.xaml.cs oder MainWindows.xaml.cs.
  3. Fügen Sie am Ende der aktuellen using-Anweisungen die folgenden Befehle hinzu.
using Azure.Communication.Calling.WindowsClient;

MainPage.xaml.cs oder MainWindows.xaml.cs offen halten. In den nächsten Schritten wird weiterer Code hinzugefügt.

Zulassen von App-Interaktionen

Die zuvor hinzugefügten Schaltflächen sind von CommunicationCall abhängig. Das bedeutet, dass ein CommunicationCall-Datenelement zur Klasse MainPage oder MainWindow hinzugefügt werden muss. Darüber hinaus muss derselben Klasse ein CallAgent-Datenelement hinzugefügt werden, damit der asynchrone Vorgang für die Erstellung von CallAgent erfolgreich ist.

Fügen Sie der Klasse MainPage oder MainWindow die folgenden Datenelemente hinzu:

CallAgent callAgent;
CommunicationCall call;

Erstellen von Schaltflächenhandlern

Zuvor wurden dem XAML-Code zwei Schaltflächen hinzugefügt. Der folgende Code fügt die Handler hinzu, die ausgeführt werden sollen, wenn ein Benutzer die Schaltfläche auswählt. Der folgende Code sollte nach den Datenelementen aus dem vorherigen Abschnitt hinzugefügt werden.

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

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

Objektmodell

Die folgenden Klassen und Schnittstellen befassen sich mit einigen der wichtigsten Features der Azure Communication Services-Clientbibliothek „Calling“ für UWP.

Name BESCHREIBUNG
CallClient CallClient ist der Haupteinstiegspunkt der Calling-Client-Bibliothek.
CallAgent CallAgent dient zum Starten von und Teilnehmen an Anrufen.
CommunicationCall CommunicationCall dient zum Verwalten von Anrufen, die getätigt wurden oder an denen teilgenommen wurde.
CommunicationTokenCredential CommunicationTokenCredential dient als tokengestützte Anmeldeinformation zum Instanziieren von CallAgent.
CallAgentOptions Die CallAgentOptions enthält Informationen zum Identifizieren des Anrufers.
HangupOptions HangupOptions gibt an, ob ein Anruf für alle Teilnehmer beendet werden soll.

Initialisieren von „CallAgent“

Zum Erzeugen einer CallAgent-Instanz anhand von CallClient müssen Sie die Methode CallClient.CreateCallAgentAsync verwenden, die ein CallAgent-Objekt asynchron zurückgibt, nachdem es initialisiert wurde.

Zum Erstellen von CallAgent müssen Sie ein CallTokenCredential-Objekt und ein CallAgentOptions-Objekt übergeben. Denken Sie daran, dass CallTokenCredential eine Ausnahme auslöst, wenn ein falsch formatiertes Token übergeben wird.

Der folgende Code sollte innerhalb einer Hilfsfunktion hinzugefügt werden, die bei der App-Initialisierung aufgerufen werden soll.

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

Ändern Sie das <AUTHENTICATION_TOKEN> mit einem gültigen Anmeldeinformationstoken für Ihre Ressource. Wenn ein Anmeldeinformationstoken eingebunden werden muss, lesen Sie die Dokumentation zu Benutzerzugriffstoken.

Erstellen von CallAgent und Tätigen eines Anrufs

Die Objekte, die zum Erstellen von CallAgent erforderlich sind, sind jetzt bereit. Es ist an der Zeit, CallAgent asynchron zu erstellen und einen Anruf zu tätigen.

Der folgende Code sollte nach der Behandlung der Ausnahme aus dem vorherigen Schritt hinzugefügt werden.

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;

Sie können auch 8:echo123 verwenden, um mit dem Azure Communication Services-Echobot zu sprechen.

Stumm schalten aktiveren und deaktivieren

Zum Stummschalten oder Aufheben der Stummschaltung des ausgehenden Tons können Sie die asynchronen MuteOutgoingAudioAsync- und UnmuteOutgoingAudioAsync-APIs verwenden:

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

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

Andere Teilnehmer stummschalten

Hinweis

Diese API wird als öffentliche Vorschau für Entwickler bereitgestellt. Je nachdem, welches Feedback wir dazu erhalten, werden möglicherweise Änderungen vorgenommen. Um diese API zu verwenden, verwenden Sie bitte die Betaversion von Azure Communication Services Calling Windows SDK, Version 1.4.0-beta.1 oder höher.

Um alle anderen Teilnehmer stummzuschalten oder einen bestimmten Teilnehmer stummzuschalten, können Sie die asynchronen APIs MuteAllRemoteParticipantsAsync für den Anruf und MuteAsync für den Remote-Teilnehmer verwenden:

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

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

Beenden eines Anrufs

Sobald ein Anruf getätigt wurde, sollte die HangupAsync-Methode des CommunicationCall-Objekts verwendet werden, um den Anruf zu beenden.

Eine Instanz von HangupOptions sollte auch verwendet werden, um anzugeben, ob der Anruf für alle Teilnehmer beendet werden muss.

Der folgende Code sollte in HangupButton_Click hinzugefügt werden.

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

Ausführen des Codes

Stellen Sie sicher, dass Visual Studio die App für x64, x86 oder ARM64 erstellt, und klicken Sie dann auf F5, um die Ausführung der App zu starten. Klicken Sie anschließend auf die Schaltfläche Call, um den festgelegten Gesprächspartner anzurufen.

Beachten Sie, dass das System beim ersten Ausführen der App den Benutzer zur Gewährung des Zugriffs auf das Mikrofon auffordert.

Nächste Schritte