Kom igång med det anropande hero-exemplet
Azure Communication Services Group Calling Hero-exemplet visar hur Web SDK för kommunikationstjänster som anropar webb kan användas för att skapa en gruppsamtalsupplevelse.
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 huvudsamtalsarbetsytan där kärnsamtalsupplevelsen 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 enskild panel som visar deras visningsnamn och videoström (när det finns en)
- Rubrik: Det är här de primära anropskontrollerna finns för att växla inställningar och deltagarpanelen, aktivera/inaktivera video och blanda, dela skärmen och lämna samtalet.
- Sidofält: Här visas information om deltagare och inställningar när de växlas med hjälp av kontrollerna i rubriken. Komponenten kan stängas med hjälp av 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.git
Connection String
Hämta från Azure Portal eller med hjälp av 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äng i filen samples/Server/appsetting.json. Ange din anslutningssträng i variabeln:ResourceConnectionString
.Endpoint string
Hämta från Azure Portal eller med hjälp av Azure CLI.az communication list-key --name "<acsResourceName>" --resource-group "<resourceGroup>"
Mer information om slutpunktssträngar finns i Skapa en Azure-kommunikationsresurser
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 setup
Starta den anropande appen
npm run start
Då ö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 setup
npm run build
npm 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:
- Bekanta dig med att använda anropande SDK
- Läs mer om hur samtal fungerar
Mer att läsa
- Exempel – Hitta fler exempel och exempel på översiktssidan för våra 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 konfigurerat visningsnamnet och ansluter till samtalet ser du huvudsamtalsarbetsytan där kärnsamtalsupplevelsen 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 enskild panel som visar deras visningsnamn och videoström (när det finns en). 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.xcworkspace
i XCode. - Skapa en textfil i roten med namnet
AppSettings.xcconfig
och 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. Anteckna
Application (client) ID
, ,Directory (tenant) ID
Application ID URI
- Skapa en
AppSettings.xcconfig
fil 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:
- Bekanta dig med att använda anropande SDK
- 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 och exempel på översiktssidan för våra exempel.
- Funktioner för Samtal i Azure-kommunikation – Om du vill veta mer om den anropande iOS-sdk:n –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 ser huvudsamtalsarbetsytan där kärnsamtalsupplevelsen 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 enskild panel som visar deras visningsnamn och videoström (när det finns en). 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 i den
AzureCalling
nedladdade versionen för exemplet. - Expandera app/tillgångar för att uppdatera
appSettings.properties
. Ange värdet för nyckelncommunicationTokenFetchUrl
som URL för din autentiseringsslutpunkt som konfigurerats 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. Anteckna
Package name
,Signature hash
,MSAL Configutaion
.
Redigera
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
och angeisAADAuthEnabled
för att aktivera Microsoft Entra-ID.Redigera
AndroidManifest.xml
och angeandroid:path
till nyckellagringssignaturshash. (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
. Inkludera "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.json
och ange värdet för nyckelncommunicationTokenFetchUrl
som URL för din säkra autentiseringsslutpunkt.Redigera
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
och ange värdet för nyckelnaadScopes
frånAzure Active Directory
Expose an API
omfångAnge värdet för
graphURL
iAzureCalling/app/assets/appSettings.properties
som Graph API-slutpunkt för att hämta användarinformation.Redigera
AzureCalling/app/src/main/assets/appSettings.properties
och ange värdet för nyckelntenant
fö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:
- Bekanta dig med att använda anropande SDK
- 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 och exempel på översiktssidan för våra exempel.
- Funktioner för Samtal i Azure-kommunikation – Om du vill veta mer om att anropa Android 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 Universell Windows-plattform utvecklingsarbetsbelastning.
En distribuerad Communication Services-resurs. Skapa en Communication Services-resurs. Du måste registrera 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.
Konfigurera
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å projektet och gå till för att Manage Nuget Packages
installera Azure.Communication.Calling.WindowsClient
1.2.0-beta.1 eller överlägsen version. Kontrollera att Inkludera förhyrd ä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 huvudinmatningspunkten till klientbiblioteket För samtal. |
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 CallAgent
behö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 MediaElement
kan 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 GetStartCallOptionsAsynnc();
var call = await this.callAgent.StartCallAsync( new [] { new UserCallIdentifier(acsCallee) }, options);
return call;
}
private async Task<CommunicationCall> StartPhoneCallAsync(string acsCallee, string alternateCallerId)
{
var options = await GetStartCallOptionsAsynnc();
options.AlternateCallerId = new PhoneNumberCallIdentifier(alternateCallerId);
var call = await this.callAgent.StartCallAsync( new [] { new PhoneNumberCallIdentifier(acsCallee) }, options);
return call;
}
private async Task<CommunicationCall> JoinGroupCallByIdAsync(Guid groupId)
{
var joinCallOptions = await GetJoinCallOptionsAsync();
var groupCallLocator = new GroupCallLocator(groupId);
var call = await this.callAgent.JoinAsync(groupCallLocator, joinCallOptions);
return call;
}
private async Task<CommunicationCall> JoinTeamsMeetingByLinkAsync(Uri teamsCallLink)
{
var joinCallOptions = await GetJoinCallOptionsAsync();
var teamsMeetingLinkLocator = new TeamsMeetingLinkLocator(teamsCallLink.AbsoluteUri);
var call = await callAgent.JoinAsync(teamsMeetingLinkLocator, joinCallOptions);
return call;
}
private async Task<StartCallOptions> GetStartCallOptionsAsynnc()
{
return new StartCallOptions() {
OutgoingAudioOptions = new OutgoingAudioOptions() { IsOutgoingAudioMuted = true, OutgoingAudioStream = micStream },
OutgoingVideoOptions = new OutgoingVideoOptions() { OutgoingVideoStreams = new OutgoingVideoStream[] { cameraStream } }
};
}
private async Task<JoinCallOptions> GetJoinCallOptionsAsync()
{
return new JoinCallOptions() {
OutgoingAudioOptions = new OutgoingAudioOptions() { IsOutgoingAudioMuted = true },
OutgoingVideoOptions = new OutgoingVideoOptions() { OutgoingVideoStreams = new OutgoingVideoStream[] { cameraStream } }
};
}
Lägg till koden för att skapa LocalVideoStream beroende på den valda kameran på CameraList_SelectionChanged
metoden.
var selectedCamerea = CameraList.SelectedItem as VideoDeviceDetails;
cameraStream = new LocalOutgoingVideoStream(selectedCamerea);
var localUri = await cameraStream.StartPreviewAsync();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
LocalVideo.Source = MediaSource.CreateFromUri(localUri);
});
if (call != null)
{
await call?.StartVideoAsync(cameraStream);
}
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 fjärrdeltagare är tillgängliga via RemoteParticipants
samlingen på 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 videoåtergivningarna när anropet är frånkopplat och hantera ärendet när fjärrdeltagarna först ansluter 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 ARM64
vi , 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! Samtal 8:echo123
stoppar videoströmmen eftersom ekoroboten 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 distribuerad Communication Services-resurs. Skapa en Communication Services-resurs. Du måste registrera 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.
Konfigurera
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å projektet och gå till för att Manage Nuget Packages
installera Azure.Communication.Calling.WindowsClient
1.0.0 eller överlägsen version. Kontrollera att Inkludera förhyrd är markerat.
Begär åtkomst
Lägg till följande kod i :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 huvudinmatningspunkten till klientbiblioteket För samtal. |
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 CallAgent
behö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 MediaPlayerElement
kan 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 selectedCamerea = CameraList.SelectedItem as VideoDeviceDetails;
cameraStream = new LocalOutgoingVideoStream(selectedCamerea);
var localUri = await cameraStream.StartPreviewAsync();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
LocalVideo.Source = MediaSource.CreateFromUri(localUri);
});
startCallOptions.VideoOptions = new OutgoingVideoOptions(new[] { cameraStream });
}
}
var callees = new ICommunicationIdentifier[1]
{
new CommunicationUserIdentifier(CalleeTextBox.Text.Trim())
};
this.call = await this.callAgent.StartCallAsync(callees, startCallOptions);
this.call.OnRemoteParticipantsUpdated += Call_OnRemoteParticipantsUpdatedAsync;
this.call.OnStateChanged += Call_OnStateChangedAsync;
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 selectedCamerea = CameraList.SelectedItem as VideoDeviceDetails;
cameraStream = new LocalOutgoingVideoStream(selectedCamerea);
var localUri = await cameraStream.StartPreviewAsync();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
LocalVideo.Source = MediaSource.CreateFromUri(localUri);
});
acceptCallOptions.VideoOptions = new OutgoingVideoOptions(new[] { localVideoStream });
}
}
call = await incomingCall.AcceptAsync(acceptCallOptions);
Fjärrdeltagare och fjärrvideoströmmar
Alla fjärrdeltagare är tillgängliga via RemoteParticipants
samlingen på 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 videoåtergivningarna när anropet är frånkopplat och hantera ärendet när fjärrdeltagarna först ansluter 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 ARM64
vi , 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! Samtal 8:echo123
stoppar videoströmmen eftersom ekoroboten inte stöder videoströmning.
Mer information om användar-ID:t (identitet) finns i guiden Användaråtkomsttoken .