Erste Schritte mit dem Hero-Beispiel für Anrufe
Das Hero-Beispiel für Gruppenanrufe von Azure Communication Services veranschaulicht, wie das Communication Services Calling Web-SDK für Anrufe verwendet werden kann, um eine Benutzeroberfläche für Gruppenanrufe zu erstellen.
In diesem Beispielschnellstart erfahren Sie, wie das Beispiel funktioniert, bevor Sie es auf Ihrem lokalen Computer ausführen und dann mithilfe Ihrer eigenen Azure Communication Services-Ressourcen in Azure bereitstellen.
Code herunterladen
Suchen Sie das Projekt für dieses Beispiel auf GitHub. Eine Version des Beispiels mit Features, die sich derzeit in der Public Preview befinden, z. B. Teams Interoperabilität und Anrufaufzeichnung, finden Sie in einem separaten Branch.
Übersicht
Das Beispiel verfügt sowohl über eine clientseitige als auch eine serverseitige Anwendung. Die clientseitige Anwendung ist eine React/Redux-Webanwendung, für die das Fluent-UI-Framework von Microsoft verwendet wird. Diese Anwendung sendet Anforderungen an eine serverseitige ASP.NET Core-Anwendung, die für die clientseitige Anwendung die Verbindungsherstellung mit Azure ermöglicht.
Das Beispiel sieht wie folgt aus:
Wenn Sie auf die Schaltfläche „Start a call“ (Anruf starten) klicken, ruft die Webanwendung ein Benutzerzugriffstoken aus der serverseitigen Anwendung ab. Dieses Token wird dann verwendet, um die Client-App mit Azure Communication Services zu verbinden. Nach dem Abrufen des Tokens werden Sie aufgefordert, die gewünschte Kamera und das Mikrofon anzugeben. Sie können Ihre Geräte mit den entsprechenden Umschaltern deaktivieren und aktivieren:
Nachdem Sie Ihren Anzeigenamen und Ihre Geräte konfiguriert haben, können Sie der Anrufsitzung beitreten. Der Hauptbereich für Anrufe, der die zentrale Anrufbenutzeroberfläche enthält, wird angezeigt.
Komponenten des Hauptbildschirms für Anrufe:
- Medienkatalog: Der Hauptbereich, in dem die Teilnehmer angezeigt werden. Wenn ein Teilnehmer seine Kamera aktiviert hat, wird der Videofeed hier angezeigt. Jeder Teilnehmer verfügt über eine individuelle Kachel, auf der sein Anzeigename und der Videostream (falls vorhanden) angezeigt werden.
- Header: Hier befinden sich die wichtigsten Anrufsteuerelemente zum Umschalten der Seitenleiste für Einstellungen und Teilnehmer, Aktivieren/Deaktivieren von Videos und der Mischung, Freigeben des Bildschirms und Beenden des Anrufs.
- Seitenleiste: Hier werden die Informationen zu den Teilnehmern und Einstellungen angezeigt, wenn der entsprechende Umschalter im Headerbereich verwendet wird. Die Komponente kann mit dem „X“ oben rechts geschlossen werden. Auf der Randleiste für die Teilnehmenden werden eine Liste mit Teilnehmenden und ein Link zum Einladen von weiteren Benutzer*innen zum Chat angezeigt. In der Seitenleiste für die Einstellungen können Sie die Mikrofon- und Kameraeinstellungen konfigurieren.
Weiter unten finden Sie weitere Informationen zu den Voraussetzungen und Schritten zum Einrichten des Beispiels.
Voraussetzungen
- Ein Azure-Konto mit einem aktiven Abonnement. Details finden Sie auf der Seite zum Erstellen eines kostenloses Azure-Kontos.
- Node.js (12.18.4 und höher)
- Visual Studio Code (Stabiler Build)
- Eine Azure Communication Services-Ressource. Ausführlichere Informationen hierzu finden Sie unter Schnellstart: Erstellen und Verwalten einer Communication Services-Ressource. Sie müssen die Verbindungszeichenfolge Ihrer Ressource für diesen Schnellstart aufzeichnen.
Vor dem erstmaligen Ausführen des Beispiels
Öffnen Sie eine Instanz von PowerShell, des Windows-Terminals, einer Eingabeaufforderung oder eines gleichwertigen Tools, und navigieren Sie zu dem Verzeichnis, in dem Sie das Beispiel klonen möchten.
git clone https://github.com/Azure-Samples/communication-services-web-calling-hero.git
Rufen Sie die
Connection String
aus dem Azure-Portal oder mithilfe der Azure CLI ab.az communication list-key --name "<acsResourceName>" --resource-group "<resourceGroup>"
Weitere Informationen zu Verbindungszeichenfolgen finden Sie unter Erstellen einer Azure Communication Services-Ressource.
Sobald Sie die erhalten haben
Connection String
, fügen Sie die Verbindungszeichenfolge in die Datei samples/Server/appsetting.json ein. Geben Sie Ihre Verbindungszeichenfolge in die Variable ein:ResourceConnectionString
.Rufen Sie die
Endpoint string
aus dem Azure-Portal oder mithilfe der Azure CLI ab.az communication list-key --name "<acsResourceName>" --resource-group "<resourceGroup>"
Weitere Informationen zu Endpunkt-Strings finden Sie unter Erstellen einer Azure Communication-Ressource
Sobald Sie die erhalten haben
Endpoint String
, fügen Sie die Endpunktzeichenfolge in die Datei samples/Server/appsetting.json ein. Geben Sie Ihre Endpunktzeichenfolge in die Variable ein:EndpointUrl
.
Lokaler Testlauf
Installieren von Abhängigkeiten
npm run setup
Aufruf-App starten
npm run start
Dadurch wird ein Clientserver für die Websitedateien auf Port 3000 geöffnet sowie ein API-Server auf Port 8080, der Funktionen wie Mintingtoken für Anrufteilnehmende ausführt.
Problembehandlung
Die App zeigt einen Bildschirm "Nicht unterstützter Browser", aber ich bin auf einem unterstützten Browser.
Wenn Ihre App über einen anderen Hostnamen als localhost bereitgestellt wird, müssen Sie den Datenverkehr über https und nicht http bereitstellen.
Veröffentlichen in Azure
npm run setup
npm run build
npm run package
- Verwenden der Azure-Erweiterung und Bereitstellen des Anruf-/Dist-Verzeichnisses für Ihren App-Dienst
Bereinigen von Ressourcen
Wenn Sie ein Communication Services-Abonnement bereinigen und entfernen möchten, können Sie die Ressource oder die Ressourcengruppe löschen. Wenn Sie die Ressourcengruppe löschen, werden auch alle anderen Ressourcen gelöscht, die ihr zugeordnet sind. Weitere Informationen zum Bereinigen von Ressourcen finden Sie hier.
Nächste Schritte
Weitere Informationen finden Sie in den folgenden Artikeln:
- Machen Sie sich mit der Verwendung des Calling SDK vertraut
- Informieren Sie sich über die Funktionsweise von Anrufen.
Zusätzliche Lektüre
- Beispiele: In der Übersicht über Beispiele finden Sie weitere Beispiele.
- Redux: Clientseitige Zustandsverwaltung
- Fluent-UI: UI-Bibliothek von Microsoft
- React: Bibliothek zum Erstellen von Benutzeroberflächen
- ASP.NET Core: Framework für die Erstellung von Webanwendungen
Das Hero-Beispiel für Gruppenanrufe für iOS von Azure Communication Services veranschaulicht, wie das Calling iOS SDK von Communication Services verwendet werden kann, um eine Benutzeroberfläche für Gruppenanrufe mit Sprach- und Videofunktion zu erstellen. In dieser Beispiel-Schnellstartanleitung wird beschrieben, wie Sie das Beispiel einrichten und ausführen. Es ist auch eine Übersicht über das Beispiel vorhanden, um Informationen zum Kontext bereitzustellen.
Code herunterladen
Suchen Sie das Projekt für dieses Beispiel auf GitHub.
Übersicht
Beim diesem Beispiel handelt es sich um eine native iOS-Anwendung, für die die iOS-SDKs von Azure Communication Services zum Entwickeln einer Benutzeroberfläche für Anrufe mit Sprach- und Videofunktion verwendet werden. In der Anwendung wird eine serverseitige Komponente verwendet, um Zugriffstoken bereitzustellen, die dann zum Initialisieren des Azure Communication Services-SDK genutzt werden. Informationen zum Konfigurieren dieser serverseitigen Komponente finden Sie im Tutorial Erstellen eines vertrauenswürdigen Authentifizierungsdiensts mithilfe von Azure Functions.
Das Beispiel sieht wie folgt aus:
Wenn Sie auf die Schaltfläche „Neuen Anruf starten“ klicken, fordert die iOS-Anwendung Sie auf, Ihren Anzeigenamen für den Anruf einzugeben.
Nachdem Sie auf dem Bildschirm „Anruf starten“ auf „Weiter“ getippt haben, können Sie die Gruppen-ID des Anrufs über das iOS-Freigabeblatt freigeben.
Darüber hinaus ermöglicht die Anwendung es Ihnen, einem vorhandenen Azure Communication Services-Anruf beizutreten, indem Sie die ID des vorhandenen Anrufs oder einen Teams-ID-Link angeben.
Nachdem Sie einem Anruf beigetreten sind, werden Sie aufgefordert, der Anwendung die Berechtigung zum Zugriff auf Ihre Kamera und das Mikrofon zu gewähren (sofern nicht bereits geschehen). Denken Sie daran, dass (wie bei allen AVFoundation-basierten Apps) echte Audio- und Videofunktionen nur auf realer Hardware verfügbar sind.
Sobald Sie Ihren Anzeigenamen konfiguriert und dem Anruf beigetreten sind, wird der Hauptbereich für Anrufe angezeigt, der die zentrale Anrufbenutzeroberfläche enthält.
Komponenten des Hauptbildschirms für Anrufe:
- Medienkatalog: Der Hauptbereich, in dem die Teilnehmer angezeigt werden. Wenn ein Teilnehmer seine Kamera aktiviert hat, wird der Videofeed hier angezeigt. Jeder Teilnehmer verfügt über eine individuelle Kachel, auf der sein Anzeigename und der Videostream (falls vorhanden) angezeigt werden. Für den Medienkatalog wird die Anzeige von mehreren Teilnehmern unterstützt, und die Anzeige wird entsprechend aktualisiert, wenn Teilnehmer für den Anruf hinzugefügt oder entfernt werden.
- Aktionsleiste: Diese Leiste enthält die wichtigsten Anrufsteuerelemente. Mit diesen Steuerelementen können Sie Kamera und Mikrofon ein- und ausschalten, Ihren Bildschirm freigeben und den Anruf verlassen.
Unten sind weitere Informationen zu den Voraussetzungen und Schritten zum Einrichten des Beispiels angegeben.
Voraussetzungen
- Ein Azure-Konto mit einem aktiven Abonnement. Details finden Sie unter kostenloses Azure-Konto erstellen.
- Einen Mac mit Xcode zusammen mit einem gültigen in Ihrer Keychain installierten Entwicklerzertifikat.
- Eine Azure Communication Services-Ressource. Ausführlichere Informationen hierzu finden Sie unter Schnellstart: Erstellen und Verwalten einer Communication Services-Ressource.
- Eine Azure-Funktion, die den Authentifizierungsendpunkt zum Abrufen von Zugriffstoken ausführt.
Lokales Ausführen des Beispiels
Das Beispiel für Gruppenanrufe kann lokal mit Xcode ausgeführt werden. Entwickler können entweder ihr physisches Gerät oder einen Emulator verwenden, um die Anwendung zu testen.
Vor dem erstmaligen Ausführen des Beispiels
- Installieren Sie Abhängigkeiten, indem Sie
pod install
ausführen. - Öffnen Sie
AzureCalling.xcworkspace
in Xcode. - Erstellen Sie am Stamm eine Textdatei mit dem Namen
AppSettings.xcconfig
, und legen Sie den Wert fest:communicationTokenFetchUrl = <your authentication endpoint, without the https:// component>
Ausführen des Beispiels
Erstellen Sie das Beispiel in XCode, und führen Sie es mit dem AzureCalling-Ziel auf dem Simulator oder einem Gerät Ihrer Wahl aus.
(Optional) Schützen eines Authentifizierungsendpunkts
Zu Demonstrationszwecken wird in diesem Beispiel standardmäßig ein öffentlich zugänglicher Endpunkt verwendet, um ein Azure Communication Services-Zugriffstoken abzurufen. Für Produktionsszenarien empfehlen wir Ihnen, für die Bereitstellung eigener Token Ihren eigenen geschützten Endpunkt zu erstellen.
Wenn weitere Konfigurationsschritte ausgeführt werden, wird für dieses Beispiel die Verbindungsherstellung mit einem durch Microsoft Entra ID (Microsoft Entra ID) geschützten Endpunkt unterstützt. So kann erreicht werden, dass die Benutzeranmeldung für die App erfordert wird, um ein Azure Communication Services-Zugriffstoken abzurufen. Sehen Sie sich die folgenden Schritte an:
- Aktivieren Sie die Microsoft Entra-Authentifizierung in Ihrer App.
- Navigieren Sie in Microsoft Entra unter „App-Registrierungen“ zur Übersichtsseite Ihrer registrierten App. Notieren Sie sich die Werte für
Application (client) ID
,Directory (tenant) ID
undApplication ID URI
.
- Erstellen Sie eine Datei
AppSettings.xcconfig
am Stamm (sofern nicht bereits vorhanden), und fügen Sie die Werte hinzu:communicationTokenFetchUrl = <Application ID URI, without the https:// component> aadClientId = <Application (client) ID> aadTenantId = <Directory (tenant) ID>
Bereinigen von Ressourcen
Wenn Sie ein Communication Services-Abonnement bereinigen und entfernen möchten, können Sie die Ressource oder die Ressourcengruppe löschen. Wenn Sie die Ressourcengruppe löschen, werden auch alle anderen Ressourcen gelöscht, die ihr zugeordnet sind. Weitere Informationen zum Bereinigen von Ressourcen finden Sie hier.
Nächste Schritte
Weitere Informationen finden Sie in den folgenden Artikeln:
- Machen Sie sich mit der Verwendung des Calling SDK vertraut
- Informieren Sie sich über die Funktionsweise von Anrufen.
Zusätzliche Lektüre
- Azure Communication GitHub: Weitere Beispiele und Informationen finden Sie auf der offiziellen GitHub-Seite
- Beispiele: In der Übersicht über Beispiele finden Sie weitere Beispiele.
- Azure Communication Calling-Funktionen: Weitere Informationen zu Calling iOS SDK finden Sie unter Azure Communication iOS Calling SDK
Das Hero-Beispiel für Gruppenanrufe für Android von Azure Communication Services veranschaulicht, wie das Calling Android SDK von Communication Services verwendet werden kann, um eine Benutzeroberfläche für Gruppenanrufe mit Sprach- und Videofunktion zu erstellen. In dieser Beispiel-Schnellstartanleitung wird beschrieben, wie Sie das Beispiel einrichten und ausführen. Es ist auch eine Übersicht über das Beispiel vorhanden, um Informationen zum Kontext bereitzustellen.
Code herunterladen
Suchen Sie das Projekt für dieses Beispiel auf GitHub.
Übersicht
Bei diesem Beispiel handelt es sich um eine native Android-Anwendung, die die Azure Communication Services-UI-Clientbibliothek für Android zur Entwicklung einer Anrufbenutzeroberfläche nutzt, die sowohl Sprach- als auch Videoanrufe ermöglicht. In der Anwendung wird eine serverseitige Komponente verwendet, um Zugriffstoken bereitzustellen, die dann zum Initialisieren des Azure Communication Services-SDK genutzt werden. Informationen zum Konfigurieren dieser serverseitigen Komponente finden Sie im Tutorial Erstellen eines vertrauenswürdigen Authentifizierungsdiensts mithilfe von Azure Functions.
Das Beispiel sieht wie folgt aus:
Wenn Sie auf die Schaltfläche „Neuen Anruf starten“ klicken, fordert die Android-Anwendung Sie auf, Ihren Anzeigenamen für den Anruf einzugeben.
Nachdem Sie auf der Seite „Anruf starten“ auf „Weiter“ getippt haben, können Sie die Gruppen-ID freigeben.
Die Anwendung ermöglicht es Ihnen, einem vorhandenen Azure Communication Services-Anruf beizutreten, indem Sie die ID des vorhandenen Anrufs oder einen ID-Link für eine Teams-Besprechung angeben.
Nachdem Sie einem Anruf beigetreten sind, werden Sie aufgefordert, der Anwendung die Berechtigung zum Zugriff auf Ihre Kamera und das Mikrofon zu gewähren (sofern nicht bereits geschehen). Der Hauptbereich für Anrufe, der die zentrale Anrufbenutzeroberfläche enthält, wird angezeigt.
Komponenten des Hauptbildschirms für Anrufe:
- Medienkatalog: Der Hauptbereich, in dem die Teilnehmer angezeigt werden. Wenn ein Teilnehmer seine Kamera aktiviert hat, wird der Videofeed hier angezeigt. Jeder Teilnehmer verfügt über eine individuelle Kachel, auf der sein Anzeigename und der Videostream (falls vorhanden) angezeigt werden. Für den Medienkatalog wird die Anzeige von mehreren Teilnehmern unterstützt, und die Anzeige wird entsprechend aktualisiert, wenn Teilnehmer für den Anruf hinzugefügt oder entfernt werden.
- Aktionsleiste: Diese Leiste enthält die wichtigsten Anrufsteuerelemente. Mit diesen Steuerelementen können Sie Kamera und Mikrofon ein- und ausschalten, Ihren Bildschirm freigeben und den Anruf verlassen.
Unten sind weitere Informationen zu den Voraussetzungen und Schritten zum Einrichten des Beispiels angegeben.
Voraussetzungen
- Ein Azure-Konto mit einem aktiven Abonnement. Details finden Sie unter kostenloses Azure-Konto erstellen.
- Android Studio wird auf Ihrem Computer ausgeführt
- Eine Azure Communication Services-Ressource. Ausführlichere Informationen hierzu finden Sie unter Schnellstart: Erstellen und Verwalten einer Communication Services-Ressource.
- Eine Azure-Funktion, die den Authentifizierungsendpunkt zum Abrufen von Zugriffstoken ausführt.
Lokales Ausführen des Beispiels
Das Beispiel für Gruppenanrufe kann lokal mit Android Studio ausgeführt werden. Entwickler können entweder ihr physisches Gerät oder einen Emulator verwenden, um die Anwendung zu testen.
Vor dem erstmaligen Ausführen des Beispiels
- Öffnen Sie Android Studio, und wählen Sie
Open an Existing Project
- Öffnen Sie den Ordner
AzureCalling
in der heruntergeladenen Version für das Beispiel. - Erweitern Sie zu aktualisierende App/Assets
appSettings.properties
. Legen Sie als Voraussetzung den Wert für dencommunicationTokenFetchUrl
-Schlüssel auf die URL für Ihren Authentifizierungsendpunkt fest.
Ausführen des Beispiels
Kompilieren Sie das Beispiel in Android Studio, und führen Sie es aus.
(Optional) Schützen eines Authentifizierungsendpunkts
Zu Demonstrationszwecken wird in diesem Beispiel standardmäßig ein öffentlich zugänglicher Endpunkt verwendet, um ein Azure Communication Services-Token abzurufen. Für Produktionsszenarien empfehlen wir Ihnen, für die Bereitstellung eigener Token Ihren eigenen geschützten Endpunkt zu erstellen.
Wenn weitere Konfigurationsschritte ausgeführt werden, wird für dieses Beispiel die Verbindungsherstellung mit einem durch Microsoft Entra ID (Microsoft Entra ID) geschützten Endpunkt unterstützt. So kann erreicht werden, dass die Benutzeranmeldung für die App erfordert wird, um ein Azure Communication Services-Token abzurufen. Sehen Sie sich die folgenden Schritte an:
Aktivieren Sie die Microsoft Entra-Authentifizierung in Ihrer App.
Navigieren Sie in Microsoft Entra unter „App-Registrierungen“ zur Übersichtsseite Ihrer registrierten App. Notieren Sie sich die Werte für
Package name
,Signature hash
undMSAL Configutaion
.
Bearbeiten Sie
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
, und legen SieisAADAuthEnabled
fest, um Microsoft Entra ID zu aktivieren.Bearbeiten Sie
AndroidManifest.xml
, und legen Sieandroid:path
auf einen Signaturhash fest. (Optional. Der aktuelle Wert verwendet einen Hash aus dem gebündelten debug.keystore. Wenn ein anderer Keystore verwendet wird, muss dieser aktualisiert werden.)<activity android:name="com.microsoft.identity.client.BrowserTabActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:host="com.azure.samples.communication.calling" android:path="/Signature hash" <!-- do not remove /. The current hash in AndroidManifest.xml is for debug.keystore. --> android:scheme="msauth" /> </intent-filter> </activity>
Kopieren Sie die MSAL Android-Konfiguration aus dem Azure-Portal, und fügen Sie es in
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
ein. Schließen Sie „account_mode“ : „SINGLE“ ein:{ "client_id": "", "authorization_user_agent": "DEFAULT", "redirect_uri": "", "account_mode" : "SINGLE", "authorities": [ { "type": "AAD", "audience": { "type": "AzureADMyOrg", "tenant_id": "" } } ] }
Bearbeiten Sie
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
, und legen Sie den Wert für den SchlüsselcommunicationTokenFetchUrl
auf die URL für Ihren Authentifizierungsendpunkt fest.Bearbeiten Sie
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
und legen Sie den des Werts für den SchlüsselaadScopes
aus den BereichenAzure Active Directory
Expose an API
festLegen Sie den Wert für
graphURL
inAzureCalling/app/assets/appSettings.properties
als Graph-API-Endpunkt zum Abrufen von Benutzerinformationen fest.Bearbeiten Sie
AzureCalling/app/src/main/assets/appSettings.properties
, und legen Sie den Wert für den Schlüsseltenant
fest, um die automatische Anmeldung zu aktivieren. Auf diese Weise muss sich der Benutzer beim Neustart der Anwendung nicht immer wieder neu authentifizieren.
Bereinigen von Ressourcen
Wenn Sie ein Communication Services-Abonnement bereinigen und entfernen möchten, können Sie die Ressource oder die Ressourcengruppe löschen. Wenn Sie die Ressourcengruppe löschen, werden auch alle anderen Ressourcen gelöscht, die ihr zugeordnet sind. Weitere Informationen zum Bereinigen von Ressourcen finden Sie hier.
Nächste Schritte
Weitere Informationen finden Sie in den folgenden Artikeln:
- Machen Sie sich mit der Verwendung des Calling SDK vertraut
- Informieren Sie sich über die Funktionsweise von Anrufen.
Zusätzliche Lektüre
- Azure Communication GitHub: Weitere Beispiele und Informationen finden Sie auf der offiziellen GitHub-Seite
- Beispiele: In der Übersicht über Beispiele finden Sie weitere Beispiele.
- Azure Communication Calling-Funktionen: Weitere Informationen zum Android Calling SDK finden Sie unter Azure Communication Android Calling SDK
Das Hero-Beispiel für Gruppenanrufe für Windows von Azure Communication Services veranschaulicht, wie das Calling Windows SDK von Communication Services verwendet werden kann, um eine Benutzeroberfläche für Gruppenanrufe mit Sprach- und Videofunktion zu erstellen. In diesem Beispiel erfahren Sie, wie Sie das Beispiel einrichten und ausführen. Es ist auch eine Übersicht über das Beispiel vorhanden, um Informationen zum Kontext bereitzustellen.
In dieser Schnellstartanleitung erfahren Sie, wie Sie einen 1:1-Videoanruf mithilfe des Calling SDK von Azure Communication Services für Windows starten.
UWP-Beispielcode
Voraussetzungen
Zum Durchführen dieses Tutorials benötigen Sie Folgendes:
Ein Azure-Konto mit einem aktiven Abonnement. Sie können kostenlos ein Konto erstellen.
Installieren Sie Visual Studio 2022 mit der Workload „Entwicklung für die universelle Windows-Plattform“.
Eine bereitgestellte Communication Services-Ressource. Erstellen Sie eine Communication Services-Ressource. Für diese Schnellstartanleitung müssen Sie Ihre Verbindungszeichenfolge erfassen.
Ein Benutzerzugriffstoken für Ihren Azure Communication Service Sie können auch die Azure CLI verwenden und den Befehl mit Ihrer Verbindungszeichenfolge ausführen, um einen Benutzer und ein Zugriffs-Token zu erstellen.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
Ausführliche Informationen finden Sie unter Verwenden der Azure CLI zum Erstellen und Verwalten von Zugriffstoken.
Einrichten
Erstellen des Projekts
Erstellen Sie in Visual Studio ein neues Projekt mit der Vorlage Leere App (Universelle Windows-App) , um eine einseitige UWP-App (Universelle Windows-Plattform) einzurichten.
Installieren des Pakets
Klicken Sie mit der rechten Maustaste auf Ihr Projekt, und wechseln Sie zu Manage Nuget Packages
, um Azure.Communication.Calling.WindowsClient
1.2.0-beta.1 oder einer höhere Version zu installieren. Vergewissern Sie sich, dass „Vorabversion einbeziehen“ aktiviert ist.
Anfordern des Zugriffs
Wechseln Sie zu Package.appxmanifest
, und klicken Sie auf Capabilities
.
Aktivieren Sie Internet (Client & Server)
, um ein- und ausgehenden Zugriff auf das Internet zu erhalten.
Aktivieren Sie Microphone
, um auf den Audiofeed des Mikrofons zuzugreifen.
Aktivieren Sie WebCam
, um auf die Kamera des Geräts zuzugreifen.
Fügen Sie ihrem Package.appxmanifest
den folgenden Code hinzu, indem Sie mit einem Rechtsklick auf Ihrer Maus „Code anzeigen“ auswählen.
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>RtmMvrUap.dll</Path>
<ActivatableClass ActivatableClassId="VideoN.VideoSchemeHandler" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions>
Einrichten des App-Frameworks
Wir müssen ein einfaches Layout konfigurieren, um unsere Logik anzufügen. Um einen ausgehenden Anruf zu tätigen, benötigen wir ein TextBox
-Element, um die Benutzer-ID des Angerufenen bereitzustellen. Außerdem benötigen wir die Schaltflächen Start Call
und Hang Up
.
Darüber hinaus müssen wir eine Vorschau des lokalen Videos anzeigen und das Remotevideo des anderen Teilnehmers rendern. Daher benötigen wir zwei Elemente zum Anzeigen der Videostreams.
Öffnen Sie in Ihrem Projekt MainPage.xaml
, und ersetzen Sie den Inhalt durch folgende Implementierung.
<Page
x:Class="CallingQuickstart.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CallingQuickstart"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="MainGrid" HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="200*"/>
<RowDefinition Height="60*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" x:Name="AppTitleBar" Background="LightSeaGreen">
<!-- Width of the padding columns is set in LayoutMetricsChanged handler. -->
<!-- Using padding columns instead of Margin ensures that the background paints the area under the caption control buttons (for transparent buttons). -->
<TextBlock x:Name="QuickstartTitle" Text="Calling Quickstart sample title bar" Style="{StaticResource CaptionTextBlockStyle}" Padding="4,4,0,0"/>
</Grid>
<TextBox Grid.Row="1" x:Name="CalleeTextBox" PlaceholderText="Who would you like to call?" TextWrapping="Wrap" VerticalAlignment="Center" />
<Grid Grid.Row="2" Background="LightGray">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<MediaPlayerElement x:Name="LocalVideo" HorizontalAlignment="Center" Stretch="UniformToFill" Grid.Column="0" VerticalAlignment="Center" AutoPlay="True" />
<MediaPlayerElement x:Name="RemoteVideo" HorizontalAlignment="Center" Stretch="UniformToFill" Grid.Column="1" VerticalAlignment="Center" AutoPlay="True" />
</Grid>
<StackPanel Grid.Row="3" Orientation="Vertical" Grid.RowSpan="2">
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock VerticalAlignment="Center">Cameras:</TextBlock>
<ComboBox x:Name="CameraList" HorizontalAlignment="Left" Grid.Column="0" DisplayMemberPath="Name" SelectionChanged="CameraList_SelectionChanged" Margin="10"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button x:Name="CallButton" Content="Start/Join call" Click="CallButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="123"/>
<Button x:Name="HangupButton" Content="Hang up" Click="HangupButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="123"/>
<CheckBox x:Name="MuteLocal" Content="Mute" Margin="10,0,0,0" Click="MuteLocal_Click" Width="74"/>
<CheckBox x:Name="BackgroundBlur" Content="Background blur" Width="142" Margin="10,0,0,0" Click="BackgroundBlur_Click"/>
</StackPanel>
</StackPanel>
<TextBox Grid.Row="4" x:Name="Stats" Text="" TextWrapping="Wrap" VerticalAlignment="Center" Height="30" Margin="0,2,0,0" BorderThickness="2" IsReadOnly="True" Foreground="LightSlateGray" />
</Grid>
</Page>
Öffnen Sie App.xaml.cs
(mit einem Rechtsklick auf Ihrer Maus und „Code anzeigen“ auswählen), und fügen Sie oben diese Zeile hinzu:
using CallingQuickstart;
Öffnen der MainPage.xaml.cs
(mit einem Rechtsklick auf Ihrer Maus und „Code anzeigen“ auswählen), und ersetzen Sie den Inhalt mit der folgenden Implementierung:
using Azure.Communication.Calling.WindowsClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Core;
using Windows.Media.Core;
using Windows.Networking.PushNotifications;
using Windows.UI;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace CallingQuickstart
{
public sealed partial class MainPage : Page
{
private const string authToken = "<Azure Communication Services auth token>";
private CallClient callClient;
private CallTokenRefreshOptions callTokenRefreshOptions;
private CallAgent callAgent;
private CommunicationCall call = null;
private LocalOutgoingAudioStream micStream;
private LocalOutgoingVideoStream cameraStream;
#region Page initialization
public MainPage()
{
this.InitializeComponent();
// Hide default title bar.
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
coreTitleBar.ExtendViewIntoTitleBar = true;
QuickstartTitle.Text = $"{Package.Current.DisplayName} - Ready";
Window.Current.SetTitleBar(AppTitleBar);
CallButton.IsEnabled = true;
HangupButton.IsEnabled = !CallButton.IsEnabled;
MuteLocal.IsChecked = MuteLocal.IsEnabled = !CallButton.IsEnabled;
ApplicationView.PreferredLaunchViewSize = new Windows.Foundation.Size(800, 600);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
await InitCallAgentAndDeviceManagerAsync();
base.OnNavigatedTo(e);
}
#endregion
private async Task InitCallAgentAndDeviceManagerAsync()
{
// Initialize call agent and Device Manager
}
private async void Agent_OnIncomingCallAsync(object sender, IncomingCall incomingCall)
{
// Accept an incoming call
}
private async void CallButton_Click(object sender, RoutedEventArgs e)
{
// Start a call with video
}
private async void HangupButton_Click(object sender, RoutedEventArgs e)
{
// End the current call
}
private async void Call_OnStateChangedAsync(object sender, PropertyChangedEventArgs args)
{
var call = sender as CommunicationCall;
if (call != null)
{
var state = call.State;
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
QuickstartTitle.Text = $"{Package.Current.DisplayName} - {state.ToString()}";
Window.Current.SetTitleBar(AppTitleBar);
HangupButton.IsEnabled = state == CallState.Connected || state == CallState.Ringing;
CallButton.IsEnabled = !HangupButton.IsEnabled;
MuteLocal.IsEnabled = !CallButton.IsEnabled;
});
switch (state)
{
case CallState.Connected:
{
break;
}
case CallState.Disconnected:
{
break;
}
default: break;
}
}
}
private async void CameraList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Handle camera selection
}
}
}
Objektmodell
Die folgenden Klassen und Schnittstellen befassen sich mit einigen der wichtigsten Features des Azure Communication Services Calling SDK:
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. |
CallTokenCredential |
CallTokenCredential dient als tokengestützte Anmeldeinformation zum Instanziieren von CallAgent . |
CommunicationUserIdentifier |
CommunicationUserIdentifier wird zur Darstellung der Identität des Benutzers verwendet, der eine der folgenden Optionen sein kann: CommunicationUserIdentifier , PhoneNumberIdentifier oder CallingApplication . |
Authentifizieren des Clients
Zum Initialisieren eines CallAgent
benötigen Sie ein Benutzerzugriffs-Token. In der Regel wird dieses Token von einem Dienst mit einer für die Anwendung spezifischen Authentifizierung generiert. Weitere Informationen zu Benutzerzugriffstoken finden Sie im Leitfaden zu Benutzerzugriffstoken.
Ersetzen Sie für den Schnellstart <AUTHENTICATION_TOKEN>
durch ein Benutzerzugriffstoken, das für Ihre Azure Communication Service-Ressource generiert wurde.
Sobald Sie ein Token haben, initialisieren Sie damit eine CallAgent
-Instanz, die es uns ermöglicht, Anrufe zu tätigen und zu empfangen. Um auf die Kameras auf dem Gerät zugreifen zu können, benötigen wir auch eine Geräte-Manager-Instanz.
Fügen Sie der Funktion InitCallAgentAndDeviceManagerAsync
den folgenden Code hinzu:
this.callClient = new CallClient(new CallClientOptions() {
Diagnostics = new CallDiagnosticsOptions() {
AppName = "CallingQuickstart",
AppVersion="1.0",
Tags = new[] { "Calling", "ACS", "Windows" }
}
});
// Set up local video stream using the first camera enumerated
var deviceManager = await this.callClient.GetDeviceManagerAsync();
var camera = deviceManager?.Cameras?.FirstOrDefault();
var mic = deviceManager?.Microphones?.FirstOrDefault();
micStream = new LocalOutgoingAudioStream();
CameraList.ItemsSource = deviceManager.Cameras.ToList();
if (camera != null)
{
CameraList.SelectedIndex = 0;
}
callTokenRefreshOptions = new CallTokenRefreshOptions(false);
callTokenRefreshOptions.TokenRefreshRequested += OnTokenRefreshRequestedAsync;
var tokenCredential = new CallTokenCredential(authToken, callTokenRefreshOptions);
var callAgentOptions = new CallAgentOptions()
{
DisplayName = "Contoso",
//https://github.com/lukes/ISO-3166-Countries-with-Regional-Codes/blob/master/all/all.csv
EmergencyCallOptions = new EmergencyCallOptions() { CountryCode = "840" }
};
try
{
this.callAgent = await this.callClient.CreateCallAgentAsync(tokenCredential, callAgentOptions);
//await this.callAgent.RegisterForPushNotificationAsync(await this.RegisterWNS());
this.callAgent.CallsUpdated += OnCallsUpdatedAsync;
this.callAgent.IncomingCallReceived += OnIncomingCallAsync;
}
catch(Exception ex)
{
if (ex.HResult == -2147024809)
{
// E_INVALIDARG
// Handle possible invalid token
}
}
Starten eines Anrufs mit Video
Fügen Sie die Implementierung zu CallButton_Click
hinzu, um einen Anruf mit Video zu starten. Wir müssen die Kameras mit der Gerätemanager-Instanz aufzählen und LocalOutgoingVideoStream
konstruieren. Wir müssen VideoOptions
mit LocalVideoStream
festlegen und mit startCallOptions
übergeben, um die Anfangsoptionen für den Anruf festzulegen. Durch Anfügen von LocalOutgoingVideoStream
an MediaElement
können wir die Vorschau des lokalen Videos sehen.
var callString = CalleeTextBox.Text.Trim();
if (!string.IsNullOrEmpty(callString))
{
if (callString.StartsWith("8:")) // 1:1 Azure Communication Services call
{
call = await StartAcsCallAsync(callString);
}
else if (callString.StartsWith("+")) // 1:1 phone call
{
call = await StartPhoneCallAsync(callString, "+12133947338");
}
else if (Guid.TryParse(callString, out Guid groupId))// Join group call by group guid
{
call = await JoinGroupCallByIdAsync(groupId);
}
else if (Uri.TryCreate(callString, UriKind.Absolute, out Uri teamsMeetinglink)) //Teams meeting link
{
call = await JoinTeamsMeetingByLinkAsync(teamsMeetinglink);
}
}
if (call != null)
{
call.RemoteParticipantsUpdated += OnRemoteParticipantsUpdatedAsync;
call.StateChanged += OnStateChangedAsync;
}
Fügen Sie die Methoden hinzu, um die verschiedenen Arten von Anrufen zu starten oder ihnen beizutreten (1:1 ACS-Anruf, 1:1 Telefonanruf, ACS-Gruppenanruf, Beitritt zu einem Team-Meeting usw.).
private async Task<CommunicationCall> StartAcsCallAsync(string acsCallee)
{
var options = await GetStartCallOptionsAsynnc();
var call = await this.callAgent.StartCallAsync( new [] { new UserCallIdentifier(acsCallee) }, options);
return call;
}
private async Task<CommunicationCall> StartPhoneCallAsync(string acsCallee, string alternateCallerId)
{
var options = await GetStartCallOptionsAsynnc();
options.AlternateCallerId = new PhoneNumberCallIdentifier(alternateCallerId);
var call = await this.callAgent.StartCallAsync( new [] { new PhoneNumberCallIdentifier(acsCallee) }, options);
return call;
}
private async Task<CommunicationCall> JoinGroupCallByIdAsync(Guid groupId)
{
var joinCallOptions = await GetJoinCallOptionsAsync();
var groupCallLocator = new GroupCallLocator(groupId);
var call = await this.callAgent.JoinAsync(groupCallLocator, joinCallOptions);
return call;
}
private async Task<CommunicationCall> JoinTeamsMeetingByLinkAsync(Uri teamsCallLink)
{
var joinCallOptions = await GetJoinCallOptionsAsync();
var teamsMeetingLinkLocator = new TeamsMeetingLinkLocator(teamsCallLink.AbsoluteUri);
var call = await callAgent.JoinAsync(teamsMeetingLinkLocator, joinCallOptions);
return call;
}
private async Task<StartCallOptions> GetStartCallOptionsAsynnc()
{
return new StartCallOptions() {
OutgoingAudioOptions = new OutgoingAudioOptions() { IsOutgoingAudioMuted = true, OutgoingAudioStream = micStream },
OutgoingVideoOptions = new OutgoingVideoOptions() { OutgoingVideoStreams = new OutgoingVideoStream[] { cameraStream } }
};
}
private async Task<JoinCallOptions> GetJoinCallOptionsAsync()
{
return new JoinCallOptions() {
OutgoingAudioOptions = new OutgoingAudioOptions() { IsOutgoingAudioMuted = true },
OutgoingVideoOptions = new OutgoingVideoOptions() { OutgoingVideoStreams = new OutgoingVideoStream[] { cameraStream } }
};
}
Fügen Sie den Code zum Erstellen von LocalVideoStream in Abhängigkeit von der gewählten Kamera in der Methode CameraList_SelectionChanged
hinzu.
var selectedCamerea = CameraList.SelectedItem as VideoDeviceDetails;
cameraStream = new LocalOutgoingVideoStream(selectedCamerea);
var localUri = await cameraStream.StartPreviewAsync();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
LocalVideo.Source = MediaSource.CreateFromUri(localUri);
});
if (call != null)
{
await call?.StartVideoAsync(cameraStream);
}
Annehmen eines eingehenden Anrufs
Fügen Sie die Implementierung zu OnIncomingCallAsync
hinzu, um einen eingehenden Anruf mit Video zu beantworten, und übergeben Sie den LocalVideoStream
an acceptCallOptions
.
var incomingCall = args.IncomingCall;
var acceptCallOptions = new AcceptCallOptions() {
IncomingVideoOptions = new IncomingVideoOptions()
{
IncomingVideoStreamKind = VideoStreamKind.RemoteIncoming
}
};
_ = await incomingCall.AcceptAsync(acceptCallOptions);
Remote-Teilnehmer- und -Videostreams
Alle Remoteteilnehmer sind über die RemoteParticipants
-Sammlung für eine Anrufinstanz verfügbar. Sobald der Anruf verbunden ist (CallState.Connected
), können wir auf die Remoteteilnehmer des Anrufs zugreifen und die Remotevideostreams verarbeiten.
Hinweis
Wenn ein Benutzer einem Anruf beitritt, kann er über die RemoteParticipants
-Sammlung auf die aktuellen Remoteteilnehmer zugreifen. Das RemoteParticipantsUpdated
-Ereignis wird für diese vorhandenen Teilnehmer nicht ausgelöst. Dieses Ereignis wird nur ausgelöst, wenn ein Remoteteilnehmer dem Anruf beitritt oder ihn verlässt, während sich der Benutzer bereits im Anruf befindet.
private async void Call_OnVideoStreamsUpdatedAsync(object sender, RemoteVideoStreamsEventArgs args)
{
foreach (var remoteVideoStream in args.AddedRemoteVideoStreams)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
RemoteVideo.Source = await remoteVideoStream.Start();
});
}
foreach (var remoteVideoStream in args.RemovedRemoteVideoStreams)
{
remoteVideoStream.Stop();
}
}
private async void Agent_OnCallsUpdatedAsync(object sender, CallsUpdatedEventArgs args)
{
var removedParticipants = new List<RemoteParticipant>();
var addedParticipants = new List<RemoteParticipant>();
foreach(var call in args.RemovedCalls)
{
removedParticipants.AddRange(call.RemoteParticipants.ToList<RemoteParticipant>());
}
foreach (var call in args.AddedCalls)
{
addedParticipants.AddRange(call.RemoteParticipants.ToList<RemoteParticipant>());
}
await OnParticipantChangedAsync(removedParticipants, addedParticipants);
}
private async Task OnParticipantChangedAsync(IEnumerable<RemoteParticipant> removedParticipants, IEnumerable<RemoteParticipant> addedParticipants)
{
foreach (var participant in removedParticipants)
{
foreach(var incomingVideoStream in participant.IncomingVideoStreams)
{
var remoteVideoStream = incomingVideoStream as RemoteIncomingVideoStream;
if (remoteVideoStream != null)
{
await remoteVideoStream.StopPreviewAsync();
}
}
participant.VideoStreamStateChanged -= OnVideoStreamStateChanged;
}
foreach (var participant in addedParticipants)
{
participant.VideoStreamStateChanged += OnVideoStreamStateChanged;
}
}
private void OnVideoStreamStateChanged(object sender, VideoStreamStateChangedEventArgs e)
{
CallVideoStream callVideoStream = e.CallVideoStream;
switch (callVideoStream.StreamDirection)
{
case StreamDirection.Outgoing:
OnOutgoingVideoStreamStateChanged(callVideoStream as OutgoingVideoStream);
break;
case StreamDirection.Incoming:
OnIncomingVideoStreamStateChanged(callVideoStream as IncomingVideoStream);
break;
}
}
private async void OnIncomingVideoStreamStateChanged(IncomingVideoStream incomingVideoStream)
{
switch (incomingVideoStream.State)
{
case VideoStreamState.Available:
{
switch (incomingVideoStream.Kind)
{
case VideoStreamKind.RemoteIncoming:
var remoteVideoStream = incomingVideoStream as RemoteIncomingVideoStream;
var uri = await remoteVideoStream.StartPreviewAsync();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
RemoteVideo.Source = MediaSource.CreateFromUri(uri);
});
break;
case VideoStreamKind.RawIncoming:
break;
}
break;
}
case VideoStreamState.Started:
break;
case VideoStreamState.Stopping:
break;
case VideoStreamState.Stopped:
if (incomingVideoStream.Kind == VideoStreamKind.RemoteIncoming)
{
var remoteVideoStream = incomingVideoStream as RemoteIncomingVideoStream;
await remoteVideoStream.StopPreviewAsync();
}
break;
case VideoStreamState.NotAvailable:
break;
}
}
Rendern von Remote-Videos
Fügen Sie jeden Remotevideostream an MediaElement
an.
private async Task AddVideoStreamsAsync(IReadOnlyList<RemoteVideoStream> remoteVideoStreams)
{
foreach (var remoteVideoStream in remoteVideoStreams)
{
var remoteUri = await remoteVideoStream.Start();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
RemoteVideo.Source = remoteUri;
RemoteVideo.Play();
});
}
}
Zustandsaktualisierung aufrufen
Wir müssen die Video-Renderer bereinigen, sobald der Anruf getrennt ist und den Fall behandeln, dass Remoteteilnehmer dem Anruf schon zu Anfang beitreten.
private async void Call_OnStateChanged(object sender, PropertyChangedEventArgs args)
{
switch (((Call)sender).State)
{
case CallState.Disconnected:
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
LocalVideo.Source = null;
RemoteVideo.Source = null;
});
break;
case CallState.Connected:
foreach (var remoteParticipant in call.RemoteParticipants)
{
String remoteParticipantMRI = remoteParticipant.Identifier.ToString();
remoteParticipantDictionary.TryAdd(remoteParticipantMRI, remoteParticipant);
await AddVideoStreams(remoteParticipant.VideoStreams);
remoteParticipant.OnVideoStreamsUpdated += Call_OnVideoStreamsUpdated;
}
break;
default:
break;
}
}
Beenden eines Anrufs
Beenden Sie den aktuellen Anruf, nachdem auf die Schaltfläche Hang Up
geklickt wurde. Fügen Sie HangupButton_Click die Implementierung hinzu, um einen Aufruf mit dem von uns erstellten callAgent zu beenden, und löschen Sie die Teilnehmeraktualisierung und die Ereignishandler für den Anrufstatus.
var call = this.callAgent?.Calls?.FirstOrDefault();
if (call != null)
{
try
{
await call.HangUpAsync(new HangUpOptions() { ForEveryone = true });
}
catch(Exception ex)
{
}
}
Ausführen des Codes
Sie können den Build in Visual Studio erstellen und den Code ausführen. Für Lösungsplattformen unterstützen wir ARM64
, x64
und x86
.
Sie können einen ausgehenden Videoanruf tätigen, indem Sie in das Textfeld eine Benutzer-ID eingeben und auf die Schaltfläche Start Call
klicken.
Hinweis: Durch den Aufruf von 8:echo123
wird der Video-Stream beendet, da der Echo-Bot das Video-Streaming nicht unterstützt.
Weitere Informationen zu Benutzer IDs (Identität) finden Sie im Leitfaden zu Benutzerzugriffstoken.
WinUI 3-Beispielcode
Voraussetzungen
Zum Durchführen dieses Tutorials benötigen Sie Folgendes:
Ein Azure-Konto mit einem aktiven Abonnement. Sie können kostenlos ein Konto erstellen.
Installieren Sie Visual Studio 2022 und Windows App SDK, Version 1.2 Preview 2.
Grundlegendes Verständnis für das Erstellen einer WinUI 3-App. Erstellen Ihres ersten WinUI 3-Projekts (Windows App SDK) ist eine gute Ressource für den Einstieg.
Eine bereitgestellte Communication Services-Ressource. Erstellen Sie eine Communication Services-Ressource. Für diese Schnellstartanleitung müssen Sie Ihre Verbindungszeichenfolge erfassen.
Ein Benutzerzugriffstoken für Ihren Azure Communication Service Sie können auch die Azure CLI verwenden und den Befehl mit Ihrer Verbindungszeichenfolge ausführen, um einen Benutzer und ein Zugriffs-Token zu erstellen.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
Ausführliche Informationen finden Sie unter Verwenden der Azure CLI zum Erstellen und Verwalten von Zugriffstoken.
Einrichten
Erstellen des Projekts
Erstellen Sie in Visual Studio ein neues Projekt mit der Vorlage Leere App, gepackt (WinUI 3 in Desktop), um eine WinUI 3-Einzelseiten-App einzurichten.
Installieren des Pakets
Klicken Sie mit der rechten Maustaste auf Ihr Projekt, und wechseln Sie zu Manage Nuget Packages
, um Azure.Communication.Calling.WindowsClient
1.0.0-beta.33 oder einer höhere Version zu installieren. Vergewissern Sie sich, dass „Vorabversion einbeziehen“ aktiviert ist.
Anfordern des Zugriffs
Fügen Sie Ihrem app.manifest
den folgenden Code hinzu:
<file name="RtmMvrMf.dll">
<activatableClass name="VideoN.VideoSchemeHandler" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
Einrichten des App-Frameworks
Wir müssen ein einfaches Layout konfigurieren, um unsere Logik anzufügen. Um einen ausgehenden Anruf zu tätigen, benötigen wir ein TextBox
-Element, um die Benutzer-ID des Angerufenen bereitzustellen. Außerdem benötigen wir die Schaltflächen Start Call
und Hang Up
.
Darüber hinaus müssen wir eine Vorschau des lokalen Videos anzeigen und das Remotevideo des anderen Teilnehmers rendern. Daher benötigen wir zwei Elemente zum Anzeigen der Videostreams.
Öffnen Sie in Ihrem Projekt MainWindow.xaml
, und ersetzen Sie den Inhalt durch folgende Implementierung.
<Page
x:Class="CallingQuickstart.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CallingQuickstart"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid x:Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="200*"/>
<RowDefinition Height="60*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" x:Name="AppTitleBar" Background="LightSeaGreen">
<!-- Width of the padding columns is set in LayoutMetricsChanged handler. -->
<!-- Using padding columns instead of Margin ensures that the background paints the area under the caption control buttons (for transparent buttons). -->
<TextBlock x:Name="QuickstartTitle" Text="Calling Quickstart sample title bar" Style="{StaticResource CaptionTextBlockStyle}" Padding="4,4,0,0"/>
</Grid>
<TextBox Grid.Row="1" x:Name="CalleeTextBox" PlaceholderText="Who would you like to call?" TextWrapping="Wrap" VerticalAlignment="Center" />
<Grid Grid.Row="2" Background="LightGray">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<MediaPlayerElement x:Name="LocalVideo" HorizontalAlignment="Center" Stretch="UniformToFill" Grid.Column="0" VerticalAlignment="Center" AutoPlay="True" />
<MediaPlayerElement x:Name="RemoteVideo" HorizontalAlignment="Center" Stretch="UniformToFill" Grid.Column="1" VerticalAlignment="Center" AutoPlay="True" />
</Grid>
<StackPanel Grid.Row="3" Orientation="Vertical" Grid.RowSpan="2">
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock VerticalAlignment="Center">Cameras:</TextBlock>
<ComboBox x:Name="CameraList" HorizontalAlignment="Left" Grid.Column="0" DisplayMemberPath="Name" SelectionChanged="CameraList_SelectionChanged" Margin="10"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button x:Name="CallButton" Content="Start/Join call" Click="CallButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="123"/>
<Button x:Name="HangupButton" Content="Hang up" Click="HangupButton_Click" VerticalAlignment="Center" Margin="10,0,0,0" Height="40" Width="123"/>
<CheckBox x:Name="MuteLocal" Content="Mute" Margin="10,0,0,0" Click="MuteLocal_Click" Width="74"/>
<CheckBox x:Name="BackgroundBlur" Content="Background blur" Width="142" Margin="10,0,0,0" Click="BackgroundBlur_Click"/>
</StackPanel>
</StackPanel>
<TextBox Grid.Row="4" x:Name="Stats" Text="" TextWrapping="Wrap" VerticalAlignment="Center" Height="30" Margin="0,2,0,0" BorderThickness="2" IsReadOnly="True" Foreground="LightSlateGray" />
</Grid>
</Page>
Öffnen Sie App.xaml.cs
(mit einem Rechtsklick auf Ihrer Maus und „Code anzeigen“ auswählen), und fügen Sie oben diese Zeile hinzu:
using CallingQuickstart;
Öffnen der MainWindow.xaml.cs
(mit einem Rechtsklick auf Ihrer Maus und „Code anzeigen“ auswählen), und ersetzen Sie den Inhalt mit der folgenden Implementierung:
using Azure.Communication.Calling.WindowsClient;
using Azure.WinRT.Communication;
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Media.Core;
namespace CallingQuickstart
{
public sealed partial class MainWindow : Window
{
CallAgent callAgent;
Call call;
DeviceManager deviceManager;
Dictionary<string, RemoteParticipant> remoteParticipantDictionary = new Dictionary<string, RemoteParticipant>();
public MainWindow()
{
this.InitializeComponent();
Task.Run(() => this.InitCallAgentAndDeviceManagerAsync()).Wait();
}
private async Task InitCallAgentAndDeviceManagerAsync()
{
// Initialize call agent and Device Manager
}
private async void Agent_OnIncomingCallAsync(object sender, IncomingCall incomingCall)
{
// Accept an incoming call
}
private async void CallButton_Click(object sender, RoutedEventArgs e)
{
// Start a call with video
}
private async void HangupButton_Click(object sender, RoutedEventArgs e)
{
// End the current call
}
private async void Call_OnStateChangedAsync(object sender, PropertyChangedEventArgs args)
{
var state = (sender as Call)?.State;
this.DispatcherQueue.TryEnqueue(() => {
State.Text = state.ToString();
});
}
}
}
Objektmodell
Die folgenden Klassen und Schnittstellen befassen sich mit einigen der wichtigsten Features des Azure Communication Services Calling SDK:
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. |
CallTokenCredential |
CallTokenCredential dient als tokengestützte Anmeldeinformation zum Instanziieren von CallAgent . |
CommunicationUserIdentifier |
CommunicationUserIdentifier wird zur Darstellung der Identität des Benutzers verwendet, der eine der folgenden Optionen sein kann: CommunicationUserIdentifier , PhoneNumberIdentifier oder CallingApplication . |
Authentifizieren des Clients
Zum Initialisieren eines CallAgent
benötigen Sie ein Benutzerzugriffs-Token. In der Regel wird dieses Token von einem Dienst mit einer für die Anwendung spezifischen Authentifizierung generiert. Weitere Informationen zu Benutzerzugriffstoken finden Sie im Leitfaden zu Benutzerzugriffstoken.
Ersetzen Sie für den Schnellstart <AUTHENTICATION_TOKEN>
durch ein Benutzerzugriffstoken, das für Ihre Azure Communication Service-Ressource generiert wurde.
Sobald Sie ein Token haben, initialisieren Sie damit eine CallAgent
-Instanz, die es uns ermöglicht, Anrufe zu tätigen und zu empfangen. Um auf die Kameras auf dem Gerät zugreifen zu können, benötigen wir auch eine Geräte-Manager-Instanz.
Fügen Sie der Funktion InitCallAgentAndDeviceManagerAsync
den folgenden Code hinzu:
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);
this.callAgent.OnCallsUpdated += Agent_OnCallsUpdatedAsync;
this.callAgent.OnIncomingCall += Agent_OnIncomingCallAsync;
Starten eines Anrufs mit Video
Fügen Sie die Implementierung zu CallButton_Click
hinzu, um einen Anruf mit Video zu starten. Wir müssen die Kameras mit der Gerätemanager-Instanz aufzählen und LocalVideoStream
konstruieren. Wir müssen VideoOptions
mit LocalVideoStream
festlegen und mit startCallOptions
übergeben, um die Anfangsoptionen für den Anruf festzulegen. Durch Anfügen von LocalVideoStream
an MediaPlayerElement
können wir die Vorschau des lokalen Videos sehen.
var startCallOptions = new StartCallOptions();
if (this.deviceManager.Cameras?.Count > 0)
{
var videoDeviceInfo = this.deviceManager.Cameras?.FirstOrDefault();
if (videoDeviceInfo != null)
{
var selectedCamerea = CameraList.SelectedItem as VideoDeviceDetails;
cameraStream = new LocalOutgoingVideoStream(selectedCamerea);
var localUri = await cameraStream.StartPreviewAsync();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
LocalVideo.Source = MediaSource.CreateFromUri(localUri);
});
startCallOptions.VideoOptions = new OutgoingVideoOptions(new[] { cameraStream });
}
}
var callees = new ICommunicationIdentifier[1]
{
new CommunicationUserIdentifier(CalleeTextBox.Text.Trim())
};
this.call = await this.callAgent.StartCallAsync(callees, startCallOptions);
this.call.OnRemoteParticipantsUpdated += Call_OnRemoteParticipantsUpdatedAsync;
this.call.OnStateChanged += Call_OnStateChangedAsync;
Annehmen eines eingehenden Anrufs
Fügen Sie die Implementierung zu Agent_OnIncomingCallAsync
hinzu, um einen eingehenden Anruf mit Video zu beantworten, und übergeben Sie den LocalVideoStream
an acceptCallOptions
.
var acceptCallOptions = new AcceptCallOptions();
if (this.deviceManager.Cameras?.Count > 0)
{
var videoDeviceInfo = this.deviceManager.Cameras?.FirstOrDefault();
if (videoDeviceInfo != null)
{
var selectedCamerea = CameraList.SelectedItem as VideoDeviceDetails;
cameraStream = new LocalOutgoingVideoStream(selectedCamerea);
var localUri = await cameraStream.StartPreviewAsync();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
LocalVideo.Source = MediaSource.CreateFromUri(localUri);
});
acceptCallOptions.VideoOptions = new OutgoingVideoOptions(new[] { localVideoStream });
}
}
call = await incomingCall.AcceptAsync(acceptCallOptions);
Remote-Teilnehmer- und -Videostreams
Alle Remoteteilnehmer sind über die RemoteParticipants
-Sammlung für eine Anrufinstanz verfügbar. Sobald der Anruf verbunden ist, können wir auf die Remote-Teilnehmer des Anrufs zugreifen und die Remote-Video-Streams verarbeiten.
Hinweis
Wenn ein Benutzer einem Anruf beitritt, kann er über die RemoteParticipants
-Sammlung auf die aktuellen Remoteteilnehmer zugreifen. Das OnRemoteParticipantsUpdated
-Ereignis wird für diese vorhandenen Teilnehmer nicht ausgelöst. Dieses Ereignis wird nur ausgelöst, wenn ein Remoteteilnehmer dem Anruf beitritt oder ihn verlässt, während sich der Benutzer bereits im Anruf befindet.
private async void Call_OnVideoStreamsUpdatedAsync(object sender, RemoteVideoStreamsEventArgs args)
{
foreach (var remoteVideoStream in args.AddedRemoteVideoStreams)
{
this.DispatcherQueue.TryEnqueue(async () => {
RemoteVideo.Source = MediaSource.CreateFromUri(await remoteVideoStream.Start());
RemoteVideo.MediaPlayer.Play();
});
}
foreach (var remoteVideoStream in args.RemovedRemoteVideoStreams)
{
remoteVideoStream.Stop();
}
}
private async void Agent_OnCallsUpdatedAsync(object sender, CallsUpdatedEventArgs args)
{
foreach (var call in args.AddedCalls)
{
foreach (var remoteParticipant in call.RemoteParticipants)
{
var remoteParticipantMRI = remoteParticipant.Identifier.ToString();
this.remoteParticipantDictionary.TryAdd(remoteParticipantMRI, remoteParticipant);
await AddVideoStreamsAsync(remoteParticipant.VideoStreams);
remoteParticipant.OnVideoStreamsUpdated += Call_OnVideoStreamsUpdatedAsync;
}
}
}
private async void Call_OnRemoteParticipantsUpdatedAsync(object sender, ParticipantsUpdatedEventArgs args)
{
foreach (var remoteParticipant in args.AddedParticipants)
{
String remoteParticipantMRI = remoteParticipant.Identifier.ToString();
this.remoteParticipantDictionary.TryAdd(remoteParticipantMRI, remoteParticipant);
await AddVideoStreamsAsync(remoteParticipant.VideoStreams);
remoteParticipant.OnVideoStreamsUpdated += Call_OnVideoStreamsUpdatedAsync;
}
foreach (var remoteParticipant in args.RemovedParticipants)
{
String remoteParticipantMRI = remoteParticipant.Identifier.ToString();
this.remoteParticipantDictionary.Remove(remoteParticipantMRI);
}
}
Rendern von Remote-Videos
Fügen Sie jeden Remotevideostream an MediaPlayerElement
an.
private async Task AddVideoStreamsAsync(IReadOnlyList<RemoteVideoStream> remoteVideoStreams)
{
foreach (var remoteVideoStream in remoteVideoStreams)
{
var remoteUri = await remoteVideoStream.Start();
this.DispatcherQueue.TryEnqueue(() => {
RemoteVideo.Source = MediaSource.CreateFromUri(remoteUri);
RemoteVideo.MediaPlayer.Play();
});
}
}
Zustandsaktualisierung aufrufen
Wir müssen die Video-Renderer bereinigen, sobald der Anruf getrennt ist und den Fall behandeln, dass Remoteteilnehmer dem Anruf schon zu Anfang beitreten.
private async void Call_OnStateChanged(object sender, PropertyChangedEventArgs args)
{
switch (((Call)sender).State)
{
case CallState.Disconnected:
this.DispatcherQueue.TryEnqueue(() => { =>
{
LocalVideo.Source = null;
RemoteVideo.Source = null;
});
break;
case CallState.Connected:
foreach (var remoteParticipant in call.RemoteParticipants)
{
String remoteParticipantMRI = remoteParticipant.Identifier.ToString();
remoteParticipantDictionary.TryAdd(remoteParticipantMRI, remoteParticipant);
await AddVideoStreams(remoteParticipant.VideoStreams);
remoteParticipant.OnVideoStreamsUpdated += Call_OnVideoStreamsUpdated;
}
break;
default:
break;
}
}
Beenden eines Anrufs
Beenden Sie den aktuellen Anruf, nachdem auf die Schaltfläche Hang Up
geklickt wurde. Fügen Sie HangupButton_Click die Implementierung hinzu, um einen Aufruf mit dem von uns erstellten callAgent zu beenden, und löschen Sie die Teilnehmeraktualisierung und die Ereignishandler für den Anrufstatus.
this.call.OnRemoteParticipantsUpdated -= Call_OnRemoteParticipantsUpdatedAsync;
this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions());
Ausführen des Codes
Sie können den Build in Visual Studio erstellen und den Code ausführen. Für Lösungsplattformen unterstützen wir ARM64
, x64
und x86
.
Sie können einen ausgehenden Videoanruf tätigen, indem Sie in das Textfeld eine Benutzer-ID eingeben und auf die Schaltfläche Start Call
klicken.
Hinweis: Durch den Aufruf von 8:echo123
wird der Video-Stream beendet, da der Echo-Bot das Video-Streaming nicht unterstützt.
Weitere Informationen zu Benutzer IDs (Identität) finden Sie im Leitfaden zu Benutzerzugriffstoken.