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

如何通过通话自动化控制通话过程中的媒体操作

通话自动化使用 REST API 接口来接收操作请求,并提供响应以告知请求是否已成功提交。 由于通话的异步性,大多数操作将在操作成功完成或失败时触发相应的事件。 本指南介绍在通话期间可供开发人员执行的操作,例如发送 DTMF 和连续 DTMF 识别。 操作随附有关如何调用上述操作的示例代码。

通话自动化支持使用其他各种操作来管理本指南中未提到的通话和录音。

注意

通话自动化目前不能与 Microsoft Teams 互操作。 不支持使用通话自动化呼叫 Teams 用户,向其重定向通话或向 Teams 用户播放音频等操作。

作为先决条件,建议你先阅读以下文章以充分理解本指南:

  1. 介绍操作事件编程模型和事件回调的通话自动化概念指南
  2. 了解本指南中使用的用户标识符,例如 CommunicationUserIdentifier 和 PhoneNumberIdentifier。
  3. 详细了解如何通过通话自动化控制和引导通话,这将教会你处理通话的基本知识。

对于所有代码示例,client 是可以按示例所示创建的 CallAutomationClient 对象,callConnection 是从 Answer 或 CreateCall 响应中获取的 CallConnection 对象。 也可以从应用程序收到的回调事件中获取该对象。

var callAutomationClient = new CallAutomationClient("<Azure Communication Services connection string>");

发送 DTMF

可将 DTMF 音调发送给外部参与者,当你已经在通话且需要邀请另一个拥有分机号码或 IVR 导航菜单的参与者时,这可能很有用。

注意

此功能仅支持外部 PSTN 参与者,且此功能支持一次发送最多 18 个音调。

SendDtmfAsync 方法

向外部参与者发送 DTMF 音调列表。

var tones = new DtmfTone[] { DtmfTone.One, DtmfTone.Two, DtmfTone.Three, DtmfTone.Pound }; 
var sendDtmfTonesOptions = new SendDtmfTonesOptions(tones, new PhoneNumberIdentifier(calleePhonenumber))
{ 
	OperationContext = "dtmfs-to-ivr" 
}; 

var sendDtmfAsyncResult = await callAutomationClient.GetCallConnection(callConnectionId) 
	.GetCallMedia() 
        .SendDtmfTonesAsync(sendDtmfTonesOptions); 

当应用程序发送这些 DTMF 音调时,你会收到事件更新。 可使用 SendDtmfTonesCompletedSendDtmfTonesFailed 事件在应用程序中创建业务逻辑,以确定后续步骤。

SendDtmfTonesCompleted 事件的示例

if (acsEvent is SendDtmfTonesCompleted sendDtmfCompleted) 
{ 
    logger.LogInformation("Send DTMF succeeded, context={context}", sendDtmfCompleted.OperationContext); 
} 

SendDtmfTonesFailed 的示例

if (acsEvent is SendDtmfTonesFailed sendDtmfFailed) 
{ 
    logger.LogInformation("Send dtmf failed: result={result}, context={context}", 
        sendDtmfFailed.ResultInformation?.Message, sendDtmfFailed.OperationContext); 
} 

连续 DTMF 识别

可在整个通话中订阅接收连续 DTMF 音调。 当目标参与者按下键盘上的某个键时,应用程序会收到 DTMF 音调。 当参与者按下这些音调时,它们会一个接一个地发送到应用程序。

StartContinuousDtmfRecognitionAsync 方法

开始检测参与者发送的 DTMF 音调。

await callAutomationClient.GetCallConnection(callConnectionId) 
    .GetCallMedia() 
    .StartContinuousDtmfRecognitionAsync(new PhoneNumberIdentifier(c2Target), "dtmf-reco-on-c2"); 

当应用程序不再希望从参与者处接收 DTMF 音调时,可使用 StopContinuousDtmfRecognitionAsync 方法让 Azure 通信服务知道停止检测 DTMF 音调。

StopContinuousDtmfRecognitionAsync

停止检测参与者发送的 DTMF 音调。

var continuousDtmfRecognitionOptions = new ContinuousDtmfRecognitionOptions(new PhoneNumberIdentifier(callerPhonenumber)) 
{ 
    OperationContext = "dtmf-reco-on-c2" 
}; 

var startContinuousDtmfRecognitionAsyncResult = await callAutomationClient.GetCallConnection(callConnectionId) 
    .GetCallMedia() 
    .StartContinuousDtmfRecognitionAsync(continuousDtmfRecognitionOptions); 

当这些操作成功或失败时,应用程序会收到事件更新。 可使用这些事件来生成自定义业务逻辑,以配置应用程序在收到这些事件更新时需要执行的下一步骤。

