Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Varning
Azure Communication Services inför icke bakåtkompatibla ändringar, och vissa tjänster avvecklas. Läs mer i guiden om utfasning och brytande ändringar.
Azure Communication Services Group Calling Hero-exemplet visar hur Communication Services Calling Web SDK kan användas för att skapa en lösning för gruppsamtal.
I den här exempelsnabbstarten lär vi oss hur exemplet fungerar innan vi kör exemplet på den lokala datorn och distribuerar sedan exemplet till Azure med dina egna Azure Communication Services-resurser.
Ladda ned kod
Hitta projektet för det här exemplet på GitHub. En version av exemplet som innehåller funktioner som för närvarande finns i offentlig förhandsversion, till exempel Teams Interop och Samtalsinspelning , finns på en separat gren.
Översikt
Exemplet har både ett program på klientsidan och ett program på serversidan. Programmet på klientsidan är ett React/Redux-webbprogram som använder Microsofts Fluent UI-ramverk. Det här programmet skickar begäranden till ett ASP.NET Core-program på serversidan som hjälper programmet på klientsidan att ansluta till Azure.
Så här ser exemplet ut:
När du trycker på knappen Starta ett anrop hämtar webbprogrammet en användaråtkomsttoken från programmet på serversidan. Den här token används sedan för att ansluta klientappen till Azure Communication Services. När token har hämtats uppmanas du att ange den kamera och mikrofon som du vill använda. Du kan inaktivera/aktivera dina enheter med växlingskontroller:
När du har konfigurerat visningsnamnet och enheterna kan du ansluta till samtalssessionen. Du kommer att se huvudvyn för samtal där de viktigaste samtalsfunktionerna visas.
Komponenter i huvudsamtalsskärmen:
- Mediegalleri: Huvudscenen där deltagarna visas. Om en deltagare har sin kamera aktiverad visas deras videoflöde här. Varje deltagare har en egen ruta som visar deras visningsnamn och videoflöde (om det finns något)
- Sidhuvud: Här finns de viktigaste samtalskontrollerna för att växla inställningar och sidofältet för deltagare, slå av/på video och ljud, dela skärmen och lämna samtalet.
- Sidofält: Här visas information om deltagare och inställningar när visningen aktiveras med reglagen i sidhuvudet. Komponenten kan stängas med ”X” i det övre högra hörnet. Deltagarnas sidofält visar en lista över deltagare och en länk för att bjuda in fler användare att chatta. Med inställningssidan kan du konfigurera mikrofon- och kamerainställningar.
Nedan hittar du mer information om förutsättningar och steg för att konfigurera exemplet.
Förutsättningar
- Ett Azure-konto med en aktiv prenumeration. Mer information finns i Skapa ett konto kostnadsfritt
- Node.js (12.18.4 och senare)
- Visual Studio Code (stabil version)
- En Azure Communication Services-resurs. Mer information finns i Skapa en Azure Communication Services-resurs. Du måste registrera din resurs anslutningssträng för den här snabbstarten.
Innan du kör exemplet för första gången
Öppna en instans av PowerShell, Windows-terminal, kommandotolken eller motsvarande och navigera till katalogen som du vill klona exemplet till.
git clone https://github.com/Azure-Samples/communication-services-web-calling-hero.gitHämta
Connection Stringfrån Azure-portalen eller med Azure CLI.az communication list-key --name "<acsResourceName>" --resource-group "<resourceGroup>"Mer information om anslutningssträng finns i Skapa en Azure-kommunikationsresurser
När du har hämtat
Connection String, lägger du till anslutningssträngen i filen samples/Server/appsetting.json. Ange din anslutningssträng i variabeln:ResourceConnectionString.Hämta
Endpoint stringfrån Azure-portalen eller med Azure CLI.az communication list-key --name "<acsResourceName>" --resource-group "<resourceGroup>"Mer information om slutpunktssträngar finns i Skapa en Azure-kommunikationsresurs
När du har hämtat
Endpoint String, lägger du till slutpunktssträngen i filen samples/Server/appsetting.json. Ange din slutpunktssträng i variabelnEndpointUrl
Lokal körning
Installera beroenden
npm run setupStarta samtalsappen
npm run startDå öppnas en klientserver på port 3000 som hanterar webbplatsfilerna och en API-server på port 8080 som utför funktioner som minting-token för samtalsdeltagare.
Felsökning
Appen visar en "webbläsare som inte stöds" men jag finns i en webbläsare som stöds.
Om din app hanteras över ett annat värdnamn än localhost måste du hantera trafik via https och inte http.
Publicera till Azure
npm run setupnpm run buildnpm run package- Använd Azure-tillägget och distribuera katalogen Calling/dist till din apptjänst
Rensa resurser
Om du vill rensa och ta bort en Communication Services-prenumeration kan du ta bort resursen eller resursgruppen. Om du tar bort resursgruppen tas även alla andra resurser som är associerade med den bort. Läs mer om att rensa resurser.
Nästa steg
Mer information finns i följande artiklar:
- Lär dig att använda Calling SDK:t
- Läs mer om hur samtal fungerar
Mer att läsa
- Exempel – Hitta fler exempel på vår översiktssida för exempel.
- Redux – Tillståndshantering på klientsidan
- FluentUI – Microsofts drivna användargränssnittsbibliotek
- React – Bibliotek för att skapa användargränssnitt
- ASP.NET Core – Ramverk för att skapa webbprogram
Azure Communication Services Group Calling Hero Sample för iOS visar hur Communication Services Calling iOS SDK kan användas för att skapa en gruppsamtalsupplevelse som innehåller röst och video. I den här exempelsnabbstarten får du lära dig hur du konfigurerar och kör exemplet. En översikt över exemplet tillhandahålls för kontexten.
Ladda ned kod
Hitta projektet för det här exemplet på GitHub.
Översikt
Exemplet är ett internt iOS-program som använder Azure Communication Services iOS SDK:er för att skapa en samtalsupplevelse som innehåller både röst- och videosamtal. Programmet använder en komponent på serversidan för att etablera åtkomsttoken som sedan används för att initiera Azure Communication Services SDK. Om du vill konfigurera den här komponenten på serversidan kan du följa självstudien Betrodd tjänst med Azure Functions.
Så här ser exemplet ut:
När du trycker på knappen "Starta nytt anrop" uppmanar iOS-programmet dig att ange ditt visningsnamn som ska användas för samtalet.
När du har tryckt på Nästa på skärmen "Starta samtal" har du möjlighet att dela grupp-ID:t för samtalet via iOS-resursbladet.
Med programmet kan du också ansluta till ett befintligt Azure Communication Services-anrop genom att ange det befintliga anropets ID- eller teams-ID-länk.
När du har anslutit till ett samtal uppmanas du att ge programmet behörighet att komma åt kameran och mikrofonen, om den inte redan är auktoriserad. Tänk på att precis som alla AVFoundation-baserade appar är sann ljud- och videofunktion endast tillgänglig på verklig maskinvara.
När du har ställt in ditt visningsnamn och anslutit till samtalet visas huvudvyn för samtalet, där de viktigaste samtalsfunktionerna finns.
Komponenter i huvudsamtalsskärmen:
- Mediegalleri: Huvudscenen där deltagarna visas. Om en deltagare har sin kamera aktiverad visas deras videoflöde här. Varje deltagare har en egen ruta som visar deras visningsnamn och videoström (om det finns någon). Galleriet stöder flera deltagare och uppdateras när deltagarna läggs till eller tas bort i anropet.
- Åtgärdsfält: Här finns de primära anropskontrollerna. Med de här kontrollerna kan du aktivera/inaktivera video och mikrofon, dela skärmen och lämna samtalet.
Nedan hittar du mer information om förutsättningar och steg för att konfigurera exemplet.
Förutsättningar
- Ett Azure-konto med en aktiv prenumeration. Mer information finns i Skapa ett konto kostnadsfritt.
- En Mac som kör Xcode, tillsammans med ett giltigt utvecklarcertifikat installerat i nyckelringen.
- En Azure Communication Services-resurs. Mer information finns i Skapa en Azure Communication Services-resurs.
- En Azure-funktion som kör autentiseringsslutpunkten för att hämta åtkomsttoken.
Köra exempel lokalt
Gruppsamtalsexemplet kan köras lokalt med XCode. Utvecklare kan antingen använda sin fysiska enhet eller en emulator för att testa programmet.
Innan du kör exemplet för första gången
- Installera beroenden genom att köra
pod install. - Öppna
AzureCalling.xcworkspacei XCode. - Skapa en textfil i roten med namnet
AppSettings.xcconfigoch ange värdet:communicationTokenFetchUrl = <your authentication endpoint, without the https:// component>
Kör exempel
Skapa och kör exemplet i XCode med hjälp av AzureCalling-målet på valfri simulator eller enhet.
(Valfritt) Skydda en autentiseringsslutpunkt
I demonstrationssyfte använder det här exemplet en offentligt tillgänglig slutpunkt som standard för att hämta en Azure Communication Services-åtkomsttoken. För produktionsscenarier rekommenderar vi att du använder din egen skyddade slutpunkt för att etablera egna token.
Med ytterligare konfiguration stöder det här exemplet anslutning till en Microsoft Entra-ID (Microsoft Entra ID) skyddad slutpunkt så att användarinloggning krävs för att appen ska kunna hämta en Åtkomsttoken för Azure Communication Services. Se stegen nedan:
- Aktivera Microsoft Entra-autentisering i din app.
- Gå till översiktssidan för din registrerade app under Microsoft Entra-appregistreringar. Observera
Application (client) ID,Directory (tenant) ID,Application ID URI
- Skapa en
AppSettings.xcconfigfil i roten om den inte redan finns och lägg till värdena:communicationTokenFetchUrl = <Application ID URI, without the https:// component> aadClientId = <Application (client) ID> aadTenantId = <Directory (tenant) ID>
Rensa resurser
Om du vill rensa och ta bort en Communication Services-prenumeration kan du ta bort resursen eller resursgruppen. Om du tar bort resursgruppen tas även alla andra resurser som är associerade med den bort. Läs mer om att rensa resurser.
Nästa steg
Mer information finns i följande artiklar:
- Lär dig att använda Calling SDK:t
- Läs mer om hur samtal fungerar
Mer att läsa
- Azure Communication GitHub – Hitta fler exempel och information på den officiella GitHub-sidan
- Exempel – Hitta fler exempel på vår översiktssida för exempel.
- Azure Communication Calling-funktioner – Läs mer om iOS SDK för samtal –Azure Communication iOS Calling SDK
Azure Communication Services Group Calling Hero-exemplet för Android visar hur Communication Services Calling Android SDK kan användas för att skapa en gruppsamtalsupplevelse som innehåller röst och video. I den här exempelsnabbstarten får du lära dig hur du konfigurerar och kör exemplet. En översikt över exemplet tillhandahålls för kontexten.
Ladda ned kod
Hitta projektet för det här exemplet på GitHub.
Översikt
Exemplet är ett internt Android-program som använder Azure Communication Services Android UI-klientbiblioteket för att skapa en samtalsupplevelse som innehåller både röst- och videosamtal. Programmet använder en komponent på serversidan för att etablera åtkomsttoken som sedan används för att initiera Azure Communication Services SDK. Om du vill konfigurera den här komponenten på serversidan kan du följa självstudien Betrodd tjänst med Azure Functions.
Så här ser exemplet ut:
När du trycker på knappen "Starta nytt anrop" uppmanar Android-programmet dig att ange ditt visningsnamn som ska användas för samtalet.
När du har tryckt på Nästa på sidan "Starta ett samtal" har du möjlighet att dela "Gruppsamtals-ID".
Med programmet kan du ansluta till ett befintligt Azure Communication Services-anrop genom att ange det befintliga samtalets ID eller teams mötes-ID-länk och visningsnamn.
När du har anslutit till ett samtal uppmanas du att ge programmet behörighet att komma åt kameran och mikrofonen, om den inte redan är auktoriserad. Du kommer att se den huvudsakliga samtalsytan där de centrala samtalsfunktionerna finns.
Komponenter i huvudsamtalsskärmen:
- Mediegalleri: Huvudscenen där deltagarna visas. Om en deltagare har sin kamera aktiverad visas deras videoflöde här. Varje deltagare har en egen ruta som visar deras visningsnamn och videoström (om det finns någon). Galleriet stöder flera deltagare och uppdateras när deltagarna läggs till eller tas bort i anropet.
- Åtgärdsfält: Här finns de primära anropskontrollerna. Med de här kontrollerna kan du aktivera/inaktivera video och mikrofon, dela skärmen och lämna samtalet.
Nedan hittar du mer information om förutsättningar och steg för att konfigurera exemplet.
Förutsättningar
- Ett Azure-konto med en aktiv prenumeration. Mer information finns i Skapa ett konto kostnadsfritt.
- Android Studio körs på datorn
- En Azure Communication Services-resurs. Mer information finns i Skapa en Azure Communication Services-resurs.
- En Azure-funktion som kör autentiseringsslutpunkten för att hämta åtkomsttoken.
Köra exempel lokalt
Gruppsamtalsexemplet kan köras lokalt med Android Studio. Utvecklare kan antingen använda sin fysiska enhet eller en emulator för att testa programmet.
Innan du kör exemplet för första gången
- Öppna Android Studio och välj
Open an Existing Project - Öppna mappen
AzureCallingi den nedladdade utgåvan för exemplet. - Expandera app/assets för att uppdatera
appSettings.properties. Ange värdet för nyckelncommunicationTokenFetchUrltill URL:en för den autentiseringsändpunkt som du har konfigurerat som en förutsättning.
Kör exempel
Skapa och kör exemplet i Android Studio.
(Valfritt) Skydda en autentiseringsslutpunkt
I demonstrationssyfte använder det här exemplet en offentligt tillgänglig slutpunkt som standard för att hämta en Azure Communication Services-token. För produktionsscenarier rekommenderar vi att du använder din egen skyddade slutpunkt för att etablera egna token.
Med ytterligare konfiguration stöder det här exemplet anslutning till en Microsoft Entra-ID (Microsoft Entra ID) skyddad slutpunkt så att användarinloggning krävs för att appen ska kunna hämta en Azure Communication Services-token. Se stegen nedan:
Aktivera Microsoft Entra-autentisering i din app.
Gå till översiktssidan för din registrerade app under Microsoft Entra-appregistreringar. Notera
Package name,Signature hash,MSAL Configuration.
Redigera
AzureCalling/app/src/main/res/raw/auth_config_single_account.jsonoch angeisAADAuthEnabledför att aktivera Microsoft Entra-ID.Redigera
AndroidManifest.xmloch ställ inandroid:pathpå signaturhashen för nyckellagret. (Valfritt. Det aktuella värdet använder hash från bundled debug.keystore. Om ett annat nyckelarkiv används måste detta uppdateras.)<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>Kopiera MSAL Android-konfigurationen från Azure Portal och klistra in till
AzureCalling/app/src/main/res/raw/auth_config_single_account.json. Ange "account_mode": "SINGLE"{ "client_id": "", "authorization_user_agent": "DEFAULT", "redirect_uri": "", "account_mode" : "SINGLE", "authorities": [ { "type": "AAD", "audience": { "type": "AzureADMyOrg", "tenant_id": "" } } ] }Redigera
AzureCalling/app/src/main/res/raw/auth_config_single_account.jsonoch ange värdet för nyckelncommunicationTokenFetchUrlsom URL för din säkra autentiseringsslutpunkt.Redigera
AzureCalling/app/src/main/res/raw/auth_config_single_account.jsonoch ange värdet för nyckelnaadScopesiAzure Active DirectoryExpose an API-omfattningarnaAnge värdet för
graphURLiAzureCalling/app/assets/appSettings.propertiessom Graph API-slutpunkt för att hämta användarinformation.Redigera
AzureCalling/app/src/main/assets/appSettings.propertiesoch ange värdet för nyckelntenantför att aktivera tyst inloggning så att användaren inte behöver autentiseras om och om igen när programmet startas om.
Rensa resurser
Om du vill rensa och ta bort en Communication Services-prenumeration kan du ta bort resursen eller resursgruppen. Om du tar bort resursgruppen tas även alla andra resurser som är associerade med den bort. Läs mer om att rensa resurser.
Nästa steg
Mer information finns i följande artiklar:
- Lär dig att använda Calling SDK:t
- Läs mer om hur samtal fungerar
Mer att läsa
- Azure Communication GitHub – Hitta fler exempel och information på den officiella GitHub-sidan
- Exempel – Hitta fler exempel på vår översiktssida för exempel.
- Azure Communication-samtalsfunktioner – Läs mer om Android Calling SDK –Azure Communication Android Calling SDK
Azure Communication Services Group Calling Hero Sample för Windows visar hur Communication Services Calling Windows SDK kan användas för att skapa en gruppsamtalsupplevelse som innehåller röst och video. I det här exemplet får du lära dig hur du konfigurerar och kör exemplet. En översikt över exemplet tillhandahålls för kontexten.
I den här snabbstarten får du lära dig hur du startar ett 1:1-videosamtal med hjälp av Azure Communication Services Calling SDK för Windows.
UWP-exempelkod
Förutsättningar
För att slutföra den här självstudien, finns följande förhandskrav:
Ett Azure-konto med en aktiv prenumeration. Skapa ett konto utan kostnad.
Installera Visual Studio 2022 med arbetsbelastningen Universell Windows-plattformsutveckling.
En driftsatt Communication Services-resurs. Skapa en resurs för kommunikationstjänster. Du måste anteckna din anslutningssträng för den här snabbstarten.
En användaråtkomsttoken för azure-kommunikationstjänsten. Du kan också använda Azure CLI och köra kommandot med din anslutningssträng för att skapa en användare och en åtkomsttoken.
az communication identity token issue --scope voip --connection-string "yourConnectionString"Mer information finns i Använda Azure CLI för att skapa och hantera åtkomsttoken.
Konfiguration
Skapa projektet
I Visual Studio skapar du ett nytt projekt med mallen Tom app (Universell Windows) för att konfigurera en enkelsidig Universell Windows-plattform-app (UWP).
Installera paketet
Högerklicka på ditt projekt och gå till Manage Nuget Packages för att installera Azure.Communication.Calling.WindowsClient1.2.0-beta.1 eller senare. Kontrollera att Inkludera förhandsversioner är markerat.
Begär åtkomst
Gå till Package.appxmanifest och klicka på Capabilities.
Kontrollera Internet (Client & Server) om du vill få inkommande och utgående åtkomst till Internet.
Kontrollera Microphone om du vill komma åt mikrofonens ljudflöde.
Kontrollera WebCam om du vill komma åt enhetens kamera.
Lägg till följande kod i din Package.appxmanifest genom att högerklicka och välja Visa kod.
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>RtmMvrUap.dll</Path>
<ActivatableClass ActivatableClassId="VideoN.VideoSchemeHandler" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions>
Konfigurera appramverket
Vi måste konfigurera en grundläggande layout för att koppla vår logik. För att kunna ringa ett utgående samtal behöver vi ett TextBox för att ange användar-ID:t för den anropade. Vi behöver också en Start Call knapp och en Hang Up knapp.
Vi måste också förhandsgranska den lokala videon och återge fjärrvideon för den andra deltagaren. Därför behöver vi två element för att visa videoströmmarna.
MainPage.xaml Öppna projektet och ersätt innehållet med följande implementering.
<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>
Öppna App.xaml.cs (högerklicka och välj Visa kod) och lägg till den här raden längst upp:
using CallingQuickstart;
MainPage.xaml.cs Öppna (högerklicka och välj Visa kod) och ersätt innehållet med följande implementering:
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
Följande klasser och gränssnitt hanterar några av de viktigaste funktionerna i Azure Communication Services Calling SDK:
| Name | beskrivning |
|---|---|
CallClient |
CallClient är den huvudsakliga startpunkten för anropsklientbiblioteket. |
CallAgent |
CallAgent Används för att starta och ansluta anrop. |
CommunicationCall |
CommunicationCall Används för att hantera placerade eller anslutna anrop. |
CallTokenCredential |
CallTokenCredential Används som tokenautentiseringsuppgifter för att instansiera CallAgent. |
CommunicationUserIdentifier |
CommunicationUserIdentifier Används för att representera användarens identitet, vilket kan vara något av följande alternativ: CommunicationUserIdentifier, PhoneNumberIdentifier eller CallingApplication. |
Autentisera klienten
För att initiera en CallAgentbehöver du en användaråtkomsttoken. Vanligtvis genereras denna token från en tjänst med autentisering som är specifik för programmet. Mer information om token för användaråtkomst finns i guiden Användaråtkomsttoken .
För snabbstarten ersätter du <AUTHENTICATION_TOKEN> med en användaråtkomsttoken som genererats för din Azure Communication Service-resurs.
När du har en token initierar du en CallAgent instans med den, vilket gör att vi kan ringa och ta emot samtal. För att komma åt kamerorna på enheten måste vi också få Enhetshanteraren instans.
Lägg till följande kod i InitCallAgentAndDeviceManagerAsync funktionen.
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
}
}
Starta ett samtal med video
Lägg till implementeringen i CallButton_Click för att starta ett anrop med video. Vi måste räkna upp kamerorna med enhetshanterarens instans och skapa LocalOutgoingVideoStream. Vi måste ange VideoOptions med LocalVideoStream och skicka det med startCallOptions för att ange inledande alternativ för anropet. Genom att ansluta LocalOutgoingVideoStream till en MediaElementkan vi se förhandsversionen av den lokala videon.
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;
}
Lägg till metoderna för att starta eller ansluta till de olika typerna av samtal (1:1 Azure Communication Services-samtal, 1:1-telefonsamtal, Gruppsamtal för Azure Communication Services, Teams-mötesanslutning osv.).
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 } }
};
}
Lägg till koden för att skapa LocalVideoStream beroende på den valda kameran på CameraList_SelectionChanged metoden.
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);
}
Acceptera ett inkommande samtal
Lägg till implementeringen i OnIncomingCallAsync för att besvara ett inkommande samtal med video, skicka LocalVideoStream till acceptCallOptions.
var incomingCall = args.IncomingCall;
var acceptCallOptions = new AcceptCallOptions() {
IncomingVideoOptions = new IncomingVideoOptions()
{
IncomingVideoStreamKind = VideoStreamKind.RemoteIncoming
}
};
_ = await incomingCall.AcceptAsync(acceptCallOptions);
Fjärrdeltagare och fjärrvideoströmmar
Alla deltagare på distans är tillgängliga via samlingen RemoteParticipants i en samtalsinstans. När samtalet ansluts (CallState.Connected) kan vi komma åt fjärrdeltagarna i samtalet och hantera fjärrvideoströmmarna.
Kommentar
När en användare ansluter till ett samtal kan de komma åt de aktuella fjärrdeltagarna via RemoteParticipants samlingen. Händelsen RemoteParticipantsUpdated utlöses inte för dessa befintliga deltagare. Den här händelsen utlöses endast när en fjärrdeltagare ansluter eller lämnar samtalet medan användaren redan är i samtalet.
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;
}
}
Rendera fjärrvideor
För varje fjärrvideoström kopplar du den till 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();
});
}
}
Uppdatering av samtalstillstånd
Vi måste rensa videorenderarna när samtalet har kopplats från och hantera fallet när fjärrdeltagarna först ansluter till samtalet.
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;
}
}
Avsluta samtal
Avsluta det aktuella samtalet när Hang Up knappen klickas. Lägg till implementeringen i HangupButton_Click för att avsluta ett anrop med den callAgent som vi skapade och ta ned händelsehanterare för deltagaruppdatering och samtalstillstånd.
var call = this.callAgent?.Calls?.FirstOrDefault();
if (call != null)
{
try
{
await call.HangUpAsync(new HangUpOptions() { ForEveryone = true });
}
catch(Exception ex)
{
}
}
Kör koden
Du kan skapa och köra koden i Visual Studio. För lösningsplattformar stöder vi ARM64, x64 och x86.
Du kan göra ett utgående videosamtal genom att ange ett användar-ID i textfältet och klicka på Start Call knappen.
Obs! Att ringa 8:echo123 stoppar videoströmmen eftersom ekoboten inte stöder videoströmning.
Mer information om användar-ID:t (identitet) finns i guiden Användaråtkomsttoken .
WinUI 3-exempelkod
Förutsättningar
För att slutföra den här självstudien, finns följande förhandskrav:
Ett Azure-konto med en aktiv prenumeration. Skapa ett konto utan kostnad.
Installera Visual Studio 2022 och SDK för Windows-appar version 1.2 preview 2.
Grundläggande förståelse för hur du skapar en WinUI 3-app. Skapa ditt första WinUI 3-projekt (SDK för Windows-appar) är en bra resurs att börja med.
En driftsatt Communication Services-resurs. Skapa en resurs för kommunikationstjänster. Du måste anteckna din anslutningssträng för den här snabbstarten.
En användaråtkomsttoken för azure-kommunikationstjänsten. Du kan också använda Azure CLI och köra kommandot med din anslutningssträng för att skapa en användare och en åtkomsttoken.
az communication identity token issue --scope voip --connection-string "yourConnectionString"Mer information finns i Använda Azure CLI för att skapa och hantera åtkomsttoken.
Konfiguration
Skapa projektet
I Visual Studio skapar du ett nytt projekt med mallen Tom app, Paketerad (WinUI 3 i Desktop) för att konfigurera en winui 3-app med en enda sida.
Installera paketet
Högerklicka på ditt projekt och gå till Manage Nuget Packages för att installera Azure.Communication.Calling.WindowsClient1.0.0 eller senare. Kontrollera att Inkludera förhandsversioner är markerat.
Begär åtkomst
Lägg till följande kod i din app.manifest:
<file name="RtmMvrMf.dll">
<activatableClass name="VideoN.VideoSchemeHandler" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
Konfigurera appramverket
Vi måste konfigurera en grundläggande layout för att koppla vår logik. För att kunna ringa ett utgående samtal behöver vi ett TextBox för att ange användar-ID:t för den anropade. Vi behöver också en Start Call knapp och en Hang Up knapp.
Vi måste också förhandsgranska den lokala videon och återge fjärrvideon för den andra deltagaren. Därför behöver vi två element för att visa videoströmmarna.
MainWindow.xaml Öppna projektet och ersätt innehållet med följande implementering.
<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>
Öppna App.xaml.cs (högerklicka och välj Visa kod) och lägg till den här raden längst upp:
using CallingQuickstart;
MainWindow.xaml.cs Öppna (högerklicka och välj Visa kod) och ersätt innehållet med följande implementering:
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
Följande klasser och gränssnitt hanterar några av de viktigaste funktionerna i Azure Communication Services Calling SDK:
| Name | beskrivning |
|---|---|
CallClient |
CallClient är den huvudsakliga startpunkten för anropsklientbiblioteket. |
CallAgent |
CallAgent Används för att starta och ansluta anrop. |
CommunicationCall |
CommunicationCall Används för att hantera placerade eller anslutna anrop. |
CallTokenCredential |
CallTokenCredential Används som tokenautentiseringsuppgifter för att instansiera CallAgent. |
CommunicationUserIdentifier |
CommunicationUserIdentifier Används för att representera användarens identitet, vilket kan vara något av följande alternativ: CommunicationUserIdentifier, PhoneNumberIdentifier eller CallingApplication. |
Autentisera klienten
För att initiera en CallAgentbehöver du en användaråtkomsttoken. Vanligtvis genereras denna token från en tjänst med autentisering som är specifik för programmet. Mer information om token för användaråtkomst finns i guiden Användaråtkomsttoken .
För snabbstarten ersätter du <AUTHENTICATION_TOKEN> med en användaråtkomsttoken som genererats för din Azure Communication Service-resurs.
När du har en token initierar du en CallAgent instans med den, vilket gör att vi kan göra och ta emot anrop. För att komma åt kamerorna på enheten måste vi också få Enhetshanteraren instans.
Lägg till följande kod i InitCallAgentAndDeviceManagerAsync funktionen.
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;
Starta ett samtal med video
Lägg till implementeringen i CallButton_Click för att starta ett anrop med video. Vi måste räkna upp kamerorna med enhetshanterarens instans och skapa LocalVideoStream. Vi måste ange VideoOptions med LocalVideoStream och skicka det med startCallOptions för att ange inledande alternativ för anropet. Genom att ansluta LocalVideoStream till en MediaPlayerElementkan vi se förhandsversionen av den lokala videon.
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;
Acceptera ett inkommande samtal
Lägg till implementeringen i Agent_OnIncomingCallAsync för att besvara ett inkommande samtal med video, skicka LocalVideoStream till 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);
Fjärrdeltagare och fjärrvideoströmmar
Alla deltagare på distans är tillgängliga via samlingen RemoteParticipants i en samtalsinstans. När samtalet är anslutet kan vi komma åt fjärrdeltagarna i samtalet och hantera fjärrvideoströmmarna.
Kommentar
När en användare ansluter till ett samtal kan de komma åt de aktuella fjärrdeltagarna via RemoteParticipants samlingen. Händelsen OnRemoteParticipantsUpdated utlöses inte för dessa befintliga deltagare. Den här händelsen utlöses endast när en fjärrdeltagare ansluter eller lämnar samtalet medan användaren redan är i samtalet.
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);
}
}
Rendera fjärrvideor
För varje fjärrvideoström kopplar du den till 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();
});
}
}
Uppdatering av samtalstillstånd
Vi måste rensa videorenderarna när samtalet har kopplats från och hantera fallet när fjärrdeltagarna först ansluter till samtalet.
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;
}
}
Avsluta samtal
Avsluta det aktuella samtalet när Hang Up knappen klickas. Lägg till implementeringen i HangupButton_Click för att avsluta ett anrop med den callAgent som vi skapade och ta ned händelsehanterare för deltagaruppdatering och samtalstillstånd.
this.call.OnRemoteParticipantsUpdated -= Call_OnRemoteParticipantsUpdatedAsync;
this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions());
Kör koden
Du kan skapa och köra koden i Visual Studio. För lösningsplattformar stöder vi ARM64, x64 och x86.
Du kan göra ett utgående videosamtal genom att ange ett användar-ID i textfältet och klicka på Start Call knappen.
Obs! Att ringa 8:echo123 stoppar videoströmmen eftersom ekoboten inte stöder videoströmning.
Mer information om användar-ID:t (identitet) finns i guiden Användaråtkomsttoken .