你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
本指南帮助你了解如何通过 Azure 通信服务通话自动化 SDK 来开始识别参与者提供的 DTMF 输入。
Prerequisites
- 具有有效订阅的 Azure 帐户,有关详细信息,请参阅免费创建帐户。
- Azure 通信服务资源。 请参阅创建 Azure 通信服务资源。 请注意此资源的连接字符串。
- 使用通话自动化 SDK 创建新的 Web 服务应用程序。
- 适用于操作系统的最新 .NET 库。
- 最新的 NuGet 包。
对于 AI 功能
- 创建 Azure AI 服务并将其连接到 Azure 通信服务资源。
- 为 Azure AI 服务资源创建自定义子域。
技术规范
以下参数可用于自定义 Recognize 函数:
| 参数 | 类型 | 默认值(如果未指定) | 说明 | 必需还是可选 |
|---|---|---|---|---|
Prompt (有关详细信息,请参阅使用播放操作为用户自定义语音提示) |
FileSource、TextSource | 未设置 | 在识别输入之前要播放的消息。 | 可选 |
InterToneTimeout |
TimeSpan | 2 秒 最小值:1 秒 最大值:60 秒 |
Azure 通信服务等待呼叫者按另一个数字的秒数限制(数字间超时)。 | 可选 |
InitialSegmentationSilenceTimeoutInSeconds |
Integer | 0.5 秒 | 识别操作在考虑超时之前将等待输入多长时间。 请参阅如何识别语音。 | 可选 |
RecognizeInputsType |
枚举 | dtmf | 识别的输入的类型。 选项包括 dtmf、choices、speech 和 speechordtmf。 |
必选 |
InitialSilenceTimeout |
TimeSpan | 5 秒 最小值:0 秒 最大值:300 秒 (DTMF) 最大值:20 秒 (Choices) 最大值:20 秒 (Speech) |
“初始静音超时”用于调整在识别尝试以“无匹配项”结果结束前,短语前允许的非语音音频量。 请参阅如何识别语音。 | 可选 |
MaxTonesToCollect |
Integer | 无默认值 最小值:1 |
开发人员期望参与者输入的位数。 | 必需 |
StopTones |
IEnumeration<DtmfTone> | 未设置 | 数字参与者可以按压以退出批量 DTMF 事件。 | 可选 |
InterruptPrompt |
布尔值 | True | 如果参与者能够通过按一个数字来中断 playMessage。 | 可选 |
InterruptCallMediaOperation |
布尔值 | True | 如果设置此标志,则会中断当前的调用媒体操作。 例如,如果正在播放任何音频,它会中断该操作并启动识别。 | 可选 |
OperationContext |
字符串 | 未设置 | 开发人员可以传递 mid 操作的字符串,用于允许开发人员存储有关他们收到的事件的上下文。 | 可选 |
Phrases |
字符串 | 未设置 | 与标签关联的短语列表。 听到其中任何一个短语都表示成功识别。 | 必选 |
Tone |
字符串 | 未设置 | 用户决定按下数字而不是使用语音时,要识别的音调。 | 可选 |
Label |
字符串 | 未设置 | 用于识别的关键值。 | 必选 |
Language |
字符串 | En-us | 用于识别语音的语言。 | 可选 |
EndSilenceTimeout |
TimeSpan | 0.5 秒 | 用于检测生成为语音的最终结果的说话人的最后一次暂停。 | 可选 |
注意
如果 DTMF 和语音都在 recognizeInputsType 中,则识别操作将作用于收到的第一个输入类型。 例如,如果用户首先按下小键盘上的数字,则识别操作会将其视为 DTMF 事件并继续侦听 DTMF 音调。 如果用户先说话,则识别操作会将其视为语音识别事件并侦听语音输入。
新建 C# 应用程序
在操作系统的控制台窗口中,使用 dotnet 命令创建新的 Web 应用程序。
dotnet new web -n MyApplication
安装 NuGet 包
从 NuGet 库 | Azure.Communication.CallAutomation 获取 NuGet 包。 按照说明安装相应的包。
建立呼叫
至此,你应已熟悉如何开始通话。 有关发起通话的详细信息,请参阅快速入门:发起传出通话。 还可以使用此处提供的代码片段来了解如何应答呼叫。
var callAutomationClient = new CallAutomationClient("<Azure Communication Services connection string>");
var answerCallOptions = new AnswerCallOptions("<Incoming call context once call is connected>", new Uri("<https://sample-callback-uri>"))
{
CallIntelligenceOptions = new CallIntelligenceOptions() { CognitiveServicesEndpoint = new Uri("<Azure Cognitive Services Endpoint>") }
};
var answerCallResult = await callAutomationClient.AnswerCallAsync(answerCallOptions);
调用识别动作
在你的应用程序应答呼叫时,你可以提供有关识别参与者输入和播放提示的信息。
DTMF
var maxTonesToCollect = 3;
String textToPlay = "Welcome to Contoso, please enter 3 DTMF.";
var playSource = new TextSource(textToPlay, "en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeDtmfOptions(targetParticipant, maxTonesToCollect) {
InitialSilenceTimeout = TimeSpan.FromSeconds(30),
Prompt = playSource,
InterToneTimeout = TimeSpan.FromSeconds(5),
InterruptPrompt = true,
StopTones = new DtmfTone[] {
DtmfTone.Pound
},
};
var recognizeResult = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.StartRecognizingAsync(recognizeOptions);
对于语音转文本流,通话自动化识别操作还支持使用自定义语音识别模型。 在生成需要侦听默认语音转文本模型可能无法理解的复杂字词的应用程序时,自定义语音识别模型等功能可能非常有用。 例如,在为远程医疗行业生成应用程序,并且虚拟代理需要能够识别医疗术语时。 可以在创建自定义语音识别项目中了解详细信息。
语音转文本选择
var choices = new List < RecognitionChoice > {
new RecognitionChoice("Confirm", new List < string > {
"Confirm",
"First",
"One"
}) {
Tone = DtmfTone.One
},
new RecognitionChoice("Cancel", new List < string > {
"Cancel",
"Second",
"Two"
}) {
Tone = DtmfTone.Two
}
};
String textToPlay = "Hello, This is a reminder for your appointment at 2 PM, Say Confirm to confirm your appointment or Cancel to cancel the appointment. Thank you!";
var playSource = new TextSource(textToPlay, "en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeChoiceOptions(targetParticipant, choices) {
InterruptPrompt = true,
InitialSilenceTimeout = TimeSpan.FromSeconds(30),
Prompt = playSource,
OperationContext = "AppointmentReminderMenu",
SpeechLanguages = new List<string> { "en-US", "hi-IN", "fr-FR" },
//Only add the SpeechModelEndpointId if you have a custom speech model you would like to use
SpeechModelEndpointId = "YourCustomSpeechModelEndpointId"
};
var recognizeResult = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.StartRecognizingAsync(recognizeOptions);
语音转文本
String textToPlay = "Hi, how can I help you today?";
var playSource = new TextSource(textToPlay, "en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeSpeechOptions(targetParticipant) {
Prompt = playSource,
EndSilenceTimeout = TimeSpan.FromMilliseconds(1000),
OperationContext = "OpenQuestionSpeech",
//Only add the SpeechModelEndpointId if you have a custom speech model you would like to use
SpeechModelEndpointId = "YourCustomSpeechModelEndpointId"
};
var recognizeResult = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.StartRecognizingAsync(recognizeOptions);
语音转文本或 DTMF
var maxTonesToCollect = 1;
String textToPlay = "Hi, how can I help you today, you can press 0 to speak to an agent?";
var playSource = new TextSource(textToPlay, "en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeSpeechOrDtmfOptions(targetParticipant, maxTonesToCollect)
{
Prompt = playSource,
EndSilenceTimeout = TimeSpan.FromMilliseconds(1000),
InitialSilenceTimeout = TimeSpan.FromSeconds(30),
InterruptPrompt = true,
OperationContext = "OpenQuestionSpeechOrDtmf",
SpeechLanguages = new List<string> { "en-US", "hi-IN", "fr-FR" },
//Only add the SpeechModelEndpointId if you have a custom speech model you would like to use
SpeechModelEndpointId = "YourCustomSpeechModelEndpointId"
};
var recognizeResult = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.StartRecognizingAsync(recognizeOptions);
注意
如果未设置参数,将尽可能应用默认值。
实时语言识别(预览版)
借助额外的实时语言识别,开发人员可以自动检测口语,以启用自然的、类似于人类的通信,并消除最终用户的手动语言选择。
string textToPlay = "Hi, how can I help you today?";
var playSource = new TextSource(textToPlay, "en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeSpeechOptions(targetParticipant: new PhoneNumberIdentifier(targetParticipant))
{
Prompt = playSource,
InterruptCallMediaOperation = false,
InterruptPrompt = false,
InitialSilenceTimeout = TimeSpan.FromSeconds(10),
OperationContext = "OpenQuestionSpeech",
// Enable Language Identification
SpeechLanguages = new List<string> { "en-US", "hi-IN", "fr-FR" },
// Only add the SpeechModelEndpointId if you have a custom speech model you would like to use
SpeechModelEndpointId = "YourCustomSpeechModelEndpointId"
};
var recognizeResult = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.StartRecognizingAsync(recognizeOptions);
注意
语言支持限制
使用以语音作为输入类型的 Recognize API 时:
- 可以使用
setSpeechLanguages(...)指定最多 10 种语言。 - 请注意,使用更多语言可能会由于额外的处理而增加接收
RecognizeCompleted事件所需的时间。
将 Recognize API 与选项配合使用时:
- 最多支持 4 种语言。
- 在选项模式下指定的语言超过 4 种可能会导致错误或性能下降。
情绪分析(预览版)
识别 API 支持使用语音输入时进行的情绪分析。 实时跟踪对话的情感基调以支持客户和代理交互,并在必要时允许主管进行干预。 它还可用于路由、个性化或分析。
string textToPlay = "Hi, how can I help you today?";
var playSource = new TextSource(textToPlay, "en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeSpeechOptions(targetParticipant: new PhoneNumberIdentifier(targetParticipant))
{
Prompt = playSource,
InterruptCallMediaOperation = false,
InterruptPrompt = false,
InitialSilenceTimeout = TimeSpan.FromSeconds(10),
OperationContext = "OpenQuestionSpeech",
// Enable Sentiment Analysis
IsSentimentAnalysisEnabled = true
};
var recognizeResult = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.StartRecognizingAsync(recognizeOptions);
接收识别事件更新
开发人员可以订阅有关已注册 webhook 回调的 RecognizeCompleted 和 RecognizeFailed 事件。 在应用程序中将此回调与业务逻辑配合使用可以确定当其中一个事件发生时要采取的后续步骤。
如何反序列化 RecognizeCompleted 事件的示例:
if (parsedEvent is RecognizeCompleted recognizeCompleted)
{
logger.LogInformation($"Received call event: {recognizeCompleted.GetType()}");
callConnectionId = recognizeCompleted.CallConnectionId;
switch (recognizeCompleted.RecognizeResult)
{
case DtmfResult dtmfResult:
var tones = dtmfResult.Tones;
logger.LogInformation("Recognize completed successfully, tones={tones}", tones);
break;
case ChoiceResult choiceResult:
var labelDetected = choiceResult.Label;
var phraseDetected = choiceResult.RecognizedPhrase;
var sentimentAnalysis = choiceResult.SentimentAnalysisResult;
logger.LogInformation("Recognize completed successfully, labelDetected={labelDetected}, phraseDetected={phraseDetected}", labelDetected, phraseDetected);
logger.LogInformation("Language Identified: {language}", choiceResult.LanguageIdentified);
if (sentimentAnalysis != null)
{
logger.LogInformation("Sentiment: {sentiment}", sentimentAnalysis.Sentiment);
}
break;
case SpeechResult speechResult:
var text = speechResult.Speech;
var speechSentiment = speechResult.SentimentAnalysisResult;
logger.LogInformation("Recognize completed successfully, text={text}", text);
logger.LogInformation("Language Identified: {language}", speechResult.LanguageIdentified);
if (speechSentiment != null)
{
logger.LogInformation("Sentiment: {sentiment}", speechSentiment.Sentiment);
}
break;
default:
logger.LogInformation("Recognize completed successfully, recognizeResult={recognizeResult}", recognizeCompleted.RecognizeResult);
break;
}
}
如何反序列化 RecognizeFailed 事件的示例:
if (acsEvent is RecognizeFailed recognizeFailed)
{
if (MediaEventReasonCode.RecognizeInitialSilenceTimedOut.Equals(recognizeFailed.ReasonCode))
{
// Take action for time out
logger.LogInformation("Recognition failed: initial silence time out");
}
else if (MediaEventReasonCode.RecognizeSpeechOptionNotMatched.Equals(recognizeFailed.ReasonCode))
{
// Take action for option not matched
logger.LogInformation("Recognition failed: speech option not matched");
}
else if (MediaEventReasonCode.RecognizeIncorrectToneDetected.Equals(recognizeFailed.ReasonCode))
{
// Take action for incorrect tone
logger.LogInformation("Recognition failed: incorrect tone detected");
}
else
{
logger.LogInformation("Recognition failed, result={result}, context={context}", recognizeFailed.ResultInformation?.Message, recognizeFailed.OperationContext);
}
}
如何反序列化 RecognizeCanceled 事件的示例:
if (acsEvent is RecognizeCanceled { OperationContext: "AppointmentReminderMenu" })
{
logger.LogInformation($"RecognizeCanceled event received for call connection id: {@event.CallConnectionId}");
//Take action on recognize canceled operation
await callConnection.HangUpAsync(forEveryone: true);
}
Prerequisites
- 具有有效订阅的 Azure 帐户,有关详细信息,请参阅免费创建帐户。
- Azure 通信服务资源。 请参阅创建 Azure 通信服务资源
- 使用通话自动化 SDK 创建新的 Web 服务应用程序。
- Java 开发工具包版本 8 或更高版本。
- Apache Maven。
对于 AI 功能
- 创建 Azure AI 服务并将其连接到 Azure 通信服务资源。
- 为 Azure AI 服务资源创建自定义子域。
技术规范
以下参数可用于自定义 Recognize 函数:
| 参数 | 类型 | 默认值(如果未指定) | 说明 | 必需还是可选 |
|---|---|---|---|---|
Prompt (有关详细信息,请参阅使用播放操作为用户自定义语音提示) |
FileSource、TextSource | 未设置 | 在识别输入之前要播放的消息。 | 可选 |
InterToneTimeout |
TimeSpan | 2 秒 最小值:1 秒 最大值:60 秒 |
Azure 通信服务等待呼叫者按另一个数字的秒数限制(数字间超时)。 | 可选 |
InitialSegmentationSilenceTimeoutInSeconds |
Integer | 0.5 秒 | 识别操作在考虑超时之前将等待输入多长时间。 请参阅如何识别语音。 | 可选 |
RecognizeInputsType |
枚举 | dtmf | 识别的输入的类型。 选项包括 dtmf、choices、speech 和 speechordtmf。 |
必选 |
InitialSilenceTimeout |
TimeSpan | 5 秒 最小值:0 秒 最大值:300 秒 (DTMF) 最大值:20 秒 (Choices) 最大值:20 秒 (Speech) |
“初始静音超时”用于调整在识别尝试以“无匹配项”结果结束前,短语前允许的非语音音频量。 请参阅如何识别语音。 | 可选 |
MaxTonesToCollect |
Integer | 无默认值 最小值:1 |
开发人员期望参与者输入的位数。 | 必需 |
StopTones |
IEnumeration<DtmfTone> | 未设置 | 数字参与者可以按压以退出批量 DTMF 事件。 | 可选 |
InterruptPrompt |
布尔值 | True | 如果参与者能够通过按一个数字来中断 playMessage。 | 可选 |
InterruptCallMediaOperation |
布尔值 | True | 如果设置此标志,则会中断当前的调用媒体操作。 例如,如果正在播放任何音频,它会中断该操作并启动识别。 | 可选 |
OperationContext |
字符串 | 未设置 | 开发人员可以传递 mid 操作的字符串,用于允许开发人员存储有关他们收到的事件的上下文。 | 可选 |
Phrases |
字符串 | 未设置 | 与标签关联的短语列表。 听到其中任何一个短语都表示成功识别。 | 必选 |
Tone |
字符串 | 未设置 | 用户决定按下数字而不是使用语音时,要识别的音调。 | 可选 |
Label |
字符串 | 未设置 | 用于识别的关键值。 | 必选 |
Language |
字符串 | En-us | 用于识别语音的语言。 | 可选 |
EndSilenceTimeout |
TimeSpan | 0.5 秒 | 用于检测生成为语音的最终结果的说话人的最后一次暂停。 | 可选 |
注意
如果 DTMF 和语音都在 recognizeInputsType 中,则识别操作将作用于收到的第一个输入类型。 例如,如果用户首先按下小键盘上的数字,则识别操作会将其视为 DTMF 事件并继续侦听 DTMF 音调。 如果用户先说话,则识别操作会将其视为语音识别事件并侦听语音输入。
创建新的 Java 应用程序
在终端或命令窗口中,导航到要在其中创建 Java 应用程序的目录。 运行 mvn 命令以从 maven-archetype-quickstart 模板生成 Java 项目。
mvn archetype:generate -DgroupId=com.communication.quickstart -DartifactId=communication-quickstart -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
artifactId 命令将创建一个与 mvn 参数同名的目录。
src/main/java 目录包含项目源代码。
src/test/java 目录包含测试源。
请注意,generate 步骤创建了一个与 artifactId 同名的目录。
src/main/java 目录包含源代码。
src/test/java 目录包含测试。
pom.xml 文件是项目的项目对象模型 (POM)。
将应用程序的 POM 文件更新为使用 Java 8 或更高版本。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
添加包引用
在 POM 文件中,为项目添加以下引用:
azure-communication-callautomation
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-communication-callautomation</artifactId>
<version>1.0.0</version>
</dependency>
建立呼叫
至此,你应已熟悉如何开始通话。 有关发起通话的详细信息,请参阅快速入门:发起传出通话。 还可以使用此处提供的代码片段来了解如何应答呼叫。
CallIntelligenceOptions callIntelligenceOptions = new CallIntelligenceOptions().setCognitiveServicesEndpoint("https://sample-cognitive-service-resource.cognitiveservices.azure.com/");
answerCallOptions = new AnswerCallOptions("<Incoming call context>", "<https://sample-callback-uri>").setCallIntelligenceOptions(callIntelligenceOptions);
Response < AnswerCallResult > answerCallResult = callAutomationClient
.answerCallWithResponse(answerCallOptions)
.block();
调用识别动作
在你的应用程序应答呼叫时,你可以提供有关识别参与者输入和播放提示的信息。
DTMF
var maxTonesToCollect = 3;
String textToPlay = "Welcome to Contoso, please enter 3 DTMF.";
var playSource = new TextSource()
.setText(textToPlay)
.setVoiceName("en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeDtmfOptions(targetParticipant, maxTonesToCollect)
.setInitialSilenceTimeout(Duration.ofSeconds(30))
.setPlayPrompt(playSource)
.setInterToneTimeout(Duration.ofSeconds(5))
.setInterruptPrompt(true)
.setStopTones(Arrays.asList(DtmfTone.POUND));
var recognizeResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.startRecognizingWithResponse(recognizeOptions)
.block();
log.info("Start recognizing result: " + recognizeResponse.getStatusCode());
对于语音转文本流,通话自动化识别操作还支持使用自定义语音识别模型。 在生成需要侦听默认语音转文本模型可能无法理解的复杂字词的应用程序时,自定义语音识别模型等功能可能非常有用。 例如,在为远程医疗行业生成应用程序,并且虚拟代理需要能够识别医疗术语时。 可以在创建自定义语音识别项目中了解详细信息。
语音转文本选择
var choices = Arrays.asList(
new RecognitionChoice()
.setLabel("Confirm")
.setPhrases(Arrays.asList("Confirm", "First", "One"))
.setTone(DtmfTone.ONE),
new RecognitionChoice()
.setLabel("Cancel")
.setPhrases(Arrays.asList("Cancel", "Second", "Two"))
.setTone(DtmfTone.TWO)
);
String textToPlay = "Hello, This is a reminder for your appointment at 2 PM, Say Confirm to confirm your appointment or Cancel to cancel the appointment. Thank you!";
var playSource = new TextSource()
.setText(textToPlay)
.setVoiceName("en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeChoiceOptions(targetParticipant, choices)
.setInterruptPrompt(true)
.setInitialSilenceTimeout(Duration.ofSeconds(30))
.setPlayPrompt(playSource)
.setSpeechLanguages("en-US", "es-ES", "hi-IN")
.setSentimentAnalysisEnabled(true)
.setOperationContext("AppointmentReminderMenu")
//Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
.setSpeechRecognitionModelEndpointId("YourCustomSpeechModelEndpointID");
var recognizeResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.startRecognizingWithResponse(recognizeOptions)
.block();
语音转文本
String textToPlay = "Hi, how can I help you today?";
var playSource = new TextSource()
.setText(textToPlay)
.setVoiceName("en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeSpeechOptions(targetParticipant, Duration.ofMillis(1000))
.setPlayPrompt(playSource)
.setOperationContext("OpenQuestionSpeech")
//Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
.setSpeechRecognitionModelEndpointId("YourCustomSpeechModelEndpointID");
var recognizeResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.startRecognizingWithResponse(recognizeOptions)
.block();
语音转文本或 DTMF
var maxTonesToCollect = 1;
String textToPlay = "Hi, how can I help you today, you can press 0 to speak to an agent?";
var playSource = new TextSource()
.setText(textToPlay)
.setVoiceName("en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeSpeechOrDtmfOptions(targetParticipant, maxTonesToCollect, Duration.ofMillis(1000))
.setPlayPrompt(playSource)
.setInitialSilenceTimeout(Duration.ofSeconds(30))
.setInterruptPrompt(true)
.setOperationContext("OpenQuestionSpeechOrDtmf")
//Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
.setSpeechRecognitionModelEndpointId("YourCustomSpeechModelEndpointID");
var recognizeResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.startRecognizingWithResponse(recognizeOptions)
.block();
注意
如果未设置参数,将尽可能应用默认值。
实时语言识别(预览版)
借助额外的实时语言识别,开发人员可以自动检测口语,以启用自然的、类似于人类的通信,并消除最终用户的手动语言选择。
String textToPlay = "Hi, how can I help you today?";
var playSource = new TextSource()
.setText(textToPlay)
.setVoiceName("en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeSpeechOptions(participant, Duration.ofSeconds(15))
.setPlayPrompt(playSource)
.setInterruptPrompt(false)
.setInitialSilenceTimeout(Duration.ofSeconds(15))
.setSentimentAnalysisEnabled(true)
.setSpeechLanguages("en-US", "es-ES", "hi-IN")
.setOperationContext("OpenQuestionSpeech")
// Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
.setSpeechRecognitionModelEndpointId("YourCustomSpeechModelEndpointID");
var recognizeResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.startRecognizingWithResponse(recognizeOptions)
.block();
注意
语言支持限制
使用以语音作为输入类型的 Recognize API 时:
- 可以使用
setSpeechLanguages(...)指定最多 10 种语言。 - 请注意,使用更多语言可能会由于额外的处理而增加接收
RecognizeCompleted事件所需的时间。
将 Recognize API 与选项配合使用时:
- 最多支持 4 种语言。
- 在选项模式下指定的语言超过 4 种可能会导致错误或性能下降。
情绪分析(预览版)
识别 API 支持使用语音输入时进行的情绪分析。 实时跟踪对话的情感基调以支持客户和代理交互,并在必要时允许主管进行干预。 它还可用于路由、个性化或分析。
String textToPlay = "Hi, how can I help you today?";
var playSource = new TextSource()
.setText(textToPlay)
.setVoiceName("en-US-ElizabethNeural");
var recognizeOptions = new CallMediaRecognizeSpeechOptions(participant, Duration.ofSeconds(15))
.setPlayPrompt(playSource)
.setInterruptPrompt(false)
.setInitialSilenceTimeout(Duration.ofSeconds(15))
.setSentimentAnalysisEnabled(true)
.setSpeechLanguages("en-US", "es-ES", "hi-IN")
.setOperationContext("SpeechContext");
var recognizeResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.startRecognizingWithResponse(recognizeOptions)
.block();
接收识别事件更新
开发人员可以订阅有关已注册 webhook 回调的 RecognizeCompleted 和 RecognizeFailed 事件。 在应用程序中将此回调与业务逻辑配合使用可以确定当其中一个事件发生时要采取的后续步骤。
如何反序列化 RecognizeCompleted 事件的示例:
if (acsEvent instanceof RecognizeCompleted) {
RecognizeCompleted event = (RecognizeCompleted) acsEvent;
RecognizeResult recognizeResult = event.getRecognizeResult().get();
if (recognizeResult instanceof DtmfResult) {
// Take action on collect tones
DtmfResult dtmfResult = (DtmfResult) recognizeResult;
List<DtmfTone> tones = dtmfResult.getTones();
log.info("Recognition completed, tones=" + tones + ", context=" + event.getOperationContext());
} else if (recognizeResult instanceof ChoiceResult) {
ChoiceResult collectChoiceResult = (ChoiceResult) recognizeResult;
String labelDetected = collectChoiceResult.getLabel();
String phraseDetected = collectChoiceResult.getRecognizedPhrase();
String languageIdentified = collectChoiceResult.getLanguageIdentified();
log.info("Recognition completed, labelDetected=" + labelDetected + ", phraseDetected=" + phraseDetected + ", context=" + event.getOperationContext());
log.info("Language Identified: " + languageIdentified);
if (choiceResult.getSentimentAnalysisResult() != null) {
log.info("Sentiment: " + choiceResult.getSentimentAnalysisResult().getSentiment());
}
} else if (recognizeResult instanceof SpeechResult) {
SpeechResult speechResult = (SpeechResult) recognizeResult;
String text = speechResult.getSpeech();
String languageIdentified = speechResult.getLanguageIdentified();
log.info("Recognition completed, text=" + text + ", context=" + event.getOperationContext());
log.info("Language Identified: " + languageIdentified);
if (speechResult.getSentimentAnalysisResult() != null) {
log.info("Sentiment: " + speechResult.getSentimentAnalysisResult().getSentiment());
}
} else {
log.info("Recognition completed, result=" + recognizeResult + ", context=" + event.getOperationContext());
}
}
如何反序列化 RecognizeFailed 事件的示例:
if (acsEvent instanceof RecognizeFailed) {
RecognizeFailed event = (RecognizeFailed) acsEvent;
if (ReasonCode.Recognize.INITIAL_SILENCE_TIMEOUT.equals(event.getReasonCode())) {
// Take action for time out
log.info("Recognition failed: initial silence time out");
} else if (ReasonCode.Recognize.SPEECH_OPTION_NOT_MATCHED.equals(event.getReasonCode())) {
// Take action for option not matched
log.info("Recognition failed: speech option not matched");
} else if (ReasonCode.Recognize.DMTF_OPTION_MATCHED.equals(event.getReasonCode())) {
// Take action for incorrect tone
log.info("Recognition failed: incorrect tone detected");
} else {
log.info("Recognition failed, result=" + event.getResultInformation().getMessage() + ", context=" + event.getOperationContext());
}
}
如何反序列化 RecognizeCanceled 事件的示例:
if (acsEvent instanceof RecognizeCanceled) {
RecognizeCanceled event = (RecognizeCanceled) acsEvent;
log.info("Recognition canceled, context=" + event.getOperationContext());
}
Prerequisites
- 具有有效订阅的 Azure 帐户。有关详细信息,请参阅免费创建帐户。
- Azure 通信服务资源。 请参阅创建 Azure 通信服务资源。 请注意此资源的连接字符串。
- 使用通话自动化 SDK 创建新的 Web 服务应用程序。
- 安装 Node.js,可以从其官方网站进行安装。
对于 AI 功能
- 创建 Azure AI 服务并将其连接到 Azure 通信服务资源。
- 为 Azure AI 服务资源创建自定义子域。
技术规范
以下参数可用于自定义 Recognize 函数:
| 参数 | 类型 | 默认值(如果未指定) | 说明 | 必需还是可选 |
|---|---|---|---|---|
Prompt (有关详细信息,请参阅使用播放操作为用户自定义语音提示) |
FileSource、TextSource | 未设置 | 在识别输入之前要播放的消息。 | 可选 |
InterToneTimeout |
TimeSpan | 2 秒 最小值:1 秒 最大值:60 秒 |
Azure 通信服务等待呼叫者按另一个数字的秒数限制(数字间超时)。 | 可选 |
InitialSegmentationSilenceTimeoutInSeconds |
Integer | 0.5 秒 | 识别操作在考虑超时之前将等待输入多长时间。 请参阅如何识别语音。 | 可选 |
RecognizeInputsType |
枚举 | dtmf | 识别的输入的类型。 选项包括 dtmf、choices、speech 和 speechordtmf。 |
必选 |
InitialSilenceTimeout |
TimeSpan | 5 秒 最小值:0 秒 最大值:300 秒 (DTMF) 最大值:20 秒 (Choices) 最大值:20 秒 (Speech) |
“初始静音超时”用于调整在识别尝试以“无匹配项”结果结束前,短语前允许的非语音音频量。 请参阅如何识别语音。 | 可选 |
MaxTonesToCollect |
Integer | 无默认值 最小值:1 |
开发人员期望参与者输入的位数。 | 必需 |
StopTones |
IEnumeration<DtmfTone> | 未设置 | 数字参与者可以按压以退出批量 DTMF 事件。 | 可选 |
InterruptPrompt |
布尔值 | True | 如果参与者能够通过按一个数字来中断 playMessage。 | 可选 |
InterruptCallMediaOperation |
布尔值 | True | 如果设置此标志,则会中断当前的调用媒体操作。 例如,如果正在播放任何音频,它会中断该操作并启动识别。 | 可选 |
OperationContext |
字符串 | 未设置 | 开发人员可以传递 mid 操作的字符串,用于允许开发人员存储有关他们收到的事件的上下文。 | 可选 |
Phrases |
字符串 | 未设置 | 与标签关联的短语列表。 听到其中任何一个短语都表示成功识别。 | 必选 |
Tone |
字符串 | 未设置 | 用户决定按下数字而不是使用语音时,要识别的音调。 | 可选 |
Label |
字符串 | 未设置 | 用于识别的关键值。 | 必选 |
Language |
字符串 | En-us | 用于识别语音的语言。 | 可选 |
EndSilenceTimeout |
TimeSpan | 0.5 秒 | 用于检测生成为语音的最终结果的说话人的最后一次暂停。 | 可选 |
注意
如果 DTMF 和语音都在 recognizeInputsType 中,则识别操作将作用于收到的第一个输入类型。 例如,如果用户首先按下小键盘上的数字,则识别操作会将其视为 DTMF 事件并继续侦听 DTMF 音调。 如果用户先说话,则识别操作会将其视为语音识别事件并侦听语音输入。
创建新的 JavaScript 应用程序
在项目目录中创建新的 JavaScript 应用程序。 使用以下命令,初始化新的 Node.js 项目。 这会为项目创建一个 package.json 文件,该文件管理项目的依赖项。
npm init -y
安装 Azure 通信服务呼叫自动化包
npm install @azure/communication-call-automation
例如,在项目目录中创建新的 JavaScript 文件并将其命名为 app.js。 在此文件中编写 JavaScript 代码。
通过以下命令,使用 Node.js 运行你的应用程序。
node app.js
建立呼叫
至此,你应已熟悉如何开始通话。 有关发起通话的详细信息,请参阅快速入门:发起传出通话。
调用识别动作
在你的应用程序应答呼叫时,你可以提供有关识别参与者输入和播放提示的信息。
DTMF
const maxTonesToCollect = 3;
const textToPlay = "Welcome to Contoso, please enter 3 DTMF.";
const playSource: TextSource = { text: textToPlay, voiceName: "en-US-ElizabethNeural", kind: "textSource" };
const recognizeOptions: CallMediaRecognizeDtmfOptions = {
maxTonesToCollect: maxTonesToCollect,
initialSilenceTimeoutInSeconds: 30,
playPrompt: playSource,
interToneTimeoutInSeconds: 5,
interruptPrompt: true,
stopDtmfTones: [ DtmfTone.Pound ],
kind: "callMediaRecognizeDtmfOptions"
};
await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.startRecognizing(targetParticipant, recognizeOptions);
对于语音转文本流,通话自动化识别操作还支持使用自定义语音识别模型。 在生成需要侦听默认语音转文本模型可能无法理解的复杂字词的应用程序时,自定义语音识别模型等功能可能非常有用。 例如,在为远程医疗行业生成应用程序,并且虚拟代理需要能够识别医疗术语时。 可以在创建自定义语音识别项目中了解详细信息。
语音转文本选择
const choices = [
{
label: "Confirm",
phrases: [ "Confirm", "First", "One" ],
tone: DtmfTone.One
},
{
label: "Cancel",
phrases: [ "Cancel", "Second", "Two" ],
tone: DtmfTone.Two
}
];
const textToPlay = "Hello, This is a reminder for your appointment at 2 PM, Say Confirm to confirm your appointment or Cancel to cancel the appointment. Thank you!";
const playSource: TextSource = { text: textToPlay, voiceName: "en-US-ElizabethNeural", kind: "textSource" };
const recognizeOptions: CallMediaRecognizeChoiceOptions = {
choices: choices,
interruptPrompt: true,
initialSilenceTimeoutInSeconds: 30,
playPrompt: playSource,
operationContext: "AppointmentReminderMenu",
kind: "callMediaRecognizeChoiceOptions",
//Only add the speechRecognitionModelEndpointId if you have a custom speech model you would like to use
speechRecognitionModelEndpointId: "YourCustomSpeechEndpointId"
};
await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.startRecognizing(targetParticipant, recognizeOptions);
语音转文本
const textToPlay = "Hi, how can I help you today?";
const playSource: TextSource = { text: textToPlay, voiceName: "en-US-ElizabethNeural", kind: "textSource" };
const recognizeOptions: CallMediaRecognizeSpeechOptions = {
endSilenceTimeoutInSeconds: 1,
playPrompt: playSource,
operationContext: "OpenQuestionSpeech",
kind: "callMediaRecognizeSpeechOptions",
//Only add the speechRecognitionModelEndpointId if you have a custom speech model you would like to use
speechRecognitionModelEndpointId: "YourCustomSpeechEndpointId"
};
await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.startRecognizing(targetParticipant, recognizeOptions);
语音转文本或 DTMF
const maxTonesToCollect = 1;
const textToPlay = "Hi, how can I help you today, you can press 0 to speak to an agent?";
const playSource: TextSource = { text: textToPlay, voiceName: "en-US-ElizabethNeural", kind: "textSource" };
const recognizeOptions: CallMediaRecognizeSpeechOrDtmfOptions = {
maxTonesToCollect: maxTonesToCollect,
endSilenceTimeoutInSeconds: 1,
playPrompt: playSource,
initialSilenceTimeoutInSeconds: 30,
interruptPrompt: true,
operationContext: "OpenQuestionSpeechOrDtmf",
kind: "callMediaRecognizeSpeechOrDtmfOptions",
//Only add the speechRecognitionModelEndpointId if you have a custom speech model you would like to use
speechRecognitionModelEndpointId: "YourCustomSpeechEndpointId"
};
await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.startRecognizing(targetParticipant, recognizeOptions);
注意
如果未设置参数,将尽可能应用默认值。
实时语言识别(预览版)
借助额外的实时语言识别,开发人员可以自动检测口语,以启用自然的、类似于人类的通信,并消除最终用户的手动语言选择。
const textToPlay = "Hi, how can I help you today?";
const playSource: TextSource = {
text: textToPlay,
voiceName: "en-US-ElizabethNeural",
kind: "textSource"
};
const recognizeOptions: CallMediaRecognizeSpeechOptions = {
endSilenceTimeoutInSeconds: 30,
playPrompt: playSource,
operationContext: "speechContext",
kind: "callMediaRecognizeSpeechOptions",
// Enable Language Identification
speechLanguages: ["en-US", "hi-IN", "fr-FR"],
// Only add the speechRecognitionModelEndpointId if you have a custom speech model you would like to use
speechRecognitionModelEndpointId: "YourCustomSpeechEndpointId"
};
await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.startRecognizing(targetParticipant, recognizeOptions);
注意
语言支持限制
使用以语音作为输入类型的 Recognize API 时:
- 可以使用
setSpeechLanguages(...)指定最多 10 种语言。 - 请注意,使用更多语言可能会由于额外的处理而增加接收
RecognizeCompleted事件所需的时间。
将 Recognize API 与选项配合使用时:
- 最多支持 4 种语言。
- 在选项模式下指定的语言超过 4 种可能会导致错误或性能下降。
情绪分析(预览版)
识别 API 支持使用语音输入时进行的情绪分析。 实时跟踪对话的情感基调以支持客户和代理交互,并在必要时允许主管进行干预。 它还可用于路由、个性化或分析。
const textToPlay = "Hi, how can I help you today?";
const playSource: TextSource = {
text: textToPlay,
voiceName: "en-US-ElizabethNeural",
kind: "textSource"
};
const recognizeOptions: CallMediaRecognizeSpeechOptions = {
endSilenceTimeoutInSeconds: 30,
playPrompt: playSource,
operationContext: "speechContext",
kind: "callMediaRecognizeSpeechOptions",
// Enable Sentiment Analysis
enableSentimentAnalysis: true
};
await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.startRecognizing(targetParticipant, recognizeOptions);
接收识别事件更新
开发人员可以订阅有关已注册 webhook 回调的 RecognizeCompleted 和 RecognizeFailed 事件。 在应用程序中将此回调与业务逻辑配合使用可以确定当其中一个事件发生时要采取的后续步骤。
如何反序列化 RecognizeCompleted 事件的示例:
if (event.type === "Microsoft.Communication.RecognizeCompleted") {
console.log("Received RecognizeCompleted event");
const callConnectionId = eventData.callConnectionId;
if (eventData.recognitionType === "choices") {
const labelDetected = eventData.choiceResult.label;
console.log(`Detected label: ${labelDetected}`);
console.log("Choice Result:", JSON.stringify(eventData.choiceResult, null, 2));
console.log(`Language Identified: ${eventData.choiceResult.languageIdentified}`);
if (eventData.choiceResult?.sentimentAnalysisResult !== undefined) {
console.log(`Sentiment: ${eventData.choiceResult.sentimentAnalysisResult.sentiment}`);
}
}
if (eventData.recognitionType === "dtmf") {
const tones = eventData.dtmfResult.tones;
console.log(`DTMF Tones: ${tones}`);
console.log(`Current Context: ${eventData.operationContext}`);
}
if (eventData.recognitionType === "speech") {
const text = eventData.speechResult.speech;
console.log(`Recognition completed, text: ${text}, context: ${eventData.operationContext}`);
console.log(`Language Identified: ${eventData.speechResult.languageIdentified}`);
if (eventData.speechResult?.sentimentAnalysisResult !== undefined) {
console.log(`Sentiment: ${eventData.speechResult.sentimentAnalysisResult.sentiment}`);
}
}
}
如何反序列化 RecognizeFailed 事件的示例:
if (event.type === "Microsoft.Communication.RecognizeFailed") {
console.log("Recognize failed: data=%s", JSON.stringify(eventData, null, 2));
}
如何反序列化 RecognizeCanceled 事件的示例:
if (event.type === "Microsoft.Communication.RecognizeCanceled") {
console.log("Recognize canceled, context=%s", eventData.operationContext);
}
Prerequisites
- 具有有效订阅的 Azure 帐户。有关详细信息,请参阅免费创建帐户。
- Azure 通信服务资源。 请参阅创建 Azure 通信服务资源。 请注意此资源的连接字符串。
- 使用通话自动化 SDK 创建新的 Web 服务应用程序。
- 从 Python.org 安装 Python。
对于 AI 功能
- 创建 Azure AI 服务并将其连接到 Azure 通信服务资源。
- 为 Azure AI 服务资源创建自定义子域。
技术规范
以下参数可用于自定义 Recognize 函数:
| 参数 | 类型 | 默认值(如果未指定) | 说明 | 必需还是可选 |
|---|---|---|---|---|
Prompt (有关详细信息,请参阅使用播放操作为用户自定义语音提示) |
FileSource、TextSource | 未设置 | 在识别输入之前要播放的消息。 | 可选 |
InterToneTimeout |
TimeSpan | 2 秒 最小值:1 秒 最大值:60 秒 |
Azure 通信服务等待呼叫者按另一个数字的秒数限制(数字间超时)。 | 可选 |
InitialSegmentationSilenceTimeoutInSeconds |
Integer | 0.5 秒 | 识别操作在考虑超时之前将等待输入多长时间。 请参阅如何识别语音。 | 可选 |
RecognizeInputsType |
枚举 | dtmf | 识别的输入的类型。 选项包括 dtmf、choices、speech 和 speechordtmf。 |
必选 |
InitialSilenceTimeout |
TimeSpan | 5 秒 最小值:0 秒 最大值:300 秒 (DTMF) 最大值:20 秒 (Choices) 最大值:20 秒 (Speech) |
“初始静音超时”用于调整在识别尝试以“无匹配项”结果结束前,短语前允许的非语音音频量。 请参阅如何识别语音。 | 可选 |
MaxTonesToCollect |
Integer | 无默认值 最小值:1 |
开发人员期望参与者输入的位数。 | 必需 |
StopTones |
IEnumeration<DtmfTone> | 未设置 | 数字参与者可以按压以退出批量 DTMF 事件。 | 可选 |
InterruptPrompt |
布尔值 | True | 如果参与者能够通过按一个数字来中断 playMessage。 | 可选 |
InterruptCallMediaOperation |
布尔值 | True | 如果设置此标志,则会中断当前的调用媒体操作。 例如,如果正在播放任何音频,它会中断该操作并启动识别。 | 可选 |
OperationContext |
字符串 | 未设置 | 开发人员可以传递 mid 操作的字符串,用于允许开发人员存储有关他们收到的事件的上下文。 | 可选 |
Phrases |
字符串 | 未设置 | 与标签关联的短语列表。 听到其中任何一个短语都表示成功识别。 | 必选 |
Tone |
字符串 | 未设置 | 用户决定按下数字而不是使用语音时,要识别的音调。 | 可选 |
Label |
字符串 | 未设置 | 用于识别的关键值。 | 必选 |
Language |
字符串 | En-us | 用于识别语音的语言。 | 可选 |
EndSilenceTimeout |
TimeSpan | 0.5 秒 | 用于检测生成为语音的最终结果的说话人的最后一次暂停。 | 可选 |
注意
如果 DTMF 和语音都在 recognizeInputsType 中,则识别操作将作用于收到的第一个输入类型。 例如,如果用户首先按下小键盘上的数字,则识别操作会将其视为 DTMF 事件并继续侦听 DTMF 音调。 如果用户先说话,则识别操作会将其视为语音识别事件并侦听语音输入。
创建新的 Python 应用程序
为你的项目设置 Python 虚拟环境
python -m venv play-audio-app
激活虚拟环境
在 Windows 上使用以下命令:
.\ play-audio-quickstart \Scripts\activate
在 Unix 上,使用以下命令:
source play-audio-quickstart /bin/activate
安装 Azure 通信服务呼叫自动化包
pip install azure-communication-callautomation
例如,在项目目录中创建应用程序文件并将其命名为 app.py。 在此文件中编写 Python 代码。
通过以下命令,使用 Python 运行你的应用程序。
python app.py
建立呼叫
至此,你应已熟悉如何开始通话。 有关发起通话的详细信息,请参阅快速入门:发起传出通话。
调用识别动作
在你的应用程序应答呼叫时,你可以提供有关识别参与者输入和播放提示的信息。
DTMF
max_tones_to_collect = 3
text_to_play = "Welcome to Contoso, please enter 3 DTMF."
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural")
call_automation_client.get_call_connection(call_connection_id).start_recognizing_media(
dtmf_max_tones_to_collect=max_tones_to_collect,
input_type=RecognizeInputType.DTMF,
target_participant=target_participant,
initial_silence_timeout=30,
play_prompt=play_source,
dtmf_inter_tone_timeout=5,
interrupt_prompt=True,
dtmf_stop_tones=[ DtmfTone.Pound ])
对于语音转文本流,通话自动化识别操作还支持使用自定义语音识别模型。 在生成需要侦听默认语音转文本模型可能无法理解的复杂字词的应用程序时,自定义语音识别模型等功能可能非常有用。 例如,在为远程医疗行业生成应用程序,并且虚拟代理需要能够识别医疗术语时。 可以在创建自定义语音识别项目中了解详细信息。
语音转文本选择
choices = [
RecognitionChoice(
label="Confirm",
phrases=[ "Confirm", "First", "One" ],
tone=DtmfTone.ONE
),
RecognitionChoice(
label="Cancel",
phrases=[ "Cancel", "Second", "Two" ],
tone=DtmfTone.TWO
)
]
text_to_play = "Hello, This is a reminder for your appointment at 2 PM, Say Confirm to confirm your appointment or Cancel to cancel the appointment. Thank you!"
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural")
call_automation_client.get_call_connection(call_connection_id).start_recognizing_media(
input_type=RecognizeInputType.CHOICES,
target_participant=target_participant,
choices=choices,
interrupt_prompt=True,
initial_silence_timeout=30,
play_prompt=play_source,
operation_context="AppointmentReminderMenu",
# Only add the speech_recognition_model_endpoint_id if you have a custom speech model you would like to use
speech_recognition_model_endpoint_id="YourCustomSpeechModelEndpointId")
语音转文本
text_to_play = "Hi, how can I help you today?"
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural")
call_automation_client.get_call_connection(call_connection_id).start_recognizing_media(
input_type=RecognizeInputType.SPEECH,
target_participant=target_participant,
end_silence_timeout=1,
play_prompt=play_source,
operation_context="OpenQuestionSpeech",
# Only add the speech_recognition_model_endpoint_id if you have a custom speech model you would like to use
speech_recognition_model_endpoint_id="YourCustomSpeechModelEndpointId")
语音转文本或 DTMF
max_tones_to_collect = 1
text_to_play = "Hi, how can I help you today, you can also press 0 to speak to an agent."
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural")
call_automation_client.get_call_connection(call_connection_id).start_recognizing_media(
dtmf_max_tones_to_collect=max_tones_to_collect,
input_type=RecognizeInputType.SPEECH_OR_DTMF,
target_participant=target_participant,
end_silence_timeout=1,
play_prompt=play_source,
initial_silence_timeout=30,
interrupt_prompt=True,
operation_context="OpenQuestionSpeechOrDtmf",
# Only add the speech_recognition_model_endpoint_id if you have a custom speech model you would like to use
speech_recognition_model_endpoint_id="YourCustomSpeechModelEndpointId")
app.logger.info("Start recognizing")
注意
如果未设置参数,将尽可能应用默认值。
实时语言识别(预览版)
借助额外的实时语言识别,开发人员可以自动检测口语,以启用自然的、类似于人类的通信,并消除最终用户的手动语言选择。
text_to_play = "Hi, how can I help you today?"
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural")
connection_client = call_automation_client.get_call_connection(call_connection_id)
recognize_result = await connection_client.start_recognizing_media(
input_type=RecognizeInputType.SPEECH,
target_participant=PhoneNumberIdentifier(caller_id),
end_silence_timeout=15,
play_prompt=play_source,
operation_context="OpenQuestionSpeech",
# Enable language identification
speech_language=["en-US", "es-ES", "hi-IN"],
# Only add the speech_recognition_model_endpoint_id if you have a custom speech model you would like to use
speech_recognition_model_endpoint_id="YourCustomSpeechModelEndpointId"
)
注意
语言支持限制
使用以语音作为输入类型的 Recognize API 时:
- 可以使用
setSpeechLanguages(...)指定最多 10 种语言。 - 请注意,使用更多语言可能会由于额外的处理而增加接收
RecognizeCompleted事件所需的时间。
将 Recognize API 与选项配合使用时:
- 最多支持 4 种语言。
- 在选项模式下指定的语言超过 4 种可能会导致错误或性能下降。
情绪分析(预览版)
识别 API 支持使用语音输入时进行的情绪分析。 实时跟踪对话的情感基调以支持客户和代理交互,并在必要时允许主管进行干预。 它还可用于路由、个性化或分析。
text_to_play = "Hi, how can I help you today?"
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural")
connection_client = call_automation_client.get_call_connection(call_connection_id)
recognize_result = await connection_client.start_recognizing_media(
input_type=RecognizeInputType.SPEECH,
target_participant=PhoneNumberIdentifier(caller_id),
end_silence_timeout=15,
play_prompt=play_source,
operation_context="OpenQuestionSpeech",
# Enable sentiment analysis
IsSentimentAnalysisEnabled = true,
# Only add the speech_recognition_model_endpoint_id if you have a custom speech model you would like to use
speech_recognition_model_endpoint_id="YourCustomSpeechModelEndpointId"
)
接收识别事件更新
开发人员可以订阅有关已注册 webhook 回调的 RecognizeCompleted 和 RecognizeFailed 事件。 在应用程序中将此回调与业务逻辑配合使用可以确定当其中一个事件发生时要采取的后续步骤。
如何反序列化 RecognizeCompleted 事件的示例:
if event.type == "Microsoft.Communication.RecognizeCompleted":
print(f"Received RecognizeCompleted event for connection id: {call_connection_id}")
recognition_type = event.data.get("recognitionType")
if recognition_type == "dtmf":
tones = event.data["dtmfResult"]["tones"]
context = event.data["operationContext"]
print(f"Recognition completed, tones={tones}, context={context}")
elif recognition_type == "choices":
choice_result = event.data["choiceResult"]
label_detected = choice_result["label"]
phrase_detected = choice_result["recognizedPhrase"]
language_identified = choice_result.get("languageIdentified")
sentiment = choice_result.get("sentimentAnalysisResult", {}).get("sentiment")
print(f"Recognition completed, labelDetected={label_detected}, phraseDetected={phrase_detected}, context={event.data['operationContext']}")
print(f"Language Identified: {language_identified}")
print(f"Sentiment: {sentiment}")
elif recognition_type == "speech":
speech_result = event.data["speechResult"]
text = speech_result["speech"]
language_identified = speech_result.get("languageIdentified")
sentiment = speech_result.get("sentimentAnalysisResult", {}).get("sentiment")
print(f"Recognition completed, text={text}, context={event.data['operationContext']}")
print(f"Language Identified: {language_identified}")
print(f"Sentiment: {sentiment}")
else:
print(f"Recognition completed: data={event.data}")
如何反序列化 RecognizeFailed 事件的示例:
if event.type == "Microsoft.Communication.RecognizeFailed":
app.logger.info("Recognize failed: data=%s", event.data);
如何反序列化 RecognizeCanceled 事件的示例:
if event.type == "Microsoft.Communication.RecognizeCanceled":
# Handle the RecognizeCanceled event according to your application logic
事件代码
| 状态 | Code | 子代码 | 消息 |
|---|---|---|---|
RecognizeCompleted |
200 | 8531 | 操作已完成,接收的最大位数。 |
RecognizeCompleted |
200 | 8514 | 检测到停止音调时完成的操作。 |
RecognizeCompleted |
400 | 8508 | 操作失败,操作已取消。 |
RecognizeCompleted |
400 | 8532 | 操作失败,已达到数字间静音超时。 |
RecognizeCanceled |
400 | 8508 | 操作失败,操作已取消。 |
RecognizeFailed |
400 | 8510 | 操作失败,已达到初始静音超时。 |
RecognizeFailed |
500 | 8511 | 操作失败,尝试播放提示时遇到失败。 |
RecognizeFailed |
500 | 8512 | 未知的内部服务器错误。 |
RecognizeFailed |
400 | 8510 | 操作失败,已达到初始静音超时 |
RecognizeFailed |
400 | 8532 | 操作失败,已达到数字间静音超时。 |
RecognizeFailed |
400 | 8565 | 操作失败,对 Azure AI 服务的请求不正确。 检查输入参数。 |
RecognizeFailed |
400 | 8565 | 操作失败,对 Azure AI 服务的请求不正确。 无法处理提供的有效负载,请检查播放源输入。 |
RecognizeFailed |
401 | 8565 | 操作失败,Azure AI 服务身份验证错误。 |
RecognizeFailed |
403 | 8565 | 操作失败,禁止请求 Azure AI 服务,请求使用的免费订阅已用完配额。 |
RecognizeFailed |
429 | 8565 | 操作失败,请求超出了 Azure AI 服务订阅允许的并发请求数。 |
RecognizeFailed |
408 | 8565 | 操作失败,对 Azure AI 服务的请求已超时。 |
RecognizeFailed |
500 | 8511 | 操作失败,尝试播放提示时遇到失败。 |
RecognizeFailed |
500 | 8512 | 未知的内部服务器错误。 |
已知的限制
- 不支持带内 DTMF。 请改用 RFC 2833 DTMF。
- 文本转语音提示最多支持 4,000 个字符。 如果提示内容超过此限制,我们建议使用 SSML 进行文本转语音播放操作。
- 录音时语音输入会在 1:1 呼叫中被捕获,但在启用录音时,不会在群组通话中记录。
- 如果超出配额限制,可以请求提高语音服务配额。 按照 此处 概述的步骤请求增加。
清理资源
如果想要清理并删除通信服务订阅,可以删除资源或资源组。 删除资源组同时也会删除与之相关联的任何其他资源。 了解有关清理资源的详细信息。