ContinuousDtmfRecognitionToneReceived 事件

如何处理成功检测到的 DTMF 音调的示例。

if (acsEvent is ContinuousDtmfRecognitionToneReceived continuousDtmfRecognitionToneReceived) 
{ 
	logger.LogInformation("Tone detected: sequenceId={sequenceId}, tone={tone}", 
	continuousDtmfRecognitionToneReceived.SequenceId, 
        continuousDtmfRecognitionToneReceived.Tone); 
} 

Azure 通信服务提供 SequenceId 作为 ContinuousDtmfRecognitionToneReceived 事件的一部分,而应用程序可使用它重构参与者输入 DTMF 音调的顺序。

ContinuousDtmfRecognitionFailed 事件

如何在 DTMF 音调检测失败时进行处理的示例。

if (acsEvent is ContinuousDtmfRecognitionToneFailed continuousDtmfRecognitionToneFailed) 
{ 
    logger.LogInformation("Start continuous DTMF recognition failed, result={result}, context={context}", 
        continuousDtmfRecognitionToneFailed.ResultInformation?.Message, 
        continuousDtmfRecognitionToneFailed.OperationContext); 
} 

ContinuousDtmfRecogntionStopped 事件

如何在连续 DTMF 识别停止(这可能是因为应用程序调用了 StopContinuousDtmfRecognitionAsync 事件或通话已结束)时进行处理的示例。

if (acsEvent is ContinuousDtmfRecognitionStopped continuousDtmfRecognitionStopped) 
{ 
    logger.LogInformation("Continuous DTMF recognition stopped, context={context}", continuousDtmfRecognitionStopped.OperationContext); 
} 

Hold

通过“保持”操作,开发人员可暂时暂停参与者与系统或代理之间的对话。 这在以下情况下很有用:参与者需要被转接至另一个代理或部门,或者代理需要在后台咨询主管才能继续对话。 在此期间,可选择向处于保持状态的参与者播放音频。

// Option 1: Hold without additional options
await callAutomationClient.GetCallConnection(callConnectionId)
    .GetCallMedia().HoldAsync(c2Target);

/*
// Option 2: Hold with play source
PlaySource playSource = /* initialize playSource */;
await callAutomationClient.GetCallConnection(callConnectionId)
    .GetCallMedia().HoldAsync(c2Target, playSource);

// Option 3: Hold with options
var holdOptions = new HoldOptions(target) 
{ 
    OperationCallbackUri = new Uri(""),
    OperationContext = "holdcontext"
};
await callMedia.HoldAsync(holdOptions);
*/

取消保持

通过“取消保持”操作,开发人员可恢复之前暂停的参与者与系统或代理之间的对话。 当参与者被取消保持后,他们将能够再次听到系统或代理的声音。

var unHoldOptions = new UnholdOptions(target) 
{ 
    OperationContext = "UnHoldPstnParticipant" 
}; 

// Option 1
var UnHoldParticipant = await callMedia.UnholdAsync(unHoldOptions);

/* 
// Option 2
var UnHoldParticipant = await callMedia.UnholdAsync(target);
*/

音频流式处理(公共预览版)

使用音频流式处理可以订阅正在进行的通话的实时音频流。 有关如何开始使用音频流式处理的更详细指南以及有关音频流式处理回调事件的信息,请参阅本页

实时听录(公共预览版)

使用实时听录可以访问正在进行的通话的音频的实时听录。 有关如何开始使用实时听录的更详细指南以及有关实时听录回调事件的信息,请参阅本页

媒体操作兼容性表

下表说明了在前一个操作仍在运行/排队时允许哪些媒体操作运行/排队。

现有操作 通话支线 允许 已禁止
PlayToAll 主要 PlayToAll、Recognize(Non-Group Call)、PlayTo、Recognize(Group Call)、SendDTMF、StartContinuousDtmfRecognition
Recognize(Non-Group Call) 主要 PlayToAll、Recognize(Non-Group Call)、PlayTo、Recognize(Group Call)、SendDTMF、StartContinuousDtmfRecognition
PlayTo Sub PlayToAll、Recognize(Non-Group Call) PlayTo、Recognize(Group Call)、SendDTMF、StartContinuousDtmfRecognition
Recognize(Group Call) Sub PlayToAll、Recognize(Non-Group Call) PlayTo、Recognize(Group Call)、SendDTMF、StartContinuousDtmfRecognition
SendDTMF Sub PlayToAll、Recognize(Non-Group Call) PlayTo、Recognize(Group Call)、SendDTMF、StartContinuousDtmfRecognition
StartContinuousDtmfRecognition Sub PlayToAll、Recognize(Non-Group Call)、PlayTo、Recognize(Group Call)、SendDTMF、StartContinuousDtmfRecognition