Mulai menggunakan sampel hero panggilan
Sampel Group Calling Hero Azure Communication Services menunjukkan cara Communication Services Calling Web SDK dapat digunakan untuk membangun pengalaman panggilan grup.
Dalam Mulai cepat Sampel ini, kita mempelajari cara kerja sampel sebelum kita menjalankan sampel di komputer lokal Anda lalu menyebarkan sampel ke Azure menggunakan sumber daya Azure Communication Services Anda sendiri.
Mengunduh kode
Temukan proyek untuk sampel ini di GitHub. Versi sampel yang menyertakan fitur yang saat ini ada di pratinjau publik seperti Interop Teams dan Rekaman Panggilan dapat ditemukan di cabang terpisah.
Gambaran Umum
Sampel ini memiliki aplikasi sisi klien dan aplikasi sisi server. Aplikasi sisi klien adalah aplikasi web React/Redux yang menggunakan kerangka kerja antarmuka pengguna Fluent Microsoft. Aplikasi ini mengirimkan permintaan ke aplikasi sisi server ASP.NET Core yang membantu aplikasi sisi klien terhubung ke Azure.
Berikut tampilan sampelnya:
Ketika Anda menekan tombol "Mulai panggilan", aplikasi web mengambil token akses pengguna dari aplikasi sisi server. Token ini kemudian digunakan untuk menghubungkan aplikasi klien ke Azure Communication Services. Setelah token diambil, Anda diminta untuk menentukan kamera dan mikrofon yang ingin Anda gunakan. Anda dapat menonaktifkan/mengaktifkan perangkat Anda dengan kontrol pengalih:
Setelah Anda mengonfigurasi nama tampilan dan perangkat, Anda dapat bergabung dengan sesi. Anda akan melihat kanvas panggilan utama tempat pengalaman panggilan inti berada.
Komponen layar panggilan utama:
- Galeri Media: Tempat utama untuk menampilkan peserta. Jika peserta mengaktifkan kameranya, umpan video mereka akan ditampilkan di sini. Setiap peserta memiliki petak individu yang menunjukkan nama tampilan dan aliran video mereka (bila ada)
- Header: Di sinilah kontrol panggilan utama berada untuk beralih pengaturan dan bilah sisi peserta, menyalakan dan mencampur video, berbagi layar, dan meninggalkan panggilan.
- Bilah Samping: Di sinilah peserta dan informasi pengaturan ditampilkan saat beralih menggunakan kontrol di header. Komponen dapat dimatikan menggunakan 'X' yang ada di sudut kanan atas. Bilah sisi peserta memperlihatkan daftar peserta dan tautan untuk mengundang lebih banyak pengguna untuk mengobrol. Bilah sisi pengaturan memungkinkan Anda mengonfigurasi pengaturan mikrofon dan kamera.
Di bawah ini Anda dapat menemukan informasi selengkapnya tentang prasyarat dan langkah-langkah untuk menyiapkan sampel.
Prasyarat
- Akun Azure dengan langganan aktif. Untuk mengetahui detailnya, lihat Membuat akun secara gratis
- Node.js (12.18.4 dan lebih baru)
- Visual Studio Code (Build Stabil)
- Sumber daya Azure Communication Services. Untuk detailnya, lihat Membuat sumber daya Azure Communication Services. Anda perlu merekam string koneksi sumber daya Anda untuk mulai cepat ini.
Sebelum menjalankan sampel untuk pertama kalinya
Buka instans PowerShell, Terminal Windows, Perintah atau yang setara, dan buka direktori yang ingin Anda kloning sampelnya.
git clone https://github.com/Azure-Samples/communication-services-web-calling-hero.git
Connection String
Dapatkan dari portal Azure atau dengan menggunakan Azure CLI.az communication list-key --name "<acsResourceName>" --resource-group "<resourceGroup>"
Untuk informasi selengkapnya tentang string koneksi, lihat Membuat Sumber Daya Komunikasi Azure
Setelah Anda mendapatkan
Connection String
, tambahkan string koneksi ke file sampel/Server/appsetting.json. Masukkan string koneksi Anda dalam variabel:ResourceConnectionString
.Endpoint string
Dapatkan dari portal Azure atau dengan menggunakan Azure CLI.az communication list-key --name "<acsResourceName>" --resource-group "<resourceGroup>"
Untuk informasi selengkapnya tentang string Titik Akhir, lihat Membuat Sumber Daya Komunikasi Azure
Setelah Anda mendapatkan
Endpoint String
, tambahkan string titik akhir ke file sampel/Server/appsetting.json . Masukkan string titik akhir Anda dalam variabelEndpointUrl
Eksekusi lokal
Instal dependensi
npm run setup
Memulai aplikasi panggilan
npm run start
Ini membuka server klien pada port 3000 yang melayani file situs web, dan server api pada port 8080 yang melakukan fungsionalitas seperti menambang token untuk peserta panggilan.
Pemecahan Masalah
Aplikasi ini menunjukkan layar "Browser yang tidak didukung" tetapi saya berada di browser yang didukung.
Jika aplikasi Anda dilayani melalui nama host selain localhost, Anda harus melayani lalu lintas melalui https dan bukan http.
Menerbitkan ke Azure
npm run setup
npm run build
npm run package
- Menggunakan ekstensi Azure dan menyebarkan direktori Panggilan/dist ke layanan aplikasi Anda
Membersihkan sumber daya
Jika ingin membersihkan dan menghapus langganan Azure Communication Services, Anda bisa menghapus sumber daya atau grup sumber daya. Menghapus grup sumber daya juga menghapus sumber daya apa pun yang terkait dengannya. Pelajari selengkapnya tentang membersihkan sumber daya.
Langkah berikutnya
Untuk informasi lebih lanjut, baca artikel berikut:
- Pelajari cara menggunakan SDK Panggilan
- Pelajari lebih lanjut cara kerja panggilan
Pembacaan tambahan
- Sampel - Temukan lebih banyak sampel dan contoh di halaman gambaran umum sampel kami.
- Redux - Manajemen status sisi klien
- FluentUI - Pustaka UI yang didukung Microsoft
- React - Pustaka untuk membangun antarmuka pengguna
- ASP.NET Core - Kerangka kerja untuk membangun aplikasi web
Azure Communication Services Contoh Group Calling Hero untuk iOS menunjukkan bagaimana Communication Services Calling untuk SDK iOS dapat digunakan untuk membangun pengalaman panggilan grup yang mencakup suara dan video. Dalam sampel panduan mulai cepat ini, Anda akan mempelajari cara menyiapkan dan menjalankan sampel. Ringkasan sampel disediakan untuk konteks.
Mengunduh kode
Temukan proyek untuk sampel ini di GitHub.
Gambaran Umum
Sampelnya adalah aplikasi iOS asli yang menggunakan Azure Communication Services untuk SDK iOS untuk membangun pengalaman panggilan yang menampilkan panggilan suara dan video. Aplikasi menggunakan komponen sisi server untuk melakukan provisi token akses yang kemudian digunakan untuk menginisialisasi Azure Communication Services SDK. Untuk mengonfigurasi komponen sisi server ini, silakan ikuti tutorial Layanan Tepercaya dengan Azure Functions.
Berikut tampilan sampelnya:
Saat Anda menekan tombol "Mulai panggilan baru", aplikasi iOS meminta Anda untuk memasukkan nama tampilan yang akan digunakan untuk panggilan.
Setelah mengetuk "Berikutnya" di layar "Mulai Panggilan", Anda memiliki kesempatan untuk membagikan ID grup panggilan melalui lembar berbagi iOS.
Aplikasi ini juga memungkinkan Anda untuk bergabung dengan panggilan Azure Communication Services yang ada dengan menentukan tautan ID panggilan atau ID tim yang ada.
Setelah bergabung dengan panggilan, Anda akan diminta untuk memberikan izin aplikasi untuk mengakses kamera dan mikrofon Anda, jika belum diotorisasi. Perlu diingat bahwa, seperti semua aplikasi berbasis AVFoundation, fungsionalitas audio dan video sejati hanya tersedia di perangkat keras nyata.
Setelah mengonfigurasi nama tampilan dan bergabung dalam panggilan, Anda akan melihat kanvas panggilan utama tempat pengalaman panggilan inti berada.
Komponen layar panggilan utama:
- Galeri Media: Tempat utama untuk menampilkan peserta. Jika peserta mengaktifkan kameranya, umpan video mereka akan ditampilkan di sini. Setiap peserta memiliki petak individu yang menunjukkan nama tampilan dan aliran video mereka (bila ada). Galeri mendukung banyak peserta dan diperbarui saat peserta ditambahkan atau dihapus ke panggilan.
- Bilah Tindakan: Di sinilah kontrol panggilan utama berada. Kontrol ini memungkinkan Anda mengaktifkan/menonaktifkan video dan mikrofon, membagikan layar, dan meninggalkan panggilan.
Di bawah ini Anda akan menemukan informasi lebih lanjut tentang prasyarat dan langkah-langkah untuk menyiapkan sampel.
Prasyarat
- Akun Azure dengan langganan aktif. Untuk detailnya, lihat Membuat akun gratis.
- Mac yang menjalankan Xcode, bersama dengan sertifikat pengembang valid yang diinstal ke rantai kunci Anda.
- Sumber daya Azure Communication Services. Untuk detailnya, lihat Membuat sumber daya Azure Communication Services.
- Azure Function yang menjalankan Titik Akhir Autentikasi untuk mengambil token akses.
Menjalankan sampel secara lokal
Sampel panggilan grup dapat dijalankan secara lokal menggunakan XCode. Pengembang dapat menggunakan perangkat fisik mereka atau emulator untuk menguji aplikasi.
Sebelum menjalankan sampel untuk pertama kalinya
- Pasang dependensi dengan menjalankan
pod install
. - Buka
AzureCalling.xcworkspace
di XCode. - Buat file teks di akar, dipanggil
AppSettings.xcconfig
dan atur nilainya:communicationTokenFetchUrl = <your authentication endpoint, without the https:// component>
Menjalankan sampel
Buat dan jalankan sampel di XCode, menggunakan target AzureCalling pada simulator atau perangkat pilihan Anda.
(Opsional) Mengamankan titik akhir autentikasi
Untuk tujuan demonstrasi, sampel ini menggunakan titik akhir yang dapat diakses publik secara default untuk mengambil token akses Azure Communication Services. Untuk skenario produksi, sebaiknya gunakan titik akhir aman Anda sendiri untuk melakukan provisi token Anda sendiri.
Dengan konfigurasi tambahan, sampel ini mendukung koneksi ke titik akhir yang dilindungi ID Microsoft Entra (ID Microsoft Entra) sehingga login pengguna diperlukan agar aplikasi mengambil token akses Azure Communication Services. Lihat langkah di bawah ini:
- Aktifkan autentikasi Microsoft Entra di aplikasi Anda.
- Buka halaman gambaran umum aplikasi terdaftar Anda di bawah Pendaftaran Aplikasi Microsoft Entra. Catat
Application (client) ID
,Directory (tenant) ID
,Application ID URI
- Buat
AppSettings.xcconfig
file di akar jika belum ada dan tambahkan nilai:communicationTokenFetchUrl = <Application ID URI, without the https:// component> aadClientId = <Application (client) ID> aadTenantId = <Directory (tenant) ID>
Membersihkan sumber daya
Jika ingin membersihkan dan menghapus langganan Azure Communication Services, Anda bisa menghapus sumber daya atau grup sumber daya. Menghapus grup sumber daya juga menghapus sumber daya apa pun yang terkait dengannya. Pelajari selengkapnya tentang membersihkan sumber daya.
Langkah berikutnya
Untuk informasi lebih lanjut, baca artikel berikut:
- Pelajari cara menggunakan SDK Panggilan
- Pelajari lebih lanjut cara kerja panggilan
Pembacaan tambahan
- Azure Communication GitHub - Temukan lebih banyak contoh dan informasi di halaman resmi GitHub
- Sampel - Temukan lebih banyak sampel dan contoh di halaman gambaran umum sampel kami.
- Fitur Panggilan Komunikasi Azure - Untuk mempelajari lebih lanjut panggilan iOS SDK -Azure Communication iOS Calling SDK
Sampel Group Calling Hero untuk Android Azure Communication Services menunjukkan bagaimana Communication Services Calling Android SDK dapat digunakan untuk membangun pengalaman panggilan grup yang mencakup suara dan video. Dalam sampel panduan mulai cepat ini, Anda akan mempelajari cara menyiapkan dan menjalankan sampel. Ringkasan sampel disediakan untuk konteks.
Mengunduh kode
Temukan proyek untuk sampel ini di GitHub.
Gambaran Umum
Sampelnya adalah aplikasi Android asli yang menggunakan pustaka klien UI Android Azure Communication Services untuk membangun pengalaman panggilan yang menampilkan panggilan suara dan video. Aplikasi menggunakan komponen sisi server untuk melakukan provisi token akses yang kemudian digunakan untuk menginisialisasi Azure Communication Services SDK. Untuk mengonfigurasi komponen sisi server ini, silakan ikuti tutorial Layanan Tepercaya dengan Azure Functions.
Berikut tampilan sampelnya:
Saat Anda menekan tombol "Mulai panggilan baru", aplikasi Android meminta Anda untuk memasukkan nama tampilan yang akan digunakan untuk panggilan.
Setelah mengetuk "Berikutnya" di halaman "Mulai Panggilan", Anda memiliki kesempatan untuk berbagi "ID Panggilan Grup".
Aplikasi ini memungkinkan Anda untuk bergabung dengan panggilan Azure Communication Services yang ada dengan menentukan tautan ID panggilan atau ID rapat teams yang ada dan nama tampilan.
Setelah bergabung dengan panggilan, Anda akan diminta untuk memberikan izin aplikasi untuk mengakses kamera dan mikrofon Anda, jika belum diotorisasi. Anda akan melihat kanvas panggilan utama tempat pengalaman panggilan inti berada.
Komponen layar panggilan utama:
- Galeri Media: Tempat utama untuk menampilkan peserta. Jika peserta mengaktifkan kameranya, umpan video mereka akan ditampilkan di sini. Setiap peserta memiliki petak individu yang menunjukkan nama tampilan dan aliran video mereka (bila ada). Galeri mendukung banyak peserta dan diperbarui saat peserta ditambahkan atau dihapus ke panggilan.
- Bilah Tindakan: Di sinilah kontrol panggilan utama berada. Kontrol ini memungkinkan Anda mengaktifkan/menonaktifkan video dan mikrofon, membagikan layar, dan meninggalkan panggilan.
Di bawah ini Anda akan menemukan informasi lebih lanjut tentang prasyarat dan langkah-langkah untuk menyiapkan sampel.
Prasyarat
- Akun Azure dengan langganan aktif. Untuk detailnya, lihat Membuat akun gratis.
- Android Studio berjalan di komputer Anda
- Sumber daya Azure Communication Services. Untuk detailnya, lihat Membuat sumber daya Azure Communication Services.
- Azure Function yang menjalankan Titik Akhir Autentikasi untuk mengambil token akses.
Menjalankan sampel secara lokal
Sampel panggilan grup dapat dijalankan secara lokal menggunakan Android Studio. Pengembang dapat menggunakan perangkat fisik mereka atau emulator untuk menguji aplikasi.
Sebelum menjalankan sampel untuk pertama kalinya
- Buka Android Studio dan pilih
Open an Existing Project
- Buka folder
AzureCalling
di dalam rilis yang diunduh untuk sampel. - Perluas aplikasi/aset untuk memperbarui
appSettings.properties
. Tetapkan nilai untuk kuncicommunicationTokenFetchUrl
menjadi URL untuk Titik Akhir Autentikasi Anda disiapkan sebagai prasyarat.
Menjalankan sampel
Buat dan jalankan sampel di Android Studio.
(Opsional) Mengamankan titik akhir autentikasi
Untuk tujuan demonstrasi, sampel ini menggunakan titik akhir yang dapat diakses publik secara default untuk mengambil token Azure Communication Services. Untuk skenario produksi, sebaiknya gunakan titik akhir aman Anda sendiri untuk melakukan provisi token Anda sendiri.
Dengan konfigurasi tambahan, sampel ini mendukung koneksi ke titik akhir yang dilindungi ID Microsoft Entra (ID Microsoft Entra) sehingga login pengguna diperlukan agar aplikasi mengambil token Azure Communication Services. Lihat langkah di bawah ini:
Aktifkan autentikasi Microsoft Entra di aplikasi Anda.
Buka halaman gambaran umum aplikasi terdaftar Anda di bawah Pendaftaran Aplikasi Microsoft Entra. Perhatikan
Package name
, ,Signature hash
MSAL Configutaion
.
Edit
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
dan aturisAADAuthEnabled
untuk mengaktifkan ID Microsoft Entra.Edit
AndroidManifest.xml
dan tetapkanandroid:path
ke hash tanda tangan keystore. (Opsional. Nilai saat ini menggunakan hash dari debug.keystore yang dibundel. Jika keystore yang berbeda digunakan, ini harus diperbarui.)<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>
Salin konfigurasi Android MSAL dari portal Microsoft Azure dan tempelkan ke
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
. Sertakan "account_mode": "SINGLE"{ "client_id": "", "authorization_user_agent": "DEFAULT", "redirect_uri": "", "account_mode" : "SINGLE", "authorities": [ { "type": "AAD", "audience": { "type": "AzureADMyOrg", "tenant_id": "" } } ] }
Edit
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
dan tetapkan nilai untuk kuncicommunicationTokenFetchUrl
menjadi URL untuk Titik Akhir Autentikasi Anda.Edit
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
dan tetapkan nilai untuk kunciaadScopes
dari cakupanAzure Active Directory
Expose an API
Tetapkan nilai untuk
graphURL
masukAzureCalling/app/assets/appSettings.properties
sebagai titik akhir Graph API untuk mengambil informasi pengguna.Edit
AzureCalling/app/src/main/assets/appSettings.properties
dan atur nilai untuk kuncitenant
untuk mengaktifkan masuk senyap sehingga pengguna tidak perlu diautentikasi lagi dan lagi saat memulai ulang aplikasi.
Membersihkan sumber daya
Jika ingin membersihkan dan menghapus langganan Azure Communication Services, Anda bisa menghapus sumber daya atau grup sumber daya. Menghapus grup sumber daya juga menghapus sumber daya apa pun yang terkait dengannya. Pelajari selengkapnya tentang membersihkan sumber daya.
Langkah berikutnya
Untuk informasi lebih lanjut, baca artikel berikut:
- Pelajari cara menggunakan SDK Panggilan
- Pelajari lebih lanjut cara kerja panggilan
Pembacaan tambahan
- Azure Communication GitHub - Temukan lebih banyak contoh dan informasi di halaman resmi GitHub
- Sampel - Temukan lebih banyak sampel dan contoh di halaman gambaran umum sampel kami.
- Fitur Panggilan Azure Communication - Untuk mempelajari lebih lanjut panggilan Android sdk -Azure Communication Android Calling SDK
Sampel Hero Panggilan Grup Azure Communication Services untuk Windows menunjukkan bagaimana Communication Services Calling Windows SDK dapat digunakan untuk membangun pengalaman panggilan grup yang menyertakan suara dan video. Dalam sampel ini, Anda mempelajari cara menyiapkan dan menjalankan sampel. Ringkasan sampel disediakan untuk konteks.
Dalam mulai cepat ini, Anda mempelajari cara memulai panggilan video 1:1 menggunakan Azure Communication Services Calling SDK untuk Windows.
Kode sampel UWP
Prasyarat
Untuk menyelesaikan tutorial ini, Anda memerlukan prasyarat berikut:
Akun Azure dengan langganan aktif. Buat akun secara gratis.
Instal Visual Studio 2022 dengan beban kerja pengembangan Platform Windows Universal.
Sumber daya Communication Services yang disebarkan. Buat sumber daya Azure Communication Services. Anda perlu merekam string koneksi Anda untuk mulai cepat ini.
Token Akses Pengguna untuk Azure Communication Service. Anda juga dapat menggunakan Azure CLI dan menjalankan perintah dengan string koneksi Anda untuk membuat pengguna dan token akses.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
Untuk detailnya, lihat Menggunakan Azure CLI untuk Membuat dan Mengelola Token Akses.
Menyiapkan
Membuat proyek
Di Visual Studio, buat proyek baru dengan templat Blank App (Universal Windows) untuk menyiapkan aplikasi Universal Windows Platform (UWP) satu halaman.
Pasang paket
Klik kanan proyek Anda dan buka Manage Nuget Packages
untuk menginstal Azure.Communication.Calling.WindowsClient
1.2.0-beta.1 atau versi unggul. Pastikan Sertakan Yang Telah Dilepas telah dicentang.
Meminta akses
Buka Package.appxmanifest
dan klik Capabilities
.
Periksa Internet (Client & Server)
untuk mendapatkan akses masuk dan keluar ke Internet.
Periksa Microphone
untuk mengakses umpan audio mikrofon.
Periksa WebCam
untuk mengakses kamera perangkat.
Tambahkan kode berikut ke Package.appxmanifest
Anda dengan mengeklik kanan dan memilih Tampilkan Kode.
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>RtmMvrUap.dll</Path>
<ActivatableClass ActivatableClassId="VideoN.VideoSchemeHandler" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions>
Menyiapkan kerangka kerja aplikasi
Kita perlu mengonfigurasi tata letak dasar untuk melampirkan logika. Untuk melakukan panggilan keluar, kita perlu TextBox
memberikan ID Pengguna dari penerima panggilan. Kita juga butuh tombol Start Call
dan tombol Hang Up
.
Kita juga perlu mempratinjau video lokal dan merender video jarak jauh peserta lain. Jadi kita perlu dua elemen untuk menampilkan aliran video.
Buka MainPage.xaml
dari proyek Anda dan ganti konten dengan implementasi berikut.
<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>
Buka ke App.xaml.cs
(klik kanan dan pilih Tampilkan Kode) dan tambahkan baris ini ke atas:
using CallingQuickstart;
Buka MainPage.xaml.cs
(klik kanan dan pilih Tampilkan Kode) dan ganti konten dengan implementasi berikut:
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
}
}
}
Model objek
Kelas dan antarmuka berikut menghandel beberapa fitur utama Azure Communication Services Calling SDK:
Nama | Deskripsi |
---|---|
CallClient |
CallClient adalah titik masuk utama ke pustaka klien Panggilan. |
CallAgent |
CallAgent digunakan untuk memulai dan menggabungkan panggilan. |
CommunicationCall |
CommunicationCall digunakan untuk mengelola panggilan yang ditempatkan atau digabungkan. |
CallTokenCredential |
CallTokenCredential digunakan sebagai kredensial token untuk membuat instans CallAgent . |
CommunicationUserIdentifier |
CommunicationUserIdentifier digunakan untuk mewakili identitas pengguna, yang dapat menjadi salah satu opsi berikut: CommunicationUserIdentifier , PhoneNumberIdentifier atau CallingApplication . |
Mengautentikasi klien
Untuk menginisialisasi CallAgent
, Anda memerlukan Token Akses Pengguna. Umumnya token ini dihasilkan dari layanan dengan autentikasi khusus untuk aplikasi. Untuk informasi selengkapnya tentang token akses pengguna, periksa panduan Token Akses Pengguna.
Untuk mulai cepat, ganti <AUTHENTICATION_TOKEN>
dengan token akses pengguna yang dihasilkan untuk sumber daya Azure Communication Service Anda.
Setelah Anda memiliki token, inisialisasi CallAgent
instans dengannya, yang memungkinkan kami untuk melakukan dan menerima panggilan. Untuk mengakses kamera pada perangkat, kita juga perlu mendapatkan instans Device Manager.
Tambahkan kode berikut ke fungsi InitCallAgentAndDeviceManagerAsync
.
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
}
}
Memulai panggilan dengan video
Tambahkan implementasi ke CallButton_Click
untuk memulai panggilan dengan video. Kita perlu menghitung kamera dengan instans manajer perangkat dan membangun LocalOutgoingVideoStream
. Kita perlu mengatur VideoOptions
dengan LocalVideoStream
dan meneruskannya dengan startCallOptions
untuk mengatur opsi awal untuk panggilan. Dengan melampirkan LocalOutgoingVideoStream
ke MediaElement
, kita dapat melihat pratinjau video lokal.
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;
}
Tambahkan metode untuk memulai atau menggabungkan berbagai jenis Panggilan (panggilan Azure Communication Services 1:1, panggilan telepon 1:1, panggilan Grup Azure Communication Services, gabungan rapat Teams, dll.).
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 } }
};
}
Tambahkan kode untuk membuat LocalVideoStream tergantung pada kamera yang dipilih pada CameraList_SelectionChanged
metode .
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);
}
Menerima panggilan masuk
Tambahkan implementasi ke OnIncomingCallAsync
untuk menjawab panggilan masuk dengan video, teruskan LocalVideoStream
ke acceptCallOptions
.
var incomingCall = args.IncomingCall;
var acceptCallOptions = new AcceptCallOptions() {
IncomingVideoOptions = new IncomingVideoOptions()
{
IncomingVideoStreamKind = VideoStreamKind.RemoteIncoming
}
};
_ = await incomingCall.AcceptAsync(acceptCallOptions);
Peserta jarak jauh dan streaming video jarak jauh
Semua peserta jarak jauh tersedia melalui koleksi RemoteParticipants
pada instans panggilan. Setelah panggilan tersambung (CallState.Connected
), kita dapat mengakses peserta jarak jauh panggilan dan menangani aliran video jarak jauh.
Catatan
Saat pengguna bergabung dalam panggilan, mereka dapat mengakses peserta jarak jauh saat ini melalui RemoteParticipants
koleksi. Kejadian RemoteParticipantsUpdated
ini tidak akan memicu peserta yang ada ini. Kejadian ini hanya akan memicu ketika peserta jarak jauh bergabung atau meninggalkan panggilan saat pengguna sudah dalam panggilan.
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;
}
}
Merender video jarak jauh
Untuk setiap streaming video jarak jauh, lampirkan ke 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();
});
}
}
Pembaruan status panggilan
Kita perlu membersihkan perender video setelah panggilan terputus dan menangani kasus ketika peserta jarak jauh awalnya bergabung dalam panggilan.
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;
}
}
Mengakhiri panggilan
Akhiri panggilan saat ini ketika tombol Hang Up
diklik. Tambahkan implementasi ke HangupButton_Click untuk mengakhiri panggilan dengan callAgent yang kami buat, dan robek pembaruan peserta dan panggil penanganan aktivitas status.
var call = this.callAgent?.Calls?.FirstOrDefault();
if (call != null)
{
try
{
await call.HangUpAsync(new HangUpOptions() { ForEveryone = true });
}
catch(Exception ex)
{
}
}
Menjalankan kode
Anda dapat membangun dan menjalankan kode di Visual Studio. Untuk platform solusi, kami mendukung ARM64
, x64
dan x86
.
Anda dapat melakukan panggilan video keluar dengan memberikan ID pengguna di bidang teks dan mengklik tombol Start Call
.
Catatan: Panggilan 8:echo123
menghentikan streaming video karena bot echo tidak mendukung streaming video.
Untuk informasi selengkapnya tentang ID (identitas) pengguna lihat panduan Token Akses Pengguna.
Kode sampel WinUI 3
Prasyarat
Untuk menyelesaikan tutorial ini, Anda memerlukan prasyarat berikut:
Akun Azure dengan langganan aktif. Buat akun secara gratis.
Instal Visual Studio 2022 dan SDK Aplikasi Windows versi 1.2 pratinjau 2.
Pemahaman dasar tentang cara membuat aplikasi WinUI 3. Buat proyek WinUI 3 (SDK Aplikasi Windows) pertama Anda adalah sumber daya yang baik untuk memulai.
Sumber daya Communication Services yang disebarkan. Buat sumber daya Azure Communication Services. Anda perlu merekam string koneksi Anda untuk mulai cepat ini.
Token Akses Pengguna untuk Azure Communication Service. Anda juga dapat menggunakan Azure CLI dan menjalankan perintah dengan string koneksi Anda untuk membuat pengguna dan token akses.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
Untuk detailnya, lihat Menggunakan Azure CLI untuk Membuat dan Mengelola Token Akses.
Menyiapkan
Membuat proyek
Di Visual Studio, buat proyek baru dengan templat Aplikasi Kosong, Dipaketkan (WinUI 3 di Desktop) untuk menyiapkan aplikasi WinUI 3 satu halaman.
Pasang paket
Klik kanan proyek Anda dan buka Manage Nuget Packages
untuk menginstal Azure.Communication.Calling.WindowsClient
1.0.0 atau versi unggul. Pastikan Sertakan Yang Telah Dilepas telah dicentang.
Meminta akses
Tambahkan kode berikut ke app.manifest
:
<file name="RtmMvrMf.dll">
<activatableClass name="VideoN.VideoSchemeHandler" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
Menyiapkan kerangka kerja aplikasi
Kita perlu mengonfigurasi tata letak dasar untuk melampirkan logika. Untuk melakukan panggilan keluar, kita perlu TextBox
memberikan ID Pengguna dari penerima panggilan. Kita juga butuh tombol Start Call
dan tombol Hang Up
.
Kita juga perlu mempratinjau video lokal dan merender video jarak jauh peserta lain. Jadi kita perlu dua elemen untuk menampilkan aliran video.
Buka MainWindow.xaml
dari proyek Anda dan ganti konten dengan implementasi berikut.
<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>
Buka ke App.xaml.cs
(klik kanan dan pilih Tampilkan Kode) dan tambahkan baris ini ke atas:
using CallingQuickstart;
Buka MainWindow.xaml.cs
(klik kanan dan pilih Tampilkan Kode) dan ganti konten dengan implementasi berikut:
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();
});
}
}
}
Model objek
Kelas dan antarmuka berikut menghandel beberapa fitur utama Azure Communication Services Calling SDK:
Nama | Deskripsi |
---|---|
CallClient |
CallClient adalah titik masuk utama ke pustaka klien Panggilan. |
CallAgent |
CallAgent digunakan untuk memulai dan menggabungkan panggilan. |
CommunicationCall |
CommunicationCall digunakan untuk mengelola panggilan yang ditempatkan atau digabungkan. |
CallTokenCredential |
CallTokenCredential digunakan sebagai kredensial token untuk membuat instans CallAgent . |
CommunicationUserIdentifier |
CommunicationUserIdentifier digunakan untuk mewakili identitas pengguna, yang dapat menjadi salah satu opsi berikut: CommunicationUserIdentifier , PhoneNumberIdentifier atau CallingApplication . |
Mengautentikasi klien
Untuk menginisialisasi CallAgent
, Anda memerlukan Token Akses Pengguna. Umumnya token ini dihasilkan dari layanan dengan autentikasi khusus untuk aplikasi. Untuk informasi selengkapnya tentang token akses pengguna, periksa panduan Token Akses Pengguna.
Untuk mulai cepat, ganti <AUTHENTICATION_TOKEN>
dengan token akses pengguna yang dihasilkan untuk sumber daya Azure Communication Service Anda.
Setelah Anda memiliki token yang menginisialisasi CallAgent
instans dengannya, yang memungkinkan kami untuk melakukan dan menerima panggilan. Untuk mengakses kamera pada perangkat, kita juga perlu mendapatkan instans Device Manager.
Tambahkan kode berikut ke fungsi InitCallAgentAndDeviceManagerAsync
.
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;
Memulai panggilan dengan video
Tambahkan implementasi ke CallButton_Click
untuk memulai panggilan dengan video. Kita perlu menghitung kamera dengan instans manajer perangkat dan membangun LocalVideoStream
. Kita perlu mengatur VideoOptions
dengan LocalVideoStream
dan meneruskannya dengan startCallOptions
untuk mengatur opsi awal untuk panggilan. Dengan melampirkan LocalVideoStream
ke MediaPlayerElement
, kita dapat melihat pratinjau video lokal.
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;
Menerima panggilan masuk
Tambahkan implementasi ke Agent_OnIncomingCallAsync
untuk menjawab panggilan masuk dengan video, teruskan LocalVideoStream
ke 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);
Peserta jarak jauh dan streaming video jarak jauh
Semua peserta jarak jauh tersedia melalui koleksi RemoteParticipants
pada instans panggilan. Setelah panggilan tersambung, kita dapat mengakses peserta jarak jauh panggilan dan menangani aliran video jarak jauh.
Catatan
Saat pengguna bergabung dalam panggilan, mereka dapat mengakses peserta jarak jauh saat ini melalui RemoteParticipants
koleksi. Kejadian OnRemoteParticipantsUpdated
ini tidak akan memicu peserta yang ada ini. Kejadian ini hanya akan memicu ketika peserta jarak jauh bergabung atau meninggalkan panggilan saat pengguna sudah dalam panggilan.
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);
}
}
Merender video jarak jauh
Untuk setiap streaming video jarak jauh, lampirkan ke 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();
});
}
}
Pembaruan status panggilan
Kita perlu membersihkan perender video setelah panggilan terputus dan menangani kasus ketika peserta jarak jauh awalnya bergabung dalam panggilan.
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;
}
}
Mengakhiri panggilan
Akhiri panggilan saat ini ketika tombol Hang Up
diklik. Tambahkan implementasi ke HangupButton_Click untuk mengakhiri panggilan dengan callAgent yang kami buat, dan robek pembaruan peserta dan panggil penanganan aktivitas status.
this.call.OnRemoteParticipantsUpdated -= Call_OnRemoteParticipantsUpdatedAsync;
this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions());
Menjalankan kode
Anda dapat membangun dan menjalankan kode di Visual Studio. Untuk platform solusi, kami mendukung ARM64
, x64
dan x86
.
Anda dapat melakukan panggilan video keluar dengan memberikan ID pengguna di bidang teks dan mengklik tombol Start Call
.
Catatan: Panggilan 8:echo123
menghentikan streaming video karena bot echo tidak mendukung streaming video.
Untuk informasi selengkapnya tentang ID (identitas) pengguna lihat panduan Token Akses Pengguna.