Snabbstart: Anslut din anropande app till ett Teams möte
Viktigt
Funktioner som beskrivs i det här dokumentet är för närvarande i offentlig förhandsversion. Den här förhandsversionen tillhandahålls utan serviceavtal och rekommenderas inte för produktionsarbetsbelastningar. Vissa funktioner kanske inte stöds eller kan vara begränsade. Mer information finns i Kompletterande villkor för användning av Microsoft Azure-förhandsversioner.
I den här snabbstarten lär du dig hur du ansluter till ett Teams möte med hjälp av Azure Communication Services Calling SDK for JavaScript.
Exempelkod
Hitta den färdiga koden för den här snabbstarten på GitHub.
Förutsättningar
- En fungerande Communication Services anropar webbappen.
- En Teams distribution.
Lägga till Teams ui-kontroller
Ersätt koden i index.html med följande kodfragment. Textrutan används för att ange Teams och knappen används för att delta i det angivna mötet:
<!DOCTYPE html>
<html>
<head>
<title>Communication Client - Calling Sample</title>
</head>
<body>
<h4>Azure Communication Services</h4>
<h1>Teams meeting join quickstart</h1>
<input id="teams-link-input" type="text" placeholder="Teams meeting link"
style="margin-bottom:1em; width: 300px;" />
<p>Call state <span style="font-weight: bold" id="call-state">-</span></p>
<p><span style="font-weight: bold" id="recording-state"></span></p>
<div>
<button id="join-meeting-button" type="button" disabled="false">
Join Teams Meeting
</button>
<button id="hang-up-button" type="button" disabled="true">
Hang Up
</button>
</div>
<script src="./bundle.js"></script>
</body>
</html>
Aktivera Teams ui-kontroller
Ersätt innehållet i client.js med följande kodfragment.
import { CallClient } from "@azure/communication-calling";
import { Features } from "@azure/communication-calling";
import { AzureCommunicationTokenCredential } from '@azure/communication-common';
let call;
let callAgent;
const meetingLinkInput = document.getElementById('teams-link-input');
const hangUpButton = document.getElementById('hang-up-button');
const teamsMeetingJoinButton = document.getElementById('join-meeting-button');
const callStateElement = document.getElementById('call-state');
const recordingStateElement = document.getElementById('recording-state');
async function init() {
const callClient = new CallClient();
const tokenCredential = new AzureCommunicationTokenCredential("<USER ACCESS TOKEN>");
callAgent = await callClient.createCallAgent(tokenCredential, {displayName: 'ACS user'});
teamsMeetingJoinButton.disabled = false;
}
init();
hangUpButton.addEventListener("click", async () => {
// end the current call
await call.hangUp();
// toggle button states
hangUpButton.disabled = true;
teamsMeetingJoinButton.disabled = false;
callStateElement.innerText = '-';
});
teamsMeetingJoinButton.addEventListener("click", () => {
// join with meeting link
call = callAgent.join({meetingLink: meetingLinkInput.value}, {});
call.on('stateChanged', () => {
callStateElement.innerText = call.state;
})
call.api(Features.Recording).on('isRecordingActiveChanged', () => {
if (call.api(Features.Recording).isRecordingActive) {
recordingStateElement.innerText = "This call is being recorded";
}
else {
recordingStateElement.innerText = "";
}
});
// toggle button states
hangUpButton.disabled = false;
teamsMeetingJoinButton.disabled = true;
});
Hämta länken Teams möte
Den Teams möteslänken kan hämtas med hjälp av Graph-API:er. Detta beskrivs i Graph dokumentationen.
SDK:Communication Services anropar accepterar en fullständig Teams möteslänk. Den här länken returneras som en del av resursen och är tillgänglig under egenskapen . Du kan också hämta nödvändig mötesinformation från URL:en för kopplingsmöte onlineMeeting i den Teams mötesbjudan. joinWebUrl
Kör koden
Webpack-användare kan använda webpack-dev-server för att skapa och köra din app. Kör följande kommando för att paketa programvärden på en lokal webbserver:
npx webpack-dev-server --entry ./client.js --output bundle.js --debug --devtool inline-source-map
Öppna din webbläsare och gå till http://localhost:8080/. Du bör se följande:
Infoga Teams kontext i textrutan och tryck på Delta Teams Meeting för att delta i Teams möte inifrån Communication Services program.
I den här snabbstarten lär du dig att ansluta till ett Teams-möte med hjälp av Azure Communication Services Calling SDK för Windows.
Förutsättningar
- En fungerande Communication Services anropar Windows app.
- En Teams distribution.
Lägg till Teams ui-kontroller och Aktivera Teams ui-kontroller
Ersätt koden i MainPage.xaml med följande kodfragment. Textrutan används för att ange Teams och knappen används för att ansluta till det angivna mötet:
<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}">
<StackPanel>
<TextBox PlaceholderText="Please enter the Teams meeting link." TextWrapping="Wrap" x:Name="TeamsLinkTextBox" Margin="10,10,10,10" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="Join Teams Meeting" Click="JoinButton_ClickAsync" x:Name="JoinButton" Margin="10,10,10,10" />
<Button Content="Leave Meeting" Click="LeaveButton_ClickAsync" x:Name="LeaveButton" Margin="10,10,10,10" />
</StackPanel>
<TextBlock TextWrapping="Wrap" x:Name="CallStatusTextBlock" Margin="10,10,10,10" />
<TextBlock TextWrapping="Wrap" x:Name="RecordingStatusTextBlock" Margin="10,10,10,10" />
</StackPanel>
</Page>
Aktivera Teams ui-kontroller
Ersätt innehållet i MainPage.xaml.cs med följande kodfragment:
using System;
using System.Threading.Tasks;
using Windows.UI.Core;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Azure.Communication;
using Azure.Communication.Calling;
namespace CallingQuickstart
{
public sealed partial class MainPage : Page
{
string user_token_ = "<User_Access_Token>";
Call call_;
CallClient call_client;
CallAgent call_agent;
public MainPage()
{
this.InitializeComponent();
call_client = new CallClient();
}
private async void JoinButton_ClickAsync(object sender, RoutedEventArgs e)
{
if (!await ValidateInput())
{
return;
}
//
// Create CallAgent
//
CommunicationTokenCredential token_credential;
try
{
token_credential = new CommunicationTokenCredential(user_token_);
CallAgentOptions call_agent_options = new CallAgentOptions();
call_agent = await call_client.CreateCallAgent(token_credential, call_agent_options);
}
catch
{
await new MessageDialog("It was not possible to create call agent. Please check if token is valid.").ShowAsync();
return;
}
//
// Join a Teams meeting
//
try
{
JoinCallOptions joinCallOptions = new JoinCallOptions();
TeamsMeetingLinkLocator teamsMeetingLinkLocator = new TeamsMeetingLinkLocator(TeamsLinkTextBox.Text);
call_ = await call_agent.JoinAsync(teamsMeetingLinkLocator, joinCallOptions);
}
catch
{
await new MessageDialog("It was not possible to join the Teams meeting. Please check if Teams Link is valid.").ShowAsync();
return;
}
//
// Set up call callbacks
//
call_.OnStateChanged += Call_OnStateChangedAsync;
call_.OnIsRecordingActiveChanged += Call_OnIsRecordingActiveChangedAsync;
}
private async void Call_OnStateChangedAsync(object sender, PropertyChangedEventArgs args)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
CallStatusTextBlock.Text = call_.State.ToString();
});
}
private async void Call_OnIsRecordingActiveChangedAsync(object sender, PropertyChangedEventArgs args)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
RecordingStatusTextBlock.Text = call_.IsRecordingActive ? "Recording is active." : "Recording is inactive.";
});
}
private async void LeaveButton_ClickAsync(object sender, RoutedEventArgs e)
{
try
{
await call_.HangUp(new HangUpOptions());
}
catch
{
await new MessageDialog("It was not possible to leave the Teams meeting.").ShowAsync();
}
}
private async Task<bool> ValidateInput()
{
if (user_token_.StartsWith("<"))
{
await new MessageDialog("Please enter token in source code.").ShowAsync();
return false;
}
if (TeamsLinkTextBox.Text.Trim().Length == 0 || !TeamsLinkTextBox.Text.StartsWith("http"))
{
await new MessageDialog("Please enter Teams meeting link.").ShowAsync();
return false;
}
return true;
}
}
}
Hämta länken Teams möte
Den Teams möteslänken kan hämtas med hjälp av Graph-API:er. Detta beskrivs i Graph dokumentation.
Sdk:Communication Services anropar accepterar en fullständig Teams möteslänk. Den här länken returneras som en del onlineMeeting av resursen som är tillgänglig under joinWebUrl egenskapen. Du kan också hämta nödvändig mötesinformation från URL:en för kopplingsmöte i Teams själva inbjudan.
Starta appen och anslut till Teams möte
Du kan skapa och köra appen på Visual Studio genom att välja Felsök Starta felsökning eller med hjälp av > kortkommandot (F5).
Infoga Teams kontexten i textrutan och tryck på Delta Teams Meeting för att delta i Teams möte inifrån Communication Services program.
I den här snabbstarten lär du dig att ansluta till ett Teams möte med hjälp av Azure Communication Services Calling SDK för Android.
Exempelkod
Hitta den färdiga koden för den här snabbstarten på GitHub.
Förutsättningar
- En fungerande Communication Services anropar Android-appen.
- En Teams distribution.
Lägga till Teams ui-kontroller
Ersätt koden i activity_main.xml med följande kodfragment. Textrutan används för att ange Teams och knappen används för att delta i det angivna mötet:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/teams_meeting_link"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Teams meeting link"
android:inputType="textUri"
android:layout_marginTop="100dp"
android:layout_marginHorizontal="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="70dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/join_meeting_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Join Meeting" />
<Button
android:id="@+id/hangup_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hangup" />
</LinearLayout>
<TextView
android:id="@+id/call_status_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/recording_status_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Aktivera Teams ui-kontroller
Ersätt innehållet i MainActivity.java med följande kodfragment:
package com.contoso.acsquickstart;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import com.azure.android.communication.calling.Call;
import com.azure.android.communication.calling.CallAgent;
import com.azure.android.communication.calling.CallClient;
import com.azure.android.communication.calling.HangUpOptions;
import com.azure.android.communication.calling.JoinCallOptions;
import com.azure.android.communication.common.CommunicationTokenCredential;
import com.azure.android.communication.calling.TeamsMeetingLinkLocator;
public class MainActivity extends AppCompatActivity {
private static final String[] allPermissions = new String[] { Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE };
private static final String UserToken = "<User_Access_Token>";
TextView callStatusBar;
TextView recordingStatusBar;
private CallAgent agent;
private Call call;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getAllPermissions();
createAgent();
Button joinMeetingButton = findViewById(R.id.join_meeting_button);
joinMeetingButton.setOnClickListener(l -> joinTeamsMeeting());
Button hangupButton = findViewById(R.id.hangup_button);
hangupButton.setOnClickListener(l -> leaveMeeting());
callStatusBar = findViewById(R.id.call_status_bar);
recordingStatusBar = findViewById(R.id.recording_status_bar);
}
/**
* Join Teams meeting
*/
private void joinTeamsMeeting() {
if (UserToken.startsWith("<")) {
Toast.makeText(this, "Please enter token in source code", Toast.LENGTH_SHORT).show();
return;
}
EditText calleeIdView = findViewById(R.id.teams_meeting_link);
String meetingLink = calleeIdView.getText().toString();
if (meetingLink.isEmpty()) {
Toast.makeText(this, "Please enter Teams meeting link", Toast.LENGTH_SHORT).show();
return;
}
JoinCallOptions options = new JoinCallOptions();
TeamsMeetingLinkLocator teamsMeetingLinkLocator = new TeamsMeetingLinkLocator(meetingLink);
call = agent.join(
getApplicationContext(),
teamsMeetingLinkLocator,
options);
call.addOnStateChangedListener(p -> setCallStatus(call.getState().toString()));
call.addOnIsRecordingActiveChangedListener(p -> setRecordingStatus(call.isRecordingActive()));
}
/**
* Leave from the meeting
*/
private void leaveMeeting() {
try {
call.hangUp(new HangUpOptions()).get();
} catch (ExecutionException | InterruptedException e) {
Toast.makeText(this, "Unable to leave meeting", Toast.LENGTH_SHORT).show();
}
}
/**
* Create the call agent
*/
private void createAgent() {
try {
CommunicationTokenCredential credential = new CommunicationTokenCredential(UserToken);
agent = new CallClient().createCallAgent(getApplicationContext(), credential).get();
} catch (Exception ex) {
Toast.makeText(getApplicationContext(), "Failed to create call agent.", Toast.LENGTH_SHORT).show();
}
}
/**
* Request each required permission if the app doesn't already have it.
*/
private void getAllPermissions() {
ArrayList<String> permissionsToAskFor = new ArrayList<>();
for (String permission : allPermissions) {
if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
permissionsToAskFor.add(permission);
}
}
if (!permissionsToAskFor.isEmpty()) {
ActivityCompat.requestPermissions(this, permissionsToAskFor.toArray(new String[0]), 1);
}
}
/**
* Ensure all permissions were granted, otherwise inform the user permissions are missing.
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, int[] grantResults) {
boolean allPermissionsGranted = true;
for (int result : grantResults) {
allPermissionsGranted &= (result == PackageManager.PERMISSION_GRANTED);
}
if (!allPermissionsGranted) {
Toast.makeText(this, "All permissions are needed to make the call.", Toast.LENGTH_LONG).show();
finish();
}
}
/**
* Shows call status in status bar
*/
private void setCallStatus(String status) {
runOnUiThread(() -> callStatusBar.setText(status));
}
/**
* Shows recording status status bar
*/
private void setRecordingStatus(boolean status) {
if (status == true) {
runOnUiThread(() -> recordingStatusBar.setText("This call is being recorded"));
}
else {
runOnUiThread(() -> recordingStatusBar.setText(""));
}
}
}
Hämta länken Teams möte
Den Teams möteslänken kan hämtas med hjälp av Graph-API:er. Detta beskrivs i Graph dokumentationen.
SDK:Communication Services anropar accepterar en fullständig Teams möteslänk. Den här länken returneras som en del onlineMeeting av resursen och är tillgänglig under joinWebUrl egenskapen. Du kan också hämta nödvändig mötesinformation från URL:en för kopplingsmöte i Teams själva inbjudan.
Starta appen och gå Teams möte
Appen kan nu startas med knappen "Kör app" i verktygsfältet (Skift + F10). Du bör se följande:
Infoga Teams kontext i textrutan och tryck på Anslut till möte för att delta i Teams möte inifrån Communication Services program.
I den här snabbstarten lär du dig hur du ansluter till ett Teams möte med hjälp av Azure Communication Services Anropa SDK för iOS.
Förutsättningar
- En fungerande Communication Services anropar iOS-appen.
- En Teams distribution.
Vi använder beta.12 av AzureCommunicationCalling SDK för den här snabbstarten så vi måste uppdatera podfilen och installera poddarna igen.
Ersätt din podfile med följande kod till podfilen och spara (se till att "target" matchar namnet på ditt projekt):
platform :ios, '13.0'
use_frameworks!
target 'AzureCommunicationCallingSample' do
pod 'AzureCommunicationCalling', '1.0.0-beta.12'
end
Ta bort poddmappen Podfile.lock och .xcworkspace. filen.
Kör pod install och öppna med .xcworkspace Xcode.
Lägg till Teams ui-kontroller och Aktivera Teams ui-kontroller
Ersätt koden i ContentView.swift med följande kodfragment. Textrutan används för att ange Teams och knappen används för att delta i det angivna mötet:
import SwiftUI
import AzureCommunicationCalling
import AVFoundation
struct ContentView: View {
@State var meetingLink: String = ""
@State var callStatus: String = ""
@State var message: String = ""
@State var recordingStatus: String = ""
@State var callClient: CallClient?
@State var callAgent: CallAgent?
@State var call: Call?
@State var callObserver: CallObserver?
var body: some View {
NavigationView {
Form {
Section {
TextField("Teams meeting link", text: $meetingLink)
Button(action: joinTeamsMeeting) {
Text("Join Teams Meeting")
}.disabled(callAgent == nil)
Button(action: leaveMeeting) {
Text("Leave Meeting")
}.disabled(call == nil)
Text(callStatus)
Text(message)
Text(recordingStatus)
}
}
.navigationBarTitle("Calling Quickstart")
}.onAppear {
// Initialize call agent
var userCredential: CommunicationTokenCredential?
do {
userCredential = try CommunicationTokenCredential(token: "<USER ACCESS TOKEN>")
} catch {
print("ERROR: It was not possible to create user credential.")
self.message = "Please enter your token in source code"
return
}
self.callClient = CallClient()
// Creates the call agent
self.callClient?.createCallAgent(userCredential: userCredential!) { (agent, error) in
if error != nil {
self.message = "Failed to create CallAgent."
return
} else {
self.callAgent = agent
self.message = "Call agent successfully created."
}
}
}
}
func joinTeamsMeeting() {
// Ask permissions
AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
if granted {
let joinCallOptions = JoinCallOptions()
let teamsMeetingLinkLocator = TeamsMeetingLinkLocator(meetingLink: self.meetingLink)
self.callAgent?.join(with: teamsMeetingLinkLocator, joinCallOptions: joinCallOptions) {(call, error) in
if (error == nil) {
self.call = call
self.callObserver = CallObserver(self)
self.call!.delegate = self.callObserver
self.message = "Teams meeting joined successfully"
} else {
print("Failed to get call object")
return
}
}
}
}
}
func leaveMeeting() {
if let call = call {
call.hangUp(options: nil, completionHandler: { (error) in
if error == nil {
self.message = "Leaving Teams meeting was successful"
} else {
self.message = "Leaving Teams meeting failed"
}
})
} else {
self.message = "No active call to hangup"
}
}
}
class CallObserver : NSObject, CallDelegate {
private var owner:ContentView
init(_ view:ContentView) {
owner = view
}
public func call(_ call: Call, didChangeState args: PropertyChangedEventArgs) {
owner.callStatus = CallObserver.callStateToString(state: call.state)
if call.state == .disconnected {
owner.call = nil
owner.message = "Left Meeting"
} else if call.state == .inLobby {
owner.message = "Waiting in lobby !!"
} else if call.state == .connected {
owner.message = "Joined Meeting !!"
}
}
public func call(_ call: Call, didChangeRecordingState args: PropertyChangedEventArgs) {
if (call.isRecordingActive == true) {
owner.recordingStatus = "This call is being recorded"
}
else {
owner.recordingStatus = ""
}
}
private static func callStateToString(state: CallState) -> String {
switch state {
case .connected: return "Connected"
case .connecting: return "Connecting"
case .disconnected: return "Disconnected"
case .disconnecting: return "Disconnecting"
case .earlyMedia: return "EarlyMedia"
case .none: return "None"
case .ringing: return "Ringing"
case .inLobby: return "InLobby"
default: return "Unknown"
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Hämta länken Teams möte
Den Teams möteslänken kan hämtas med hjälp av Graph-API:er. Detta beskrivs i Graph dokumentationen.
SDK:Communication Services anropar accepterar en fullständig Teams möteslänk. Den här länken returneras som en del onlineMeeting av resursen och är tillgänglig under joinWebUrl egenskapen. Du kan också hämta nödvändig mötesinformation från URL:en för kopplingsmöte i Teams själva inbjudan.
Starta appen och gå Teams möte
Du kan skapa och köra appen i iOS-simulatorn genom att välja Produktkörning eller med > hjälp av kortkommandot (⌘-R).
Infoga Teams kontext i textrutan och tryck på Delta Teams Möte för att delta i Teams möte inifrån ditt Communication Services program.
Funktioner som beskrivs i det här dokumentet använder den allmänt tillgängliga versionen av Communication Services-SDK:er. Teams Interoperability kräver betaversionen av Communication Services-SDK:er. Du kan utforska Beta-SDK:erna på sidan med versionsanteckningar.
När du kör steget "Installera paket" med Beta-SDK:er ändrar du versionen av paketet till den senaste betaversionen genom att ange version (version när du skriver den här artikeln) i @1.0.0-beta.10 communication-calling paketnamnet. Du behöver inte ändra communication-common paketkommandot. Exempel:
npm install @azure/communication-calling@1.0.0-beta.10 --save
Rensa resurser
Om du vill rensa och ta bort en Communication Services prenumeration kan du ta bort resursen eller resursgruppen. Om du tar bort resursgruppen tas även alla andra resurser som är associerade med den bort. Läs mer om att rensa resurser.
Nästa steg
Mer information finns i följande artiklar:
- Kolla in vårt exempel på anropande hero
- Lär dig mer om att anropa SDK-funktioner
- Läs mer om hur anrop fungerar