Ismerkedés a hívó főhős mintával
Az Azure Communication Services csoporthívási főkiszolgálói mintája bemutatja, hogyan használható a Communication Services Calling Web SDK a csoporthívási élmény létrehozásához.
Ebben a rövid útmutatóban megtudhatja, hogyan működik a minta, mielőtt futtatnánk a mintát a helyi gépen, majd üzembe helyeznénk a mintát az Azure-ban saját Azure Communication Services-erőforrásaival.
Kód letöltése
A minta projektjének megkeresése a GitHubon. A minta egy olyan verziója, amely a nyilvános előzetes verzióban jelenleg elérhető funkciókat tartalmazza, például a Teams Interop és a Hívásrögzítés egy külön ágon található.
Áttekintés
A minta ügyféloldali és kiszolgálóoldali alkalmazással is rendelkezik. Az ügyféloldali alkalmazás egy React/Redux webalkalmazás, amely a Microsoft Fluent felhasználói felületi keretrendszerét használja. Ez az alkalmazás kéréseket küld egy ASP.NET Core kiszolgálóoldali alkalmazásnak , amely segít az ügyféloldali alkalmazásnak az Azure-hoz való csatlakozásban.
A minta a következőképpen néz ki:
Amikor lenyomja a "Hívás indítása" gombot, a webalkalmazás lekéri a felhasználó hozzáférési jogkivonatát a kiszolgálóoldali alkalmazásból. Ez a jogkivonat ezután az ügyfélalkalmazás Azure Communication Serviceshez való csatlakoztatására szolgál. A jogkivonat lekérése után a rendszer kérni fogja, hogy adja meg a használni kívánt kamerát és mikrofont. Váltóvezérlőkkel letilthatja/engedélyezheti az eszközöket:
Miután konfigurálta a megjelenítendő nevet és az eszközöket, csatlakozhat a hívási munkamenethez. Látni fogja a fő hívási vásznon, ahol az alapvető hívási élmény él.
A fő hívóképernyő összetevői:
- Médiatár: A fő szakasz, ahol a résztvevők láthatók. Ha egy résztvevőnek engedélyezve van a kamerája, a videó hírcsatornája itt látható. Minden résztvevő rendelkezik egy külön csempével, amely megjeleníti a megjelenítendő nevét és a videóstreamet (ha van ilyen)
- Fejléc: Itt találhatók az elsődleges hívásvezérlők a beállítások és a résztvevők oldalsávjának váltásához, a videó be- és kikapcsolásához, a képernyő megosztásához és a hívás elhagyásához.
- Oldalsáv: Itt jelennek meg a résztvevők és a beállítások adatai, amikor a fejléc vezérlőivel váltanak. Az összetevőt a jobb felső sarokban lévő X használatával lehet elvetni. A résztvevők oldalsávja megjeleníti a résztvevők listáját és egy hivatkozást, a amelyen további felhasználókat hívhat meg csevegésre. A beállítások oldalsávja lehetővé teszi a mikrofon- és kamerabeállítások konfigurálását.
Az alábbiakban további információt talál a minta beállításának előfeltételeiről és lépéseiről.
Előfeltételek
- Egy Azure-fiók, aktív előfizetéssel. További részletekért lásd : Fiók létrehozása ingyenesen
- Node.js (12.18.4 vagy újabb)
- Visual Studio Code (stabil build)
- Egy Azure Communication Services-erőforrás. További részletekért lásd : Azure Communication Services-erőforrás létrehozása. Ehhez a rövid útmutatóhoz rögzítenie kell az erőforrás-kapcsolati sztring.
A minta első futtatása előtt
Nyisson meg egy PowerShell-példányt, Windows Terminált, parancssort vagy azzal egyenértékű parancsot, és keresse meg azt a könyvtárat, amelybe a mintát klónozni szeretné.
git clone https://github.com/Azure-Samples/communication-services-web-calling-hero.git
Szerezze be az
Connection String
Azure Portalt vagy az Azure CLI-t.az communication list-key --name "<acsResourceName>" --resource-group "<resourceGroup>"
A kapcsolati sztring további információkért lásd: Azure Communication Resources létrehozása
Miután megkapta a
Connection String
fájlt, adja hozzá a kapcsolati sztring a mintákhoz/kiszolgálóhoz/appsetting.json fájlhoz. Adja meg a kapcsolati sztring a következő változóban:ResourceConnectionString
.Szerezze be az
Endpoint string
Azure Portalt vagy az Azure CLI-t.az communication list-key --name "<acsResourceName>" --resource-group "<resourceGroup>"
További információ a végponti sztringekről: Azure Communication Resources létrehozása
A lekérés
Endpoint String
után adja hozzá a végponti sztringet a mintákhoz/kiszolgálóhoz/appsetting.json fájlhoz. Adja meg a végponti sztringet a változóbanEndpointUrl
Helyi futtatás
Függőségek telepítése
npm run setup
A hívó alkalmazás indítása
npm run start
Ezzel megnyílik egy ügyfélkiszolgáló a 3000-es porton, amely a webhelyfájlokat szolgálja ki, valamint egy api-kiszolgálót a 8080-es porton, amely olyan funkciókat hajt végre, mint a hívás résztvevőinek jogkivonatainak verése.
Hibaelhárítás
Az alkalmazás egy "Nem támogatott böngésző" képernyőt jelenít meg, de támogatott böngészőben vagyok.
Ha az alkalmazást a localhosttól eltérő gazdagépnéven kézbesítik, akkor a forgalmat https-en keresztül kell kiszolgálnia, és nem http-en.
Közzététel az Azure platformon
npm run setup
npm run build
npm run package
- Használja az Azure-bővítményt, és telepítse a Calling/Dist könyvtárat az app service-ben
Az erőforrások eltávolítása
Ha törölni és eltávolítani szeretne egy Communication Services-előfizetést, törölheti az erőforrást vagy az erőforráscsoportot. Az erőforráscsoport törlése a hozzá társított egyéb erőforrásokat is törli. További információ az erőforrások tisztításáról.
Következő lépések
További információért tekintse át az alábbi cikkeket:
- Ismerkedés a Hívó SDK használatával
- További információ a hívás működéséről
További információ
- Minták – További mintákat és példákat találhat a minták áttekintési oldalán.
- Redux – Ügyféloldali állapotkezelés
- FluentUI – Microsoft-alapú felhasználói felületi kódtár
- React – Kódtár felhasználói felületek létrehozásához
- ASP.NET Core – Keretrendszer webalkalmazások létrehozásához
Az iOS-hez készült Azure Communication Services csoporthívási fő minta bemutatja, hogyan használható az iOS-et hívó Kommunikációs szolgáltatások SDK egy hang- és videohívást tartalmazó csoporthívási felület létrehozásához. Ebben a rövid útmutatóban megtudhatja, hogyan állíthatja be és futtathatja a mintát. A rendszer áttekintést nyújt a mintáról a környezethez.
Kód letöltése
A minta projektjének megkeresése a GitHubon.
Áttekintés
A minta egy natív iOS-alkalmazás, amely az Azure Communication Services iOS SDK-jait használja a hang- és videohívást egyaránt tartalmazó hívási felület létrehozásához. Az alkalmazás kiszolgálóoldali összetevőt használ az Azure Communication Services SDK inicializálásához használt hozzáférési jogkivonatok kiépítéséhez. A kiszolgálóoldali összetevő konfigurálásához kövesse a megbízható szolgáltatást az Azure Functions oktatóanyagával.
A minta a következőképpen néz ki:
Amikor lenyomja az "Új hívás indítása" gombot, az iOS-alkalmazás kéri, hogy adja meg a megjelenítendő nevet a híváshoz.
Miután a "Hívás indítása" képernyőn a "Tovább" gombra koppintott, lehetősége van megosztani a hívás csoportazonosítóját az iOS megosztási lapján.
Az alkalmazás lehetővé teszi egy meglévő Azure Communication Services-híváshoz való csatlakozást a meglévő hívás azonosítójának vagy teams-azonosító hivatkozásának megadásával.
A híváshoz való csatlakozás után a rendszer kérni fogja, hogy adjon engedélyt az alkalmazásnak a kamerához és a mikrofonhoz való hozzáféréshez, ha még nincs engedélyezve. Ne feledje, hogy az AVFoundation-alapú alkalmazásokhoz hasonlóan a valódi hang- és videofunkciók csak valós hardveren érhetők el.
Miután konfigurálta a megjelenítendő nevet, és csatlakozott a híváshoz, látni fogja a fő hívási vásznon, ahol az alapvető hívási élmény él.
A fő hívóképernyő összetevői:
- Médiatár: A fő szakasz, ahol a résztvevők láthatók. Ha egy résztvevőnek engedélyezve van a kamerája, a videó hírcsatornája itt látható. Minden résztvevő rendelkezik egy külön csempével, amely megjeleníti a megjelenítendő nevét és a videóstreamet (ha van ilyen). A katalógus több résztvevőt támogat, és akkor frissül, ha a résztvevőket hozzáadják vagy eltávolítják a hívásból.
- Műveletsáv: Itt találhatók az elsődleges hívásvezérlők. Ezek a vezérlők lehetővé teszik a videó és a mikrofon be- és kikapcsolását, a képernyő megosztását és a hívás elhagyását.
Az alábbiakban további információkat talál a minta beállításának előfeltételeiről és lépéseiről.
Előfeltételek
- Egy Azure-fiók, aktív előfizetéssel. További részletekért lásd : Fiók létrehozása ingyenesen.
- Egy Xcode-ot futtató Mac gép, valamint egy érvényes fejlesztői tanúsítvány, amely telepítve van a kulcskarikába.
- Egy Azure Communication Services-erőforrás. További részletekért lásd : Azure Communication Services-erőforrás létrehozása.
- A hitelesítési végpontot futtató Azure-függvény hozzáférési jogkivonatok lekéréséhez.
Minta helyi futtatása
A csoporthívási minta helyileg futtatható az XCode használatával. A fejlesztők használhatják a fizikai eszközüket vagy egy emulátort az alkalmazás teszteléséhez.
A minta első futtatása előtt
- Telepítse a függőségeket a futtatással
pod install
. - Megnyitás
AzureCalling.xcworkspace
az XCode-ban. - Hozzon létre egy szövegfájlt a gyökérkönyvtárban, hívja meg
AppSettings.xcconfig
és állítsa be az értéket:communicationTokenFetchUrl = <your authentication endpoint, without the https:// component>
Minta futtatása
Hozza létre és futtassa a mintát az XCode-ban az AzureCalling-cél használatával a választott szimulátoron vagy eszközön.
(Nem kötelező) Hitelesítési végpont biztonságossá tétele
Bemutató célokra ez a minta alapértelmezés szerint egy nyilvánosan elérhető végpontot használ egy Azure Communication Services hozzáférési jogkivonat lekéréséhez. Éles helyzetekben javasoljuk, hogy saját biztonságos végpontot használjon saját jogkivonatok kiépítéséhez.
További konfigurációval ez a minta támogatja a Microsoft Entra ID (Microsoft Entra ID) által védett végponthoz való csatlakozást, hogy az alkalmazáshoz felhasználói bejelentkezés szükséges az Azure Communication Services hozzáférési jogkivonatának lekéréséhez. Lásd az alábbi lépéseket:
- Engedélyezze a Microsoft Entra-hitelesítést az alkalmazásban.
- Nyissa meg a regisztrált alkalmazás áttekintési oldalát a Microsoft Entra alkalmazásregisztrációk területén. Jegyezze fel a
Application (client) ID
,Directory (tenant) ID
Application ID URI
- Hozzon létre egy
AppSettings.xcconfig
fájlt a gyökérben, ha még nincs jelen, és adja hozzá az értékeket:communicationTokenFetchUrl = <Application ID URI, without the https:// component> aadClientId = <Application (client) ID> aadTenantId = <Directory (tenant) ID>
Az erőforrások eltávolítása
Ha törölni és eltávolítani szeretne egy Communication Services-előfizetést, törölheti az erőforrást vagy az erőforráscsoportot. Az erőforráscsoport törlése a hozzá társított egyéb erőforrásokat is törli. További információ az erőforrások tisztításáról.
Következő lépések
További információért tekintse át az alábbi cikkeket:
- Ismerkedés a Hívó SDK használatával
- További információ a hívás működéséről
További információ
- Azure Communication GitHub – További példák és információk a hivatalos GitHub-oldalon
- Minták – További mintákat és példákat találhat a minták áttekintési oldalán.
- Azure Communication Calling Features – További információ az iOS-sdk hívásáról – Azure Communication iOS Calling SDK
Az Androidhoz készült Azure Communication Services csoporthívási fő minta bemutatja, hogyan használható az Android SDK-t hívó kommunikációs szolgáltatások egy hang- és videohívást tartalmazó csoporthívási felület létrehozásához. Ebben a rövid útmutatóban megtudhatja, hogyan állíthatja be és futtathatja a mintát. A rendszer áttekintést nyújt a mintáról a környezethez.
Kód letöltése
A minta projektjének megkeresése a GitHubon.
Áttekintés
A minta egy natív Android-alkalmazás, amely az Azure Communication Services Android felhasználói felületének ügyféloldali kódtárát használja a hang- és videohívást egyaránt tartalmazó hívófelület létrehozásához. Az alkalmazás kiszolgálóoldali összetevőt használ az Azure Communication Services SDK inicializálásához használt hozzáférési jogkivonatok kiépítéséhez. A kiszolgálóoldali összetevő konfigurálásához kövesse a megbízható szolgáltatást az Azure Functions oktatóanyagával.
A minta a következőképpen néz ki:
Amikor lenyomja az "Új hívás indítása" gombot, az Android-alkalmazás kéri, hogy adja meg a megjelenítendő nevet a híváshoz.
Miután a "Hívás indítása" lapon a "Tovább" gombra kattintott, lehetősége van megosztani a "Csoporthívás azonosítóját".
Az alkalmazás lehetővé teszi egy meglévő Azure Communication Services-híváshoz való csatlakozást a meglévő hívás azonosítójának vagy a Teams-értekezletazonosító hivatkozásának megadásával és a megjelenítendő név megadásával.
A híváshoz való csatlakozás után a rendszer kérni fogja, hogy adjon engedélyt az alkalmazásnak a kamerához és a mikrofonhoz való hozzáféréshez, ha még nincs engedélyezve. Megjelenik a fő hívásvásznon, ahol az alapvető hívási élmény él.
A fő hívóképernyő összetevői:
- Médiatár: A fő szakasz, ahol a résztvevők láthatók. Ha egy résztvevőnek engedélyezve van a kamerája, a videó hírcsatornája itt látható. Minden résztvevő rendelkezik egy külön csempével, amely megjeleníti a megjelenítendő nevét és a videóstreamet (ha van ilyen). A katalógus több résztvevőt támogat, és akkor frissül, ha a résztvevőket hozzáadják vagy eltávolítják a hívásból.
- Műveletsáv: Itt találhatók az elsődleges hívásvezérlők. Ezek a vezérlők lehetővé teszik a videó és a mikrofon be- és kikapcsolását, a képernyő megosztását és a hívás elhagyását.
Az alábbiakban további információkat talál a minta beállításának előfeltételeiről és lépéseiről.
Előfeltételek
- Egy Azure-fiók, aktív előfizetéssel. További részletekért lásd : Fiók létrehozása ingyenesen.
- A számítógépen futó Android Studio
- Egy Azure Communication Services-erőforrás. További részletekért lásd : Azure Communication Services-erőforrás létrehozása.
- A hitelesítési végpontot futtató Azure-függvény hozzáférési jogkivonatok lekéréséhez.
Minta helyi futtatása
A csoporthívási minta helyileg futtatható az Android Studióval. A fejlesztők használhatják a fizikai eszközüket vagy egy emulátort az alkalmazás teszteléséhez.
A minta első futtatása előtt
- Nyissa meg az Android Studiót, és válassza a
Open an Existing Project
- Nyissa meg a mappát a
AzureCalling
minta letöltött kiadásában. - Bontsa ki az alkalmazást/objektumokat a frissítéshez
appSettings.properties
. Állítsa be a kulcscommunicationTokenFetchUrl
értékét az előfeltételként beállított hitelesítési végpont URL-címének.
Minta futtatása
Hozza létre és futtassa a mintát az Android Studióban.
(Nem kötelező) Hitelesítési végpont biztonságossá tétele
Bemutató célokra ez a minta alapértelmezés szerint egy nyilvánosan elérhető végpontot használ egy Azure Communication Services-jogkivonat lekéréséhez. Éles helyzetekben javasoljuk, hogy saját biztonságos végpontot használjon saját jogkivonatok kiépítéséhez.
További konfiguráció esetén ez a minta támogatja a Microsoft Entra ID (Microsoft Entra ID) által védett végponthoz való csatlakozást, hogy az alkalmazás felhasználói bejelentkezést igényeljen egy Azure Communication Services-jogkivonat lekéréséhez. Lásd az alábbi lépéseket:
Engedélyezze a Microsoft Entra-hitelesítést az alkalmazásban.
Nyissa meg a regisztrált alkalmazás áttekintési oldalát a Microsoft Entra alkalmazásregisztrációk területén. Jegyezze fel a
Package name
,Signature hash
.MSAL Configutaion
Szerkessze
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
és engedélyezzeisAADAuthEnabled
a Microsoft Entra-azonosítót.Szerkessze
AndroidManifest.xml
és állítsa beandroid:path
a kulcstár-aláírás kivonatát. (Nem kötelező. Az aktuális érték a csomagolt debug.keystore kivonatát használja. Ha más kulcstárat használ, ezt frissíteni kell.)<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>
Másolja az MSAL Android-konfigurációt az Azure Portalról, és illessze be a fájlba
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
. "account_mode": "SINGLE"{ "client_id": "", "authorization_user_agent": "DEFAULT", "redirect_uri": "", "account_mode" : "SINGLE", "authorities": [ { "type": "AAD", "audience": { "type": "AzureADMyOrg", "tenant_id": "" } } ] }
Szerkessze
AzureCalling/app/src/main/res/raw/auth_config_single_account.json
és állítsa be a kulcscommunicationTokenFetchUrl
értékét úgy, hogy a biztonságos hitelesítési végpont URL-címe legyen.A kulcs
aadScopes
értékének szerkesztéseAzureCalling/app/src/main/res/raw/auth_config_single_account.json
és beállítása hatókörökbőlAzure Active Directory
Expose an API
A felhasználói adatok beolvasásához
graphURL
állítsa beAzureCalling/app/assets/appSettings.properties
a Be értéket Graph API-végpontként.Szerkessze
AzureCalling/app/src/main/assets/appSettings.properties
és állítsa be a kulcstenant
értékét a csendes bejelentkezés engedélyezéséhez, hogy a felhasználót ne kelljen újra és újra hitelesíteni az alkalmazás újraindítása közben.
Az erőforrások eltávolítása
Ha törölni és eltávolítani szeretne egy Communication Services-előfizetést, törölheti az erőforrást vagy az erőforráscsoportot. Az erőforráscsoport törlése a hozzá társított egyéb erőforrásokat is törli. További információ az erőforrások tisztításáról.
Következő lépések
További információért tekintse át az alábbi cikkeket:
- Ismerkedés a Hívó SDK használatával
- További információ a hívás működéséről
További információ
- Azure Communication GitHub – További példák és információk a hivatalos GitHub-oldalon
- Minták – További mintákat és példákat találhat a minták áttekintési oldalán.
- Azure Communication Calling Features – További információ az Android sdk hívásáról – Azure Communication Android Calling SDK
A WindowsHoz készült Azure Communication Services csoporthívási fő minta bemutatja, hogyan használható a Kommunikációs szolgáltatások hívása Windows SDK-val egy hang- és videohívást tartalmazó csoporthívási felület létrehozásához. Ebben a mintában megtudhatja, hogyan állíthatja be és futtathatja a mintát. A rendszer áttekintést nyújt a mintáról a környezethez.
Ebben a rövid útmutatóban megtudhatja, hogyan indíthat 1:1-ás videohívást a Windowshoz készült Azure Communication Services Calling SDK használatával.
UWP-mintakód
Előfeltételek
Az oktatóanyag teljesítéséhez a következő előfeltételekre lesz szüksége:
Egy Azure-fiók, aktív előfizetéssel. Fiók ingyenes létrehozása.
Telepítse a Visual Studio 2022-t Univerzális Windows-platform fejlesztési számítási feladattal.
Üzembe helyezett Communication Services-erőforrás. Hozzon létre egy Communication Services-erőforrást. Ehhez a rövid útmutatóhoz rögzítenie kell a kapcsolati sztring.
Felhasználói hozzáférési jogkivonat az Azure Communication Service-hez. Az Azure CLI-t is használhatja, és futtathatja a parancsot a kapcsolati sztring egy felhasználó és egy hozzáférési jogkivonat létrehozásához.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
További részletekért lásd: Hozzáférési jogkivonatok létrehozása és kezelése az Azure CLI használatával.
Beállítás
A projekt létrehozása
A Visual Studióban hozzon létre egy új projektet az Üres alkalmazás (Univerzális Windows) sablonnal egy egyoldalas Univerzális Windows-platform (UWP) alkalmazás beállításához.
Telepítse a(z) csomagot
Kattintson a jobb gombbal a projektre, és nyissa meg az Manage Nuget Packages
1.2.0-beta.1 vagy a superior verzió telepítését Azure.Communication.Calling.WindowsClient
. Győződjön meg arról, hogy az Előzetes belefoglalás jelölőnégyzet be van jelölve.
Hozzáférés kérése
Ugrás, Package.appxmanifest
majd kattintson a gombra Capabilities
.
Ellenőrizze Internet (Client & Server)
, hogy szeretne-e bejövő és kimenő hozzáférést szerezni az internethez.
Ellenőrizze Microphone
, hogy elérhető-e a mikrofon hangcsatornája.
Ellenőrizze WebCam
az eszköz kamerájának elérését.
Adja hozzá a következő kódot a Package.appxmanifest
jobb gombbal a Kód megtekintése parancsra kattintva.
<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>RtmMvrUap.dll</Path>
<ActivatableClass ActivatableClassId="VideoN.VideoSchemeHandler" ThreadingModel="both" />
</InProcessServer>
</Extension>
</Extensions>
Az alkalmazás-keretrendszer beállítása
Egy alapszintű elrendezést kell konfigurálnunk a logikánk csatolásához. Kimenő hívás indításához meg kell TextBox
adnia a hívó felhasználóazonosítóját. Egy gombra és egy Start Call
gombra Hang Up
is szükségünk van.
A helyi videó előnézetét is meg kell tekintenünk, és el kell készítenünk a másik résztvevő távoli videóját. Tehát két elemre van szükségünk a videóstreamek megjelenítéséhez.
Nyissa meg a MainPage.xaml
projektet, és cserélje le a tartalmat a következő megvalósításra.
<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>
Nyissa meg a következőt App.xaml.cs
(kattintson a jobb gombbal, és válassza a Kód megtekintése lehetőséget), és adja hozzá ezt a sort a tetejére:
using CallingQuickstart;
Nyissa meg a MainPage.xaml.cs
(jobb gombbal kattintva és válassza a Kód megtekintése) lehetőséget, és cserélje le a tartalmat a következő implementációra:
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
}
}
}
Objektummodell
A következő osztályok és felületek kezelik az Azure Communication Services Calling SDK néhány fő funkcióját:
Név | Leírás |
---|---|
CallClient |
Ez CallClient a hívási ügyfélkódtár fő belépési pontja. |
CallAgent |
Ez CallAgent a hívások indítására és csatlakoztatására szolgál. |
CommunicationCall |
A CommunicationCall rendszer az elhelyezett vagy csatlakoztatott hívások kezelésére szolgál. |
CallTokenCredential |
A CallTokenCredential rendszer a jogkivonat hitelesítő adataiként használja a példányosításhoz.CallAgent |
CommunicationUserIdentifier |
A CommunicationUserIdentifier felhasználó identitásának ábrázolására szolgál, amely a következő lehetőségek egyike lehet: CommunicationUserIdentifier vagy PhoneNumberIdentifier CallingApplication . |
Az ügyfél hitelesítése
A CallAgent
felhasználói hozzáférési jogkivonat inicializálásához felhasználói hozzáférési jogkivonatra van szükség. Ez a jogkivonat általában egy olyan szolgáltatásból jön létre, amely az alkalmazásra jellemző hitelesítéssel rendelkezik. A felhasználói hozzáférési jogkivonatokról további információt a Felhasználói hozzáférési jogkivonatok útmutatójában talál.
A rövid útmutatóban cserélje le <AUTHENTICATION_TOKEN>
az Azure Communication Service-erőforráshoz létrehozott felhasználói hozzáférési jogkivonatot.
Miután rendelkezik jogkivonattal, inicializáljon vele egy példányt CallAgent
, amely lehetővé teszi számunkra a hívások indítását és fogadását. Az eszköz kameráinak eléréséhez Eszközkezelő példányt is le kell szereznünk.
Adja hozzá a következő kódot a InitCallAgentAndDeviceManagerAsync
függvényhez.
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
}
}
Hívás indítása videóval
Adja hozzá az implementációt a CallButton_Click
hívás indításához videóval. Számba kell venni a kamerákat az eszközkezelő példányával, és létre kell hoznunk LocalOutgoingVideoStream
. A hívás kezdeti beállításainak beállításához meg kell adnunk VideoOptions
a következőt LocalVideoStream
, és át kell adnunk startCallOptions
. A helyi videó előnézetét a csatolással LocalOutgoingVideoStream
MediaElement
tekintheti meg.
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;
}
Adja hozzá a különböző típusú hívás indításához vagy csatlakozásához használt metódusokat (1:1 Azure Communication Services-hívás, 1:1 telefonhívás, Azure Communication Services-csoporthívás, Teams-értekezletbe való bekapcsolódás stb.).
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 } }
};
}
Adja hozzá a kódot a LocalVideoStream létrehozásához a módszer kiválasztott kamerájától CameraList_SelectionChanged
függően.
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);
}
Bejövő hívás elfogadása
Adja hozzá az implementációt a OnIncomingCallAsync
bejövő hívás videóval való fogadásához, majd adja át a LocalVideoStream
következőnek acceptCallOptions
: .
var incomingCall = args.IncomingCall;
var acceptCallOptions = new AcceptCallOptions() {
IncomingVideoOptions = new IncomingVideoOptions()
{
IncomingVideoStreamKind = VideoStreamKind.RemoteIncoming
}
};
_ = await incomingCall.AcceptAsync(acceptCallOptions);
Távoli résztvevő és távoli videóstreamek
A híváspéldányok gyűjteményén RemoteParticipants
keresztül minden távoli résztvevő elérhető. Miután a hívás csatlakozik (CallState.Connected
), hozzáférhetünk a hívás távoli résztvevőihez, és kezelhetjük a távoli videóstreameket.
Feljegyzés
Amikor egy felhasználó csatlakozik egy híváshoz, a gyűjteményen keresztül elérheti az RemoteParticipants
aktuális távoli résztvevőket. Az RemoteParticipantsUpdated
esemény nem aktiválódik a meglévő résztvevők számára. Ez az esemény csak akkor aktiválódik, ha egy távoli résztvevő csatlakozik vagy elhagyja a hívást, amíg a felhasználó már szerepel a hívásban.
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;
}
}
Távoli videók renderelése
Minden távoli videóstreamhez csatolja a 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();
});
}
}
Állapotfrissítés hívása
A hívás megszakadása után meg kell tisztítani a videoleképezőket, és kezelni kell az esetet, amikor a távoli résztvevők először csatlakoznak a híváshoz.
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;
}
}
Hívás befejezése
A gomb kattintásával fejezd be az Hang Up
aktuális hívást. Adja hozzá az implementációt a HangupButton_Click egy hívás befejezéséhez a létrehozott callAgenttel, és bontsa le a résztvevők frissítését és az állapot eseménykezelőinek hívását.
var call = this.callAgent?.Calls?.FirstOrDefault();
if (call != null)
{
try
{
await call.HangUpAsync(new HangUpOptions() { ForEveryone = true });
}
catch(Exception ex)
{
}
}
A kód futtatása
A kódot a Visual Studióban hozhatja létre és futtathatja. A megoldásplatformok esetében támogatjuk ARM64
a x86
. x64
Kimenő videohívást úgy kezdeményezhet, hogy megad egy felhasználói azonosítót a szövegmezőben, és rákattint a Start Call
gombra.
Megjegyzés: A hívás 8:echo123
leállítja a videostreamet, mert az Echo robot nem támogatja a videostreamelést.
A felhasználói azonosítókkal (identitással) kapcsolatos további információkért tekintse meg a felhasználói hozzáférési jogkivonatok útmutatóját .
WinUI 3 mintakód
Előfeltételek
Az oktatóanyag teljesítéséhez a következő előfeltételekre lesz szüksége:
Egy Azure-fiók, aktív előfizetéssel. Fiók ingyenes létrehozása.
Telepítse a Visual Studio 2022-t és Windows-alkalmazás SDK 1.2-es előzetes verzió 2-es verzióját.
WinUI 3-alkalmazások létrehozásának alapszintű ismerete. Az első WinUI 3 (Windows-alkalmazás SDK) projekt létrehozása jó erőforrás.
Üzembe helyezett Communication Services-erőforrás. Hozzon létre egy Communication Services-erőforrást. Ehhez a rövid útmutatóhoz rögzítenie kell a kapcsolati sztring.
Felhasználói hozzáférési jogkivonat az Azure Communication Service-hez. Az Azure CLI-t is használhatja, és futtathatja a parancsot a kapcsolati sztring egy felhasználó és egy hozzáférési jogkivonat létrehozásához.
az communication identity token issue --scope voip --connection-string "yourConnectionString"
További részletekért lásd: Hozzáférési jogkivonatok létrehozása és kezelése az Azure CLI használatával.
Beállítás
A projekt létrehozása
A Visual Studióban hozzon létre egy új projektet a Blank App, Packaged (WinUI 3 in Desktop) sablonnal egy egyoldalas WinUI 3-alkalmazás beállításához.
Telepítse a(z) csomagot
Kattintson a jobb gombbal a projektre, és nyissa meg az Manage Nuget Packages
1.0.0-s vagy újabb verzió telepítését Azure.Communication.Calling.WindowsClient
. Győződjön meg arról, hogy az Előzetes belefoglalás jelölőnégyzet be van jelölve.
Hozzáférés kérése
Adja hozzá a következő kódot a következőhöz app.manifest
:
<file name="RtmMvrMf.dll">
<activatableClass name="VideoN.VideoSchemeHandler" threadingModel="both" xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>
Az alkalmazás-keretrendszer beállítása
Egy alapszintű elrendezést kell konfigurálnunk a logikánk csatolásához. Kimenő hívás indításához meg kell TextBox
adnia a hívó felhasználóazonosítóját. Egy gombra és egy Start Call
gombra Hang Up
is szükségünk van.
A helyi videó előnézetét is meg kell tekintenünk, és el kell készítenünk a másik résztvevő távoli videóját. Tehát két elemre van szükségünk a videóstreamek megjelenítéséhez.
Nyissa meg a MainWindow.xaml
projektet, és cserélje le a tartalmat a következő megvalósításra.
<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>
Nyissa meg a következőt App.xaml.cs
(kattintson a jobb gombbal, és válassza a Kód megtekintése lehetőséget), és adja hozzá ezt a sort a tetejére:
using CallingQuickstart;
Nyissa meg a MainWindow.xaml.cs
(jobb gombbal kattintva és válassza a Kód megtekintése) lehetőséget, és cserélje le a tartalmat a következő implementációra:
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();
});
}
}
}
Objektummodell
A következő osztályok és felületek kezelik az Azure Communication Services Calling SDK néhány fő funkcióját:
Név | Leírás |
---|---|
CallClient |
Ez CallClient a hívási ügyfélkódtár fő belépési pontja. |
CallAgent |
Ez CallAgent a hívások indítására és csatlakoztatására szolgál. |
CommunicationCall |
A CommunicationCall rendszer az elhelyezett vagy csatlakoztatott hívások kezelésére szolgál. |
CallTokenCredential |
A CallTokenCredential rendszer a jogkivonat hitelesítő adataiként használja a példányosításhoz.CallAgent |
CommunicationUserIdentifier |
A CommunicationUserIdentifier felhasználó identitásának ábrázolására szolgál, amely a következő lehetőségek egyike lehet: CommunicationUserIdentifier vagy PhoneNumberIdentifier CallingApplication . |
Az ügyfél hitelesítése
A CallAgent
felhasználói hozzáférési jogkivonat inicializálásához felhasználói hozzáférési jogkivonatra van szükség. Ez a jogkivonat általában egy olyan szolgáltatásból jön létre, amely az alkalmazásra jellemző hitelesítéssel rendelkezik. A felhasználói hozzáférési jogkivonatokról további információt a Felhasználói hozzáférési jogkivonatok útmutatójában talál.
A rövid útmutatóban cserélje le <AUTHENTICATION_TOKEN>
az Azure Communication Service-erőforráshoz létrehozott felhasználói hozzáférési jogkivonatot.
Miután rendelkezik egy jogkivonattal, inicializálhat vele egy CallAgent
példányt, amely lehetővé teszi számunkra a hívások indítását és fogadását. Az eszköz kameráinak eléréséhez Eszközkezelő példányt is le kell szereznünk.
Adja hozzá a következő kódot a InitCallAgentAndDeviceManagerAsync
függvényhez.
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;
Hívás indítása videóval
Adja hozzá az implementációt a CallButton_Click
hívás indításához videóval. Számba kell venni a kamerákat az eszközkezelő példányával, és létre kell hoznunk LocalVideoStream
. A hívás kezdeti beállításainak beállításához meg kell adnunk VideoOptions
a következőt LocalVideoStream
, és át kell adnunk startCallOptions
. A helyi videó előnézetét a csatolással LocalVideoStream
MediaPlayerElement
tekintheti meg.
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;
Bejövő hívás elfogadása
Adja hozzá az implementációt a Agent_OnIncomingCallAsync
bejövő hívás videóval való fogadásához, majd adja át a LocalVideoStream
következőnek 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);
Távoli résztvevő és távoli videóstreamek
A híváspéldányok gyűjteményén RemoteParticipants
keresztül minden távoli résztvevő elérhető. A hívás csatlakoztatása után hozzáférhetünk a hívás távoli résztvevőihez, és kezelhetjük a távoli videóstreameket.
Feljegyzés
Amikor egy felhasználó csatlakozik egy híváshoz, a gyűjteményen keresztül elérheti az RemoteParticipants
aktuális távoli résztvevőket. Az OnRemoteParticipantsUpdated
esemény nem aktiválódik a meglévő résztvevők számára. Ez az esemény csak akkor aktiválódik, ha egy távoli résztvevő csatlakozik vagy elhagyja a hívást, amíg a felhasználó már szerepel a hívásban.
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);
}
}
Távoli videók renderelése
Minden távoli videóstreamhez csatolja a 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();
});
}
}
Állapotfrissítés hívása
A hívás megszakadása után meg kell tisztítani a videoleképezőket, és kezelni kell az esetet, amikor a távoli résztvevők először csatlakoznak a híváshoz.
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;
}
}
Hívás befejezése
A gomb kattintásával fejezd be az Hang Up
aktuális hívást. Adja hozzá az implementációt a HangupButton_Click egy hívás befejezéséhez a létrehozott callAgenttel, és bontsa le a résztvevők frissítését és az állapot eseménykezelőinek hívását.
this.call.OnRemoteParticipantsUpdated -= Call_OnRemoteParticipantsUpdatedAsync;
this.call.OnStateChanged -= Call_OnStateChangedAsync;
await this.call.HangUpAsync(new HangUpOptions());
A kód futtatása
A kódot a Visual Studióban hozhatja létre és futtathatja. A megoldásplatformok esetében támogatjuk ARM64
a x86
. x64
Kimenő videohívást úgy kezdeményezhet, hogy megad egy felhasználói azonosítót a szövegmezőben, és rákattint a Start Call
gombra.
Megjegyzés: A hívás 8:echo123
leállítja a videostreamet, mert az Echo robot nem támogatja a videostreamelést.
A felhasználói azonosítókkal (identitással) kapcsolatos további információkért tekintse meg a felhasználói hozzáférési jogkivonatok útmutatóját .