Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Warning
Azure Communication Services voert ingrijpende wijzigingen door en sommige services worden uitgefaseerd. Lees meer in de handleiding voor buitengebruikstelling en ingrijpende wijzigingen.
Het Group Calling Hero Sample van Azure Communication Services laat zien hoe de Calling Web SDK van Communication Services kan worden gebruikt om een ervaring voor groepsgesprekken te bouwen.
In deze quickstart leert u hoe het voorbeeld werkt voordat u het voorbeeld uitvoert op uw lokale computer en vervolgens het voorbeeld implementeert in Azure met behulp van uw eigen Azure Communication Services-resources.
Code downloaden
Zoek het project voor dit voorbeeld op GitHub. Een versie van het voorbeeld met functies die momenteel beschikbaar zijn als openbare preview, zoals Teams Interop en Gespreksopname , vindt u in een afzonderlijke vertakking.
Overzicht
Het voorbeeld heeft zowel een toepassing aan de clientzijde als een toepassing aan de serverzijde. De toepassing aan de clientzijde is een React/Redux-webtoepassing die gebruikmaakt van het Fluent UI-framework van Microsoft. Met deze toepassing worden aanvragen verzonden naar een ASP.NET Core-toepassing aan de serverzijde zodat de toepassing aan de clientzijde kan worden verbonden met Azure.
Het voorbeeld ziet er als volgt uit:
Wanneer u op de knop 'Gesprek starten' klikt, haalt de webtoepassing een gebruikertoegangstoken op uit de servertoepassing. Vervolgens wordt dit token gebruikt om de client-app met Azure Communication Services te verbinden. Zodra het token is opgehaald, wordt u gevraagd de camera en microfoon op te geven die u wilt gebruiken. U kunt uw apparaten uitschakelen/inschakelen met wisselknoppen:
Zodra u uw weergavenaam en apparaten hebt geconfigureerd, kunt u deelnemen aan de gesprekssessie. U ziet het hoofdgesprekscanvas waarin de belangrijkste oproepervaring zich bevindt.
Onderdelen van het hoofdgespreksscherm:
- Mediagalerie: het hoofdpodium waar deelnemers worden weergegeven. Als deelnemers hun camera hebben ingeschakeld, wordt hier hun videofeed weergegeven. Elke deelnemer beschikt over een afzonderlijke tegel waarop hun weergavenaam en videostream (indien beschikbaar) worden weergegeven
- Koptekst: Hier bevinden de primaire oproepbesturingselementen zich om instellingen en zijbalk van deelnemers in of uit te schakelen, video in of uit te schakelen, scherm te delen en het gesprek te verlaten.
- Zijbalk: Hier worden informatie over deelnemers en instellingen weergegeven wanneer u deze in- of uitschakelt met de bedieningselementen in de header. U kunt het onderdeel verwijderen door op X te klikken in de rechterbovenhoek. De zijbalk van deelnemers bevat een lijst met deelnemers en een koppeling om meer gebruikers uit te nodigen om te chatten. In de zijbalk met instellingen kunt u de microfoon- en camera-instellingen configureren.
Hieronder vindt u meer informatie over de vereisten en de stappen om het voorbeeld in te stellen.
Vereisten
- Een Azure-account met een actief abonnement. Zie Gratis een account maken voor meer informatie
- Node.js (12.18.4 en hoger)
- Visual Studio Code (stabiele build)
- Een Azure Communication Services-resource. Zie Een Azure Communication Services-resource maken voor meer informatie. U moet voor deze quickstart de verbindingsreeks van uw resource noteren.
Voordat u het voorbeeld voor de eerste keer uitvoert
Open een instantie van PowerShell, Windows Terminal, de opdrachtprompt of een vergelijkbare service en ga naar de map waarnaar u het voorbeeld wilt klonen.
git clone https://github.com/Azure-Samples/communication-services-web-calling-hero.gitHaal de
Connection Stringop via de Azure-portal of met behulp van de Azure CLI.az communication list-key --name "<acsResourceName>" --resource-group "<resourceGroup>"Zie Een Azure Communications-resource maken voor meer informatie over verbindingsreeksen
Zodra u het
Connection Stringbestand hebt, voegt u de verbindingsreeks toe aan het bestand samples/Server/appsetting.json. Voer in de variabele uw verbindingsreeks in:ResourceConnectionString.Haal de
Endpoint stringuit de Azure-portal of met behulp van de Azure CLI.az communication list-key --name "<acsResourceName>" --resource-group "<resourceGroup>"Zie Een Azure Communication-resource maken voor meer informatie over eindpuntreeksen.
Wanneer u de
Endpoint Stringhebt verkregen, voegt u de eindpunttekenreeks toe aan het bestand samples/Server/appsetting.json. Voer uw eindpunttekenreeks in de variabele inEndpointUrl
Lokaal uitvoeren
Afhankelijkheden installeren
npm run setupDe aanroepende app starten
npm run startHiermee opent u een clientserver op poort 3000 die de websitebestanden dient en een API-server op poort 8080 die functionaliteit uitvoert, zoals munttokens voor oproepdeelnemers.
Probleemoplossing
In de app wordt een scherm 'Niet-ondersteunde browser' weergegeven, maar ik gebruik een ondersteunde browser.
Als uw app wordt geleverd via een andere hostnaam dan localhost, moet u verkeer via https en niet http leveren.
Publiceren naar Azure
npm run setupnpm run buildnpm run package- De Azure-extensie gebruiken en de map Aanroepen/verwijderen implementeren in uw app-service
Resources opruimen
Als u een Communication Services-abonnement wilt opschonen en verwijderen, kunt u de resource of resourcegroep verwijderen. Als u de resourcegroep verwijdert, worden ook alle bijbehorende resources verwijderd. Meer informatie over het opschonen van resources.
Volgende stappen
Raadpleeg voor meer informatie de volgende artikelen:
- Vertrouwd raken met het gebruik van de Calling SDK
- Meer informatie over de werking van aanroepen
Verder lezen
- Voorbeelden - Vind meer voorbeelden en voorbeelden op onze overzichtspagina met voorbeelden.
- Redux: statusbeheer op de client
- FluentUI: door Microsoft ondersteunde bibliotheek voor de gebruikersinterface
- React: bibliotheek voor het ontwikkelen van gebruikersinterfaces
- ASP.NET Core: een framework voor het bouwen van webtoepassingen
De Azure Communication Services-voorbeeldtoepassing voor groepsgesprekken voor iOS demonstreert hoe de Communication Services Calling iOS SDK kan worden gebruikt om een ervaring voor groepsgesprekken met spraak en video te bouwen. In deze voorbeeldsnelstartgids leert u hoe u het voorbeeld instelt en uitvoert. Er wordt een overzicht gegeven van het voorbeeld voor context.
Code downloaden
Zoek het project voor dit voorbeeld op GitHub.
Overzicht
Het voorbeeld is een systeemeigen iOS-toepassing die gebruikmaakt van de Azure Communication Services iOS SDK's om een belervaring te bouwen die zowel spraak- als videogesprekken bevat. De toepassing maakt gebruik van een onderdeel aan de serverzijde om toegangstokens in te richten die vervolgens worden gebruikt om de Azure Communication Services SDK te initialiseren. Om dit serveronderdeel te configureren, kunt u gerust de zelfstudie Trusted Service with Azure Functions volgen.
Het voorbeeld ziet er als volgt uit:
Wanneer u op de knop Nieuwe oproep starten drukt, wordt u door de iOS-toepassing gevraagd uw weergavenaam in te voeren die u voor het gesprek wilt gebruiken.
Nadat u op Volgende hebt getikt op het scherm Gesprek starten, hebt u de mogelijkheid om de groeps-id van de oproep te delen via het iOS-shareblad.
Met de toepassing kunt u ook deelnemen aan een bestaande Azure Communication Services-aanroep door de koppeling naar de id of de teams-id van de bestaande aanroep op te geven.
Nadat u deelneemt aan een gesprek, wordt u gevraagd om de toepassing toestemming te geven om toegang te krijgen tot uw camera en microfoon, als deze nog niet is geautoriseerd. Houd er rekening mee dat, net als alle AVFoundation-apps, echte audio- en videofunctionaliteit alleen beschikbaar is op echte hardware.
Zodra u uw weergavenaam hebt geconfigureerd en deelneemt aan het gesprek, ziet u het hoofdgesprekcanvas waarin de belangrijkste oproepervaring zich bevindt.
Onderdelen van het hoofdgespreksscherm:
- Mediagalerie: het hoofdpodium waar deelnemers worden weergegeven. Als deelnemers hun camera hebben ingeschakeld, wordt hier hun videofeed weergegeven. Elke deelnemer heeft een eigen tegel waarop de weergavenaam en videostream te zien zijn (als die er is). De galerie ondersteunt meerdere deelnemers en wordt bijgewerkt wanneer deelnemers aan het gesprek worden toegevoegd of verwijderd.
- Actiebalk: hier bevinden zich de primaire oproepbesturingselementen. Met deze besturingselementen kunt u uw video en microfoon in-/uitschakelen, uw scherm delen en het gesprek verlaten.
Hieronder vindt u meer informatie over de vereisten en stappen om het voorbeeld in te stellen.
Vereisten
- Een Azure-account met een actief abonnement. Zie Gratis een account maken voor meer informatie.
- Een Mac waarop Xcode wordt uitgevoerd, evenals een geldig ontwikkelaarscertificaat dat is geïnstalleerd in uw Sleutelhanger.
- Een Azure Communication Services-resource. Zie Een Azure Communication Services-resource maken voor meer informatie.
- Een Azure-functie waarop het verificatie-eindpunt wordt uitgevoerd om toegangstokens op te halen.
Lokaal voorbeeld uitvoeren
Het voorbeeld van groepsgesprekken kan lokaal worden uitgevoerd met behulp van XCode. Ontwikkelaars kunnen hun fysieke apparaat of een emulator gebruiken om de toepassing te testen.
Voordat u het voorbeeld voor de eerste keer uitvoert
- Installeer afhankelijkheden door uit te voeren
pod install. - Open
AzureCalling.xcworkspacein Xcode. - Maak in de hoofdmap een tekstbestand met de naam
AppSettings.xcconfigen stel de waarde in:communicationTokenFetchUrl = <your authentication endpoint, without the https:// component>
Voorbeeld uitvoeren
Bouw en voer het voorbeeld uit in XCode met behulp van het AzureCalling-doel op de simulator of het apparaat van uw keuze.
(Optioneel) Een verificatie-eindpunt beveiligen
Voor demonstratiedoeleinden gebruikt dit voorbeeld standaard een openbaar toegankelijk eindpunt om een Azure Communication Services-toegangstoken op te halen. Voor productiescenario's raden we u aan uw eigen beveiligde eindpunt te gebruiken om uw eigen tokens in te richten.
Met aanvullende configuratie biedt dit voorbeeld ondersteuning voor het maken van verbinding met een met Microsoft Entra ID beveiligd eindpunt (Microsoft Entra ID), zodat gebruikersaanmelding is vereist voor de app om een Azure Communication Services-toegangstoken op te halen. Zie de onderstaande stappen:
- Schakel Microsoft Entra-verificatie in uw app in.
- Ga naar de overzichtspagina van uw geregistreerde app onder Microsoft Entra App Registrations. Noteer de
Application (client) ID, ,Directory (tenant) IDApplication ID URI
- Maak een
AppSettings.xcconfigbestand in de hoofdmap als dit nog niet aanwezig is en voeg de waarden toe:communicationTokenFetchUrl = <Application ID URI, without the https:// component> aadClientId = <Application (client) ID> aadTenantId = <Directory (tenant) ID>
Resources opruimen
Als u een Communication Services-abonnement wilt opschonen en verwijderen, kunt u de resource of resourcegroep verwijderen. Als u de resourcegroep verwijdert, worden ook alle bijbehorende resources verwijderd. Meer informatie over het opschonen van resources.
Volgende stappen
Raadpleeg voor meer informatie de volgende artikelen:
- Vertrouwd raken met het gebruik van de Calling SDK
- Meer informatie over de werking van aanroepen
Verder lezen
- Azure Communication GitHub: u vindt meer voorbeelden en informatie op de officiële GitHub-pagina
- Voorbeelden - Vind meer voorbeelden en voorbeelden op onze overzichtspagina met voorbeelden.
- Azure Communication Calling Features - Meer informatie over de Calling SDK voor iOS -Azure Communication iOS Calling SDK
Het Hero-voorbeeld voor groepsgesprekken van Azure Communication Services voor Android laat zien hoe de Communication Services Calling Android SDK kan worden gebruikt om een ervaring voor groepsgesprekken met spraak en video te bouwen. In deze voorbeeldsnelstartgids leert u hoe u het voorbeeld instelt en uitvoert. Er wordt een overzicht gegeven van het voorbeeld voor context.
Code downloaden
Zoek het project voor dit voorbeeld op GitHub.
Overzicht
Het voorbeeld is een systeemeigen Android-toepassing die gebruikmaakt van de Azure Communication Services Android UI-clientbibliotheek om een belervaring te bouwen die zowel spraak- als videogesprekken bevat. De toepassing maakt gebruik van een onderdeel aan de serverzijde om toegangstokens in te richten die vervolgens worden gebruikt om de Azure Communication Services SDK te initialiseren. Om dit serveronderdeel te configureren, kunt u gerust de zelfstudie Trusted Service with Azure Functions volgen.
Het voorbeeld ziet er als volgt uit:
Wanneer u op de knop Nieuwe oproep starten drukt, wordt u in de Android-toepassing gevraagd uw weergavenaam in te voeren die u voor het gesprek wilt gebruiken.
Nadat u op 'Volgende' op de pagina 'Een gesprek starten' hebt getikt, hebt u de mogelijkheid om de 'Groepsoproep-id' te delen.
Met de applicatie kunt u deelnemen aan een bestaand Azure Communication Services-gesprek door de id van het bestaande gesprek of de koppeling naar de vergaderings-id van Teams, en de weergavenaam op te geven.
Nadat u deelneemt aan een gesprek, wordt u gevraagd om de toepassing toestemming te geven om toegang te krijgen tot uw camera en microfoon, als deze nog niet is geautoriseerd. U ziet het hoofdgesprekscanvas waarin de belangrijkste gesprekservaring zich bevindt.
Onderdelen van het hoofdgespreksscherm:
- Mediagalerie: het hoofdpodium waar deelnemers worden weergegeven. Als deelnemers hun camera hebben ingeschakeld, wordt hier hun videofeed weergegeven. Elke deelnemer heeft een eigen tegel waarop de weergavenaam en videostream te zien zijn (als die er is). De galerie ondersteunt meerdere deelnemers en wordt bijgewerkt wanneer deelnemers aan het gesprek worden toegevoegd of verwijderd.
- Actiebalk: hier bevinden zich de primaire oproepbesturingselementen. Met deze besturingselementen kunt u uw video en microfoon in-/uitschakelen, uw scherm delen en het gesprek verlaten.
Hieronder vindt u meer informatie over de vereisten en stappen om het voorbeeld in te stellen.
Vereisten
- Een Azure-account met een actief abonnement. Zie Gratis een account maken voor meer informatie.
- Android Studio wordt uitgevoerd op uw computer
- Een Azure Communication Services-resource. Zie Een Azure Communication Services-resource maken voor meer informatie.
- Een Azure-functie waarop het verificatie-eindpunt wordt uitgevoerd om toegangstokens op te halen.
Lokaal voorbeeld uitvoeren
De voorbeeldapp voor groepsgesprekken kan lokaal worden uitgevoerd met behulp van Android Studio. Ontwikkelaars kunnen hun fysieke apparaat of een emulator gebruiken om de toepassing te testen.
Voordat u het voorbeeld voor de eerste keer uitvoert
- Open Android Studio en selecteer
Open an Existing Project - Open de map
AzureCallingin de gedownloade release voor het voorbeeld. - Klap app/assets uit om
appSettings.propertiesbij te werken. Stel de waarde voor de sleutelcommunicationTokenFetchUrlin op de URL van het authenticatie-eindpunt dat u als vereiste hebt ingesteld.
Voorbeeld uitvoeren
Bouw en voer het voorbeeld uit in Android Studio.
(Optioneel) Een verificatie-eindpunt beveiligen
Voor demonstratiedoeleinden gebruikt dit voorbeeld standaard een openbaar toegankelijk eindpunt om een Azure Communication Services-token op te halen. Voor productiescenario's raden we u aan uw eigen beveiligde eindpunt te gebruiken om uw eigen tokens in te richten.
Met extra configuratie ondersteunt dit voorbeeld het maken van verbinding met een met Microsoft Entra ID beveiligd eindpunt (Microsoft Entra ID), zodat gebruikersaanmelding is vereist voor de app om een Azure Communication Services-token op te halen. Zie de onderstaande stappen:
Schakel Microsoft Entra-verificatie in uw app in.
Ga naar de overzichtspagina van uw geregistreerde app onder Microsoft Entra App Registrations. Let op de
Package name,Signature hash,MSAL Configuration.
Bewerk
AzureCalling/app/src/main/res/raw/auth_config_single_account.jsonen stelisAADAuthEnabledin om Microsoft Entra ID in te schakelen.Bewerk
AndroidManifest.xmlen stelandroid:pathin op de handtekeninghash van de sleutelopslag. (Optioneel. De huidige waarde maakt gebruik van hash uit gebundelde foutopsporing.keystore. Als er een ander sleutelarchief wordt gebruikt, moet dit worden bijgewerkt.)<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>Kopieer de MSAL Android-configuratie vanuit de Azure-portal en plak deze in
AzureCalling/app/src/main/res/raw/auth_config_single_account.json. Neem "account_mode": "SINGLE" op{ "client_id": "", "authorization_user_agent": "DEFAULT", "redirect_uri": "", "account_mode" : "SINGLE", "authorities": [ { "type": "AAD", "audience": { "type": "AzureADMyOrg", "tenant_id": "" } } ] }Bewerk
AzureCalling/app/src/main/res/raw/auth_config_single_account.jsonen stel de waarde in voor de sleutelcommunicationTokenFetchUrlals de URL voor uw beveiligde verificatie-eindpunt.Bewerk
AzureCalling/app/src/main/res/raw/auth_config_single_account.jsonen stel de waarde voor de sleutelaadScopesin uit de bereikenAzure Active DirectoryExpose an APIStel de waarde voor
graphURLinAzureCalling/app/assets/appSettings.propertiesals het Graph API-eindpunt om gebruikersgegevens op te halen.Bewerk
AzureCalling/app/src/main/assets/appSettings.propertiesen stel de waarde voor de sleuteltenantin om stille aanmelding in te schakelen, zodat de gebruiker niet opnieuw en opnieuw hoeft te worden geverifieerd tijdens het opnieuw opstarten van de toepassing.
Resources opruimen
Als u een Communication Services-abonnement wilt opschonen en verwijderen, kunt u de resource of resourcegroep verwijderen. Als u de resourcegroep verwijdert, worden ook alle bijbehorende resources verwijderd. Meer informatie over het opschonen van resources.
Volgende stappen
Raadpleeg voor meer informatie de volgende artikelen:
- Vertrouwd raken met het gebruik van de Calling SDK
- Meer informatie over de werking van aanroepen
Verder lezen
- Azure Communication GitHub: u vindt meer voorbeelden en informatie op de officiële GitHub-pagina
- Voorbeelden - Vind meer voorbeelden en voorbeelden op onze overzichtspagina met voorbeelden.
- Azure Communication-belfuncties - Voor meer informatie over de Android-SDK voor bellen -Azure Communication Android Calling SDK
Het Hero-voorbeeld voor groepsgesprekken voor Windows van Azure Communication Services laat zien hoe de Communication Services Calling Windows SDK kan worden gebruikt om een groepsbelervaring met spraak en video te bouwen. In dit voorbeeld leert u hoe u het voorbeeld instelt en uitvoert. Er wordt een overzicht gegeven van het voorbeeld voor context.
In deze quickstart leert u hoe u een 1:1-videogesprek start met behulp van de Azure Communication Services Calling SDK voor Windows.
UWP-voorbeeldcode
Vereisten
Voor het voltooien van deze zelfstudie moet aan de volgende vereisten worden voldaan:
Een Azure-account met een actief abonnement. Gratis een account maken
Installeer Visual Studio 2022 met Universeel Windows-platform ontwikkelworkload.
Een geïmplementeerde Communication Services-resource. Een Communication Services-resource maken. Voor deze quickstart moet u uw verbindingsreeks noteren.
Een toegangstoken voor gebruikers voor uw Azure Communication Service. U kunt ook de Azure CLI gebruiken en de opdracht uitvoeren met uw verbindingsreeks om een gebruiker en een toegangstoken te maken.
az communication identity token issue --scope voip --connection-string "yourConnectionString"Zie Azure CLI gebruiken voor het maken en beheren van toegangstokens voor meer informatie.
Configureren
Het project maken
Maak in Visual Studio een nieuw project met de sjabloon Blank App (Universal Windows) om een UWP-app (single page Universeel Windows-platform) in te stellen.
Het pakket installeren
Klik met de rechtermuisknop op uw project en ga naar Manage Nuget Packages om Azure.Communication.Calling.WindowsClient1.2.0-beta.1 of hoger te installeren. Zorg ervoor dat 'Preleased opnemen' is aangevinkt.
Toegang aanvragen
Ga naar Package.appxmanifest en klik op Capabilities.
Schakel Internet (Client & Server) in om inkomende en uitgaande toegang tot het internet te krijgen.
Controleer Microphone of u toegang wilt krijgen tot de audiofeed van de microfoon.
Controleer WebCam of u toegang hebt tot de camera van het apparaat.
Voeg de volgende code toe aan uw Package.appxmanifest door met de rechtermuisknop te klikken en Code weergeven te kiezen.
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>RtmMvrUap.dll</Path>
<ActivatableClass ActivatableClassId="VideoN.VideoSchemeHandler" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions>
Stel het app-framework in
We moeten een eenvoudige indeling configureren om onze logica te koppelen. Om een uitgaande oproep te plaatsen, hebben we TextBox nodig om de gebruikers-id van de opgebelde gebruiker op te geven. We hebben ook een Start Call knop en een Hang Up knop nodig.
We moeten ook een voorbeeld van de lokale video bekijken en de externe video van de andere deelnemer weergeven. We hebben dus twee elementen nodig om de videostreams weer te geven.
Open het MainPage.xaml project en vervang de inhoud door de volgende implementatie.
<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>
Open App.xaml.cs (klik met de rechtermuisknop en kies Code weergeven) en voeg deze regel bovenaan toe:
using CallingQuickstart;
Open de MainPage.xaml.cs (klik met de rechtermuisknop en kies Code bekijken) en vervang de inhoud door de volgende implementatie:
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
}
}
}
Objectmodel
De volgende klassen en interfaces verwerken enkele van de belangrijkste functies van de Azure Communication Services Calling SDK:
| Name | Beschrijving |
|---|---|
CallClient |
Het CallClient is het belangrijkste ingangspunt voor de clientbibliotheek voor Calling. |
CallAgent |
Het CallAgent wordt gebruikt om oproepen te starten en eraan deel te nemen. |
CommunicationCall |
Het CommunicationCall wordt gebruikt voor het beheren van geplaatste of gekoppelde oproepen. |
CallTokenCredential |
De CallTokenCredential wordt gebruikt als het tokengeloofsgegeven om de CallAgent te instantiëren. |
CommunicationUserIdentifier |
Het CommunicationUserIdentifier wordt gebruikt om de identiteit van de gebruiker weer te geven. Dit kan een van de volgende opties zijn: CommunicationUserIdentifier, PhoneNumberIdentifier of CallingApplication. |
De client verifiëren
Als u een CallAgentinitialisatie wilt uitvoeren, hebt u een token voor gebruikerstoegang nodig. Over het algemeen wordt dit token gegenereerd op basis van een service met verificatie die specifiek is voor de toepassing. Raadpleeg de handleiding gebruikerstoegangstokens voor meer informatie over tokens voor gebruikerstoegang.
Voor de quickstart vervangt u <AUTHENTICATION_TOKEN> door een gebruikerstoegangstoken dat voor uw Azure Communication Service-resource is gegenereerd.
Zodra u een token hebt, initialiseert u er een CallAgent exemplaar mee, zodat we oproepen kunnen plaatsen en ontvangen. Om toegang te krijgen tot de camera's op het apparaat, moeten we ook Apparaatbeheer exemplaar ophalen.
Voeg de volgende code toe aan de InitCallAgentAndDeviceManagerAsync functie.
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
}
}
Een gesprek starten met video
Voeg de implementatie toe aan de CallButton_Click om een videogesprek te starten. We moeten de camera's opsommen met de Device Manager-instantie en LocalOutgoingVideoStream opbouwen. We moeten het VideoOptions instellen met LocalVideoStream en het met startCallOptions doorgeven om de initiële opties voor het gesprek in te stellen. Door LocalOutgoingVideoStream aan een MediaElement te koppelen, kunnen we de voorbeeldweergave van de lokale video zien.
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;
}
Voeg de methoden toe om de verschillende typen oproepen te starten of eraan deel te nemen (1:1 Azure Communication Services-oproep, 1:1 telefoongesprek, Azure Communication Services-groepsgesprek, deelnemen aan Teams-vergadering, enzovoort).
private async Task<CommunicationCall> StartAcsCallAsync(string acsCallee)
{
var options = await GetStartCallOptionsAsync();
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 GetStartCallOptionsAsync();
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> GetStartCallOptionsAsync()
{
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 } }
};
}
Voeg de code toe om de LocalVideoStream te maken, afhankelijk van de geselecteerde camera op de CameraList_SelectionChanged methode.
var selectedCamera = CameraList.SelectedItem as VideoDeviceDetails;
cameraStream = new LocalOutgoingVideoStream(selectedCamera);
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);
}
Een inkomende oproep accepteren
Voeg de implementatie toe aan de OnIncomingCallAsync om een inkomende oproep met video te beantwoorden en geef LocalVideoStream door aan acceptCallOptions.
var incomingCall = args.IncomingCall;
var acceptCallOptions = new AcceptCallOptions() {
IncomingVideoOptions = new IncomingVideoOptions()
{
IncomingVideoStreamKind = VideoStreamKind.RemoteIncoming
}
};
_ = await incomingCall.AcceptAsync(acceptCallOptions);
Externe deelnemer en externe videostreams
Alle deelnemers op afstand zijn beschikbaar via de verzameling RemoteParticipants van een oproepinstantie. Zodra de oproep is verbonden (CallState.Connected), hebben we toegang tot de externe deelnemers aan het gesprek en verwerken we de externe videostreams.
Notitie
Wanneer een gebruiker deelneemt aan een gesprek, heeft deze via de RemoteParticipants verzameling toegang tot de huidige externe deelnemers. De RemoteParticipantsUpdated gebeurtenis wordt niet geactiveerd voor deze bestaande deelnemers. Deze gebeurtenis wordt alleen geactiveerd wanneer een externe deelnemer deelneemt of de oproep verlaat terwijl de gebruiker zich al in het gesprek bevindt.
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;
}
}
Externe video's weergeven
Koppel elke externe videostream aan de MediaElement.
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();
});
}
}
Update van oproepstatus
We moeten de videorenderers opruimen zodra het gesprek is beëindigd en rekening houden met het geval waarin deelnemers op afstand voor het eerst aan het gesprek deelnemen.
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;
}
}
Een gesprek beëindigen
Beëindig het huidige gesprek wanneer op de Hang Up knop wordt geklikt. Voeg de implementatie toe aan de HangupButton_Click om een gesprek te beëindigen met de callAgent die we hebben gemaakt, en verwijder de gebeurtenis-handlers voor deelnemersupdates en wijzigingen in de gespreksstatus.
var call = this.callAgent?.Calls?.FirstOrDefault();
if (call != null)
{
try
{
await call.HangUpAsync(new HangUpOptions() { ForEveryone = true });
}
catch(Exception ex)
{
}
}
De code uitvoeren
U kunt de code bouwen en uitvoeren in Visual Studio. Voor oplossingsplatforms ondersteunen we ARM64, x64 en x86.
U kunt een uitgaande videogesprek voeren door een gebruikers-id op te geven in het tekstveld en op de Start Call knop te klikken.
Opmerking: bellen 8:echo123 stopt de videostream omdat echobot geen ondersteuning biedt voor videostreaming.
Raadpleeg de handleiding gebruikerstoegangstokens voor meer informatie over gebruikers-id's (identiteit).
WinUI 3-voorbeeldcode
Vereisten
Voor het voltooien van deze zelfstudie moet aan de volgende vereisten worden voldaan:
Een Azure-account met een actief abonnement. Gratis een account maken
Installeer Visual Studio 2022 en Windows-app SDK versie 1.2 preview 2.
Basiskennis van het maken van een WinUI 3-app. Het maken van uw eerste WinUI 3-project (Windows-app SDK) is een goede resource om mee te beginnen.
Een geïmplementeerde Communication Services-resource. Een Communication Services-resource maken. Voor deze quickstart moet u uw verbindingsreeks noteren.
Een toegangstoken voor gebruikers voor uw Azure Communication Service. U kunt ook de Azure CLI gebruiken en de opdracht uitvoeren met uw verbindingsreeks om een gebruiker en een toegangstoken te maken.
az communication identity token issue --scope voip --connection-string "yourConnectionString"Zie Azure CLI gebruiken voor het maken en beheren van toegangstokens voor meer informatie.
Configureren
Het project maken
Maak in Visual Studio een nieuw project met de sjabloon Blank App, Packaged (WinUI 3 in Desktop) om een WinUI 3-app met één pagina in te stellen.
Het pakket installeren
Klik met de rechtermuisknop op uw project en ga naar Manage Nuget Packages om Azure.Communication.Calling.WindowsClient1.0.0 of hoger te installeren. Zorg ervoor dat 'Preleased opnemen' is aangevinkt.
Toegang aanvragen
Voeg de volgende code toe aan uw app.manifest:
<file name="RtmMvrMf.dll">
<activatableClass name="VideoN.VideoSchemeHandler" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
Stel het app-framework in
We moeten een eenvoudige indeling configureren om onze logica te koppelen. Om een uitgaande oproep te plaatsen, hebben we TextBox nodig om de gebruikers-id van de opgebelde gebruiker op te geven. We hebben ook een Start Call knop en een Hang Up knop nodig.
We moeten ook een voorbeeld van de lokale video bekijken en de externe video van de andere deelnemer weergeven. We hebben dus twee elementen nodig om de videostreams weer te geven.
Open het MainWindow.xaml project en vervang de inhoud door de volgende implementatie.
<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>
Open App.xaml.cs (klik met de rechtermuisknop en kies Code weergeven) en voeg deze regel bovenaan toe:
using CallingQuickstart;
Open de MainWindow.xaml.cs (klik met de rechtermuisknop en kies Code bekijken) en vervang de inhoud door de volgende implementatie:
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();
});
}
}
}
Objectmodel
De volgende klassen en interfaces verwerken enkele van de belangrijkste functies van de Azure Communication Services Calling SDK:
| Name | Beschrijving |
|---|---|
CallClient |
Het CallClient is het belangrijkste ingangspunt voor de clientbibliotheek voor Calling. |
CallAgent |
Het CallAgent wordt gebruikt om oproepen te starten en eraan deel te nemen. |
CommunicationCall |
Het CommunicationCall wordt gebruikt voor het beheren van geplaatste of gekoppelde oproepen. |
CallTokenCredential |
De CallTokenCredential wordt gebruikt als het tokengeloofsgegeven om de CallAgent te instantiëren. |
CommunicationUserIdentifier |
Het CommunicationUserIdentifier wordt gebruikt om de identiteit van de gebruiker weer te geven. Dit kan een van de volgende opties zijn: CommunicationUserIdentifier, PhoneNumberIdentifier of CallingApplication. |
De client verifiëren
Als u een CallAgentinitialisatie wilt uitvoeren, hebt u een token voor gebruikerstoegang nodig. Over het algemeen wordt dit token gegenereerd op basis van een service met verificatie die specifiek is voor de toepassing. Raadpleeg de handleiding gebruikerstoegangstokens voor meer informatie over tokens voor gebruikerstoegang.
Voor de quickstart vervangt u <AUTHENTICATION_TOKEN> door een gebruikerstoegangstoken dat voor uw Azure Communication Service-resource is gegenereerd.
Zodra u een token hebt, initialiseert u daarmee een exemplaar van CallAgent, waarmee u oproepen kunt plaatsen en ontvangen. Om toegang te krijgen tot de camera's op het apparaat, moeten we ook een instantie van Apparaatbeheer ophalen.
Voeg de volgende code toe aan de InitCallAgentAndDeviceManagerAsync functie.
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;
Een gesprek starten met video
Voeg de implementatie toe aan de CallButton_Click om een oproep met beeld te starten. We moeten de camera's opsommen met de instantie van Apparaatbeheer en LocalVideoStream opbouwen. We moeten de VideoOptions instellen met LocalVideoStream en deze samen met startCallOptions doorgeven om de initiële opties voor het gesprek in te stellen. Door LocalVideoStream aan een MediaPlayerElement te koppelen, kunnen we de voorbeeldweergave van de lokale video zien.
var startCallOptions = new StartCallOptions();
if (this.deviceManager.Cameras?.Count > 0)
{
var videoDeviceInfo = this.deviceManager.Cameras?.FirstOrDefault();
if (videoDeviceInfo != null)
{
var selectedCamera = CameraList.SelectedItem as VideoDeviceDetails;
cameraStream = new LocalOutgoingVideoStream(selectedCamera);
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;
Een inkomende oproep accepteren
Voeg de implementatie toe aan de Agent_OnIncomingCallAsync om een inkomende oproep met video te beantwoorden, geef LocalVideoStream door aan acceptCallOptions.
var acceptCallOptions = new AcceptCallOptions();
if (this.deviceManager.Cameras?.Count > 0)
{
var videoDeviceInfo = this.deviceManager.Cameras?.FirstOrDefault();
if (videoDeviceInfo != null)
{
var selectedCamera = CameraList.SelectedItem as VideoDeviceDetails;
cameraStream = new LocalOutgoingVideoStream(selectedCamera);
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);
Deelnemer op afstand en videostreams op afstand
Alle externe deelnemers zijn beschikbaar via de verzameling RemoteParticipants in een gespreksinstantie. Zodra de oproep is verbonden, hebben we toegang tot de externe deelnemers aan het gesprek en verwerken we de externe videostreams.
Notitie
Wanneer een gebruiker deelneemt aan een gesprek, heeft deze via de RemoteParticipants verzameling toegang tot de huidige externe deelnemers. De OnRemoteParticipantsUpdated gebeurtenis wordt niet geactiveerd voor deze bestaande deelnemers. Deze gebeurtenis wordt alleen geactiveerd wanneer een externe deelnemer deelneemt of de oproep verlaat terwijl de gebruiker zich al in het gesprek bevindt.
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);
}
}
Externe video's weergeven
Voor elke externe videostream koppelt u deze aan de MediaPlayerElement.
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();
});
}
}
Update van oproepstatus
We moeten de videorenderers opruimen zodra het gesprek is beëindigd en rekening houden met het geval waarin deelnemers op afstand voor het eerst aan het gesprek deelnemen.
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;
}
}
Een gesprek beëindigen
Beëindig het huidige gesprek wanneer op de Hang Up knop wordt geklikt. Voeg de implementatie toe aan HangupButton_Click om een gesprek te beëindigen met de callAgent die we hebben gemaakt, en ruim de gebeurtenis-handlers voor deelnemersupdates en gespreksstatus op.
this.call.OnRemoteParticipantsUpdated -= Call_OnRemoteParticipantsUpdatedAsync;
this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions());
De code uitvoeren
U kunt de code bouwen en uitvoeren in Visual Studio. Voor oplossingsplatforms ondersteunen we ARM64, x64 en x86.
U kunt een uitgaande videogesprek voeren door een gebruikers-id op te geven in het tekstveld en op de Start Call knop te klikken.
Opmerking: bellen 8:echo123 stopt de videostream omdat echobot geen ondersteuning biedt voor videostreaming.
Raadpleeg de handleiding gebruikerstoegangstokens voor meer informatie over gebruikers-id's (identiteit).