你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

在客户端上显示通话听录状态

需要征得所有通话参与者的同意才能听录。 Microsoft Teams 允许用户在会议或通话中开始听录。 听录开始后,你将收到事件通知。 如果在你加入通话或会议之前听录已开始,你可以检查听录状态。 如果会议或通话需要听录同意且你已收集相关同意,你可以提供明确的听录同意。

先决条件

支持

下表定义了 Azure 通信服务中对通话听录的支持。

标识和通话类型

下表显示了特定通话类型和标识的听录支持。

标识 Teams 会议 房间 1 对 1 通话 组呼叫 1:1 Teams 互操作通话 小组 Teams 互操作通话
通信服务用户 ✔️ ✔️ ✔️
Microsoft 365 用户 ✔️ ✔️ ✔️

Operations

下表显示了通话 SDK 中各个 API 对各种标识类型的支持。

Operations 通信服务用户 Microsoft 365 用户
获取“听录已开始”事件 ✔️ ✔️
获取听录状态 ✔️ ✔️
开始或停止听录
了解是否需要显式同意 ✔️[1] ✔️[1]
提供听录显式同意 ✔️[1] ✔️[1]

[1] 此功能仅在 Teams 会议和组 Teams 互操作性通话中可用。

SDK

下表显示了各个 Azure 通信服务 SDK 中的听录支持。

平台 Web Web UI iOS iOS UI Android Android UI Windows
支持 ✔️ ✔️[1] ✔️[1] ✔️[1] ✔️[1] ✔️[1] ✔️[1]

[1] 这些 SDK 不支持显式同意。

安装 SDK

使用 npm install 命令安装适用于 JavaScript 的 Azure 通信服务通用 SDK 和通话 SDK:

npm install @azure/communication-common --save
npm install @azure/communication-calling --save

初始化所需的对象

大多数通话操作需要 CallClient 实例。 创建新的 CallClient 实例时,可以使用自定义选项(如 Logger 实例)对其进行配置。

有了 CallClient 实例后,可以通过调用 createCallAgent 创建 CallAgent 实例。 此方法将异步返回 CallAgent 实例对象。

createCallAgent 方法使用 CommunicationTokenCredential 作为参数。 它接受用户访问令牌

可在 CallClient 实例上使用 getDeviceManager 方法来访问 deviceManager

const { CallClient } = require('@azure/communication-calling');
const { AzureCommunicationTokenCredential} = require('@azure/communication-common');
const { AzureLogger, setLogLevel } = require("@azure/logger");

// Set the logger's log level
setLogLevel('verbose');

// Redirect log output to console, file, buffer, REST API, or whatever location you want
AzureLogger.log = (...args) => {
    console.log(...args); // Redirect log output to console
};

const userToken = '<USER_TOKEN>';
callClient = new CallClient(options);
const tokenCredential = new AzureCommunicationTokenCredential(userToken);
const callAgent = await callClient.createCallAgent(tokenCredential, {displayName: 'optional Azure Communication Services user name'});
const deviceManager = await callClient.getDeviceManager()

如何最好地管理 SDK 与 Microsoft 基础结构的连接性

Call Agent 实例可帮助你管理通话(以加入或启动通话)。 通话 SDK 需要连接到 Microsoft 基础结构以获取传入通话通知并协调其他通话详细信息,否则无法工作。 你的 Call Agent 有两种可能的状态:

已连接 - Call Agent connectionStatue 值为 Connected 表示客户端 SDK 已连接,能够接收来自 Microsoft 基础结构的通知。

已断开连接 - Call Agent connectionStatue 值为 Disconnected 表示存在阻止 SDK 正确连接的问题。 应重新创建 Call Agent

  • invalidToken:如果令牌已过期或无效,Call Agent 实例会断开连接并出现此错误。
  • connectionIssue:如果客户端连接到 Microsoft 基础结构时出现问题,则在多次重试后,Call Agent 会显示 connectionIssue 错误。

可以通过检查 connectionState 属性的当前值来检查本地 Call Agent 是否已连接到 Microsoft 基础结构。 在通话过程中,可以侦听 connectionStateChanged 事件,以确定 Call Agent 是否从“已连接”状态更改为“已断开连接”状态。

const connectionState = callAgentInstance.connectionState;
console.log(connectionState); // it may return either of 'Connected' | 'Disconnected'

const connectionStateCallback = (args) => {
    console.log(args); // it will return an object with oldState and newState, each of having a value of either of 'Connected' | 'Disconnected'
    // it will also return reason, either of 'invalidToken' | 'connectionIssue'
}
callAgentInstance.on('connectionStateChanged', connectionStateCallback);

警告

由于 Microsoft Teams 中的更改,版本 1.21 及更低版本中的 JavaScript 通话 SDK 会停止 Teams 听录,并阻止 Teams 用户开始听录。 如果你要在通话和会议中利用 Teams 听录,则需要将通话 SDK 至少升级到 1.22 版。

通话听录

Transcription 是类 Call 的扩展功能。 首先需要获取听录功能 API 对象

const callTranscriptionFeature = call.feature(Features.Transcription);

可以在属性 isTranscriptionActive 中检查听录状态。 如果值设置为 true,则听录处于活动状态。

const isTranscriptionActive = callTranscriptionFeature.isTranscriptionActive;

可以订阅当听录状态发生更改时触发的事件:

const isTranscriptionActiveChangedHandler = () => {
  console.log(callTranscriptionFeature.isTranscriptionActive);
};
callTranscriptionFeature.on('isTranscriptionActiveChanged', isTranscriptionActiveChangedHandler);

可以使用以下代码取消订阅该事件:

callTranscriptionFeature.off('isTranscriptionActiveChanged', isTranscriptionActiveChangedHandler);

当 Teams 会议或通话被配置为需要显式同意才能进行录制或听录时,你需要从用户处获取显式同意,以允许对用户进行听录或录制。 你可以在加入会议时主动提供同意,也可以在录制或听录开始时被动地提供同意。 在获得显式同意之前,参与者的音频、视频和屏幕共享将在听录过程中被禁用。

你可以通过属性 isTeamsConsentRequired 检查会议听录是否需要显式同意。 如果该值设置为 true,则 call 需要显式同意。

const isTranscriptionConsentRequired = callTranscriptionFeature.isTeamsConsentRequired;

如果已获得用户的听录同意,可以调用 grantTeamsConsent() 方法来指示对服务的显式同意。 此同意仅适用于一个 call 会话,如果用户重新加入会议,则需要再次提供同意。

callTranscriptionFeature.grantTeamsConsent();

当听录处于活动状态且尚未获得显式同意时,启用音频、视频或屏幕共享的尝试将失败。 可以通过检查类 ParticipantCapabilities 的属性 reason功能 turnVideoOnunmuteMicshareScreen 来识别这种情况。 可以在功能 call.feature(Features.Capabilities) 中找到这些功能。 这些功能将返回用户需要提供显式同意的原因 ExplicitConsentRequired

安装 SDK

找到项目级 build.gradle 文件,并将 mavenCentral() 添加到 buildscriptallprojects 下的存储库列表中:

buildscript {
    repositories {
    ...
        mavenCentral()
    ...
    }
}
allprojects {
    repositories {
    ...
        mavenCentral()
    ...
    }
}

然后,在模块级 build.gradle 文件中,将以下行添加到 dependencies 部分:

dependencies {
    ...
    implementation 'com.azure.android:azure-communication-calling:1.0.0'
    ...
}

初始化所需的对象

若要创建 CallAgent 实例,必须对 CallClient 实例调用 createCallAgent 方法。 此调用将异步返回 CallAgent 实例对象。

createCallAgent 方法采用 CommunicationUserCredential 作为参数来封装访问令牌

若要访问 DeviceManager,必须先创建 callAgent 实例。 然后,可以使用 CallClient.getDeviceManager 方法获取 DeviceManager

String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an activity, for instance
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential).get();
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();

若要为主叫方设置显示名称,请使用以下替代方法:

String userToken = '<user token>';
CallClient callClient = new CallClient();
CommunicationTokenCredential tokenCredential = new CommunicationTokenCredential(userToken);
android.content.Context appContext = this.getApplicationContext(); // From within an activity, for instance
CallAgentOptions callAgentOptions = new CallAgentOptions();
callAgentOptions.setDisplayName("Alice Bob");
DeviceManager deviceManager = callClient.getDeviceManager(appContext).get();
CallAgent callAgent = callClient.createCallAgent(appContext, tokenCredential, callAgentOptions).get();

警告

在 Azure 通信服务呼叫 Android SDK 的 1.1.0 版和 beta 版 1.1.0-beta.1 之前,isTranscriptionActiveaddOnIsTranscriptionActiveChangedListenerCall 对象的一部分。 对于新的 Beta 版本,这些 API 已作为 Call 的扩展功能移动,如下所述。

通话听录是核心 Call 对象的扩展功能。 首先,需要获取听录功能对象:

TranscriptionCallFeature callTranscriptionFeature = call.feature(Features.TRANSCRIPTION);

然后,若要检查是否正在停录通话,请检查 callTranscriptionFeatureisTranscriptionActive 属性。 它将返回 boolean

boolean isTranscriptionActive = callTranscriptionFeature.isTranscriptionActive();

还可以订阅听录中的更改:

private void handleCallOnIsTranscriptionChanged(PropertyChangedEvent args) {
    boolean isTranscriptionActive = callTranscriptionFeature.isTranscriptionActive();
}

callTranscriptionFeature.addOnIsTranscriptionActiveChangedListener(handleCallOnIsTranscriptionChanged);

设置系统

按照以下步骤设置系统。

创建 Xcode 项目

在 Xcode 中,创建新的 iOS 项目,并选择“单视图应用”模板。 本文使用 SwiftUI 框架,因此应将“语言”设置为“Swift”,并将“界面”设置为“SwiftUI”

在本文中,无需创建测试。 请随意清除“包括测试”复选框

显示用于在 Xcode 中创建项目的窗口的屏幕截图。

使用 CocoaPods 安装包和依赖项

  1. 为应用程序创建 Podfile,如此示例所示:

    platform :ios, '13.0'
    use_frameworks!
    target 'AzureCommunicationCallingSample' do
        pod 'AzureCommunicationCalling', '~> 1.0.0'
    end
    
  2. 运行 pod install

  3. 使用 Xcode 打开 .xcworkspace

请求访问麦克风

若要访问设备的麦克风,需要使用 NSMicrophoneUsageDescription 更新应用的信息属性列表。 将关联的值设置为一个字符串,该字符串将包含在系统用于向用户请求访问权限的对话框中。

右键单击项目树的 Info.plist 条目,然后选择“打开为...”>“源代码”。 将以下代码行添加到顶层 <dict> 节,然后保存文件。

<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for VOIP calling.</string>

设置应用框架

打开项目的 ContentView.swift 文件。 将 import 声明添加到文件顶部以导入 AzureCommunicationCalling 库。 此外,导入 AVFoundation。 你需要用它来处理代码中的音频权限请求。

import AzureCommunicationCalling
import AVFoundation

初始化 CallAgent

若要从 CallClient 创建 CallAgent 实例,必须使用 callClient.createCallAgent 方法,该方法在初始化后异步返回 CallAgent 对象。

若要创建通话客户端,请传递 CommunicationTokenCredential 对象:

import AzureCommunication

let tokenString = "token_string"
var userCredential: CommunicationTokenCredential?
do {
    let options = CommunicationTokenRefreshOptions(initialToken: token, refreshProactively: true, tokenRefresher: self.fetchTokenSync)
    userCredential = try CommunicationTokenCredential(withOptions: options)
} catch {
    updates("Couldn't created Credential object", false)
    initializationDispatchGroup!.leave()
    return
}

// tokenProvider needs to be implemented by Contoso, which fetches a new token
public func fetchTokenSync(then onCompletion: TokenRefreshOnCompletion) {
    let newToken = self.tokenProvider!.fetchNewToken()
    onCompletion(newToken, nil)
}

将创建的 CommunicationTokenCredential 对象传递给 CallClient 并设置显示名称:

self.callClient = CallClient()
let callAgentOptions = CallAgentOptions()
options.displayName = " iOS Azure Communication Services User"

self.callClient!.createCallAgent(userCredential: userCredential!,
    options: callAgentOptions) { (callAgent, error) in
        if error == nil {
            print("Create agent succeeded")
            self.callAgent = callAgent
        } else {
            print("Create agent failed")
        }
})

警告

1.1.0 和 1.1.0-beta.1(beta 版)之前版本的 Azure 通信服务呼叫 iOS SDK 使用 isTranscriptionActive 作为 Call 对象的一部分,并且 didChangeTranscriptionState 属于 CallDelegate 委托的一部分。 对于新的 Beta 版本,这些 API 已作为 Call 的扩展功能移动,如下所述。

通话听录是核心 Call 对象的扩展功能。 首先,需要获取听录功能对象:

let callTranscriptionFeature = call.feature(Features.transcription)

然后,若要确认是否正在听录通话,请检查 callTranscriptionFeatureisTranscriptionActive 属性。 它将返回 Bool

let isTranscriptionActive = callTranscriptionFeature.isTranscriptionActive;

还可以通过使用事件 TranscriptionCallFeatureDelegate 在类层级实现 didChangeTranscriptionState 委托,以订阅听录更改:

callTranscriptionFeature.delegate = self

// didChangeTranscriptionState is a member of TranscriptionCallFeatureDelegate
public func transcriptionCallFeature(_ transcriptionCallFeature: TranscriptionCallFeature, didChangeTranscriptionState args: PropertyChangedEventArgs) {
    let isTranscriptionActive = callTranscriptionFeature.isTranscriptionActive
}

设置系统

按照以下步骤设置系统。

创建 Visual Studio 项目

对于通用 Windows 平台应用,请在 Visual Studio 2022 中创建新的“空白应用(通用 Windows)”项目。 输入项目名称后,可随意选择任何版本高于 10.0.17763.0 的 Windows SDK。

对于 WinUI 3 应用,请使用“已打包空白应用(桌面中的 WinUI 3)”模板创建新项目,以设置单页 WinUI 3 应用。 需要 Windows App SDK 版本 1.3 或更高版本。

使用 NuGet 包管理器安装包和依赖项

可通过 NuGet 包公开提供通话 SDK API 和库。

要查找、下载和安装通话 SDK NuGet 包,请执行以下操作:

  1. 选择“工具”>“NuGet 包管理器”>“管理解决方案的 NuGet 包”,以打开 NuGet 包管理器
  2. 选择“浏览”,然后在搜索框中输入 Azure.Communication.Calling.WindowsClient
  3. 确保已选中“包括预发行版”复选框
  4. 选择 Azure.Communication.Calling.WindowsClient 包,然后选择 Azure.Communication.Calling.WindowsClient 1.4.0-beta.1 或更新版本。
  5. 在右侧窗格中选中与 Azure 通信服务项目对应的复选框。
  6. 选择“安装” 。

通话听录是核心 Call 对象的扩展功能。 首先,需要获取听录功能对象:

TranscriptionCallFeature transcriptionFeature = call.Features.Transcription;

然后,若要检查是否正在停录通话,请检查 transcriptionFeatureIsTranscriptionActive 属性。 它将返回 boolean

boolean isTranscriptionActive = transcriptionFeature.isTranscriptionActive;

还可以订阅听录中的更改:

private async void Call__OnIsTranscriptionActiveChanged(object sender, PropertyChangedEventArgs args)
    boolean isTranscriptionActive = transcriptionFeature.IsTranscriptionActive();
}

transcriptionFeature.IsTranscriptionActiveChanged += Call__OnIsTranscriptionActiveChanged;

后续步骤