用「播放」動作自訂使用者語音提示
本指南將協助您開始使用 Azure 通訊服務通話自動化 SDK 提供的播放動作,為參與者播放音訊檔案。
必要條件
- 包含使用中訂用帳戶的 Azure 帳戶。如需詳細資料,請參閱建立免費帳戶。
- Azure 通訊服務資源。 請參閱建立 Azure 通訊服務資源。 儲存此資源的連接字串。
- 使用通話自動化 SDK 來建立新的 Web 服務應用程式。
- 您作業系統適用的最新 .NET 程式庫。
- 取得最新的 NuGet 套件。
針對 AI 功能
- 建立 Azure AI 服務並將其連線至您的 Azure 通訊服務資源。
- 為您的 Azure AI 服務資源建立自訂子網域。
建立新的 C# 應用程式
在作業系統的主控台視窗中,使用 dotnet
命令建立新的 Web 應用程式。
dotnet new web -n MyApplication
安裝 NuGet 封裝
如果您尚未取得 NuGet 套件,可以從這裡取得。
(選擇性) 如果您想要使用音訊檔案來播放提示,請準備您的音訊檔案
如果您還沒有音訊檔案,請先建立後再用以向參與者播放提示和訊息。 音訊檔案必須裝載於 Azure 通訊服務可存取且支援驗證的位置。 請保留 URL 複本,以便於要求播放音訊檔案時使用。 Azure 通訊服務可支援搭配 ID3V2TAG 的 MP3 檔案,以及採樣速率 16 KHz 的單聲道 16 位元 PCM 的 WAV 檔案。 .
您可以用我們的使用音訊內容建立工具的語音合成來測試建立自己的音訊檔案。
(選擇性) 將您的 Azure 認知服務連線到您的 Azure 通訊服務
如果您要使用文字轉換語音功能,則必須連線 Azure 認知服務至 Azure 通訊服務。
建立通話
這時您應該已熟悉開始通話。如果您需要深入了解如何撥打電話,請遵循我們的快速入門。 您也可以使用這裡提供的程式碼片段來了解如何接聽來電。
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);
播放音訊
通話一旦建立,即可透過多個選項,選擇您希望播放音訊的方式。 您可以為加入通話的參與者播放音訊,或為通話中的所有參與者播放音訊。
播放來源 - 音訊檔案
若要使用音訊檔案對參與者播放音訊,您必須確定音訊檔案是 WAV 檔案、單聲道和 16 KHz。 若要播放音訊檔案,您必須確定將具有 URI 的 Azure 通訊服務提供給您在 Azure 通訊服務可存取的位置中裝載的檔案。 SDK 中的 FileSource 類型可用來指定播放動作的音訊檔案。
var playSource = new FileSource(new Uri(audioUri));
//Multiple FileSource Prompts, if you want to play multiple audio files in one request you can provide them in a list.
//var playSources = new List<PlaySource>() { new FileSource(new Uri("https://www2.cs.uic.edu/~i101/SoundFiles/StarWars3.wav")), new FileSource(new Uri("https://www2.cs.uic.edu/~i101/SoundFiles/preamble10.wav")) };
播放來源 - 文字轉換語音
若要透過 Azure AI 服務使用文字轉換語音播放音訊,您需要提供您想要播放的文字,以及您想要使用的 SourceLocale 和 VoiceKind 或 VoiceName。 我們支援 Azure AI 服務支援的所有語音名稱,完整清單請見此處。
String textToPlay = "Welcome to Contoso";
// Provide SourceLocale and VoiceKind to select an appropriate voice.
var playSource = new TextSource(textToPlay, "en-US", VoiceKind.Female);
//Multiple TextSource prompt, if you want to play multiple text prompts in one request you can provide them in a list.
//var playSources = new List<PlaySource>() { new TextSource("recognize prompt one") { VoiceName = SpeechToTextVoice }, new TextSource("recognize prompt two") { VoiceName = SpeechToTextVoice }, new TextSource(content) { VoiceName = SpeechToTextVoice } };
String textToPlay = "Welcome to Contoso";
// Provide VoiceName to select a specific voice.
var playSource = new TextSource(textToPlay, "en-US-ElizabethNeural");
//Multiple TextSource prompt, if you want to play multiple text prompts in one request you can provide them in a list.
//var playSources = new List<PlaySource>() { new TextSource("recognize prompt one") { VoiceName = SpeechToTextVoice }, new TextSource("recognize prompt two") { VoiceName = SpeechToTextVoice }, new TextSource(content) { VoiceName = SpeechToTextVoice } };
播放來源 - 使用 SSML 的文字轉換語音
如果您想要使用 Azure AI 服務進一步自訂文字轉換語音輸出,您可以在透過通話自動化叫用您的播放動作時,使用語音合成標記語言 SSML。 使用 SSML 時,您可以微調音高、停頓、改善發音、變更說話速度、調整音量,以及歸因多個語音。
String ssmlToPlay = "<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\"><voice name=\"en-US-JennyNeural\">Hello World!</voice></speak>";
var playSource = new SsmlSource(ssmlToPlay);
自訂語音模型
如果您想要更加強化提示並包含自訂語音模型,文字轉換語音播放動作現在支援這些自訂語音。 如果您嘗試為客戶提供更當地化、更個人化的體驗,或您有預設模型可能無法涵蓋您嘗試發音的字組和腔調的情況,這些是絕佳的選擇。 若要深入了如何建立和部署自訂模型,您可以閱讀本指南。
自訂語音名稱的一般文字範例
String textToPlay = "Welcome to Contoso";
// Provide VoiceName and CustomVoiceEndpointId to select custom voice.
var playSource = new TextSource(textToPlay)
{
VoiceName = "YourCustomVoiceName",
CustomVoiceEndpointId = "YourCustomEndpointId"
};
自訂語音名稱的 SSML 範例
var playSource = new SsmlSource(ssmlToPlay,"YourCustomEndpointId");
決定要用於播放音訊的 playSource 之後,您可以選擇要對特定參與者或所有參與者播放。
對所有參與者播放音訊
在此案例中,系統會對通話中的所有參與者播放音訊。
var playResponse = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.PlayToAllAsync(playSource);
支援插話
在向所有參與者循環播放音訊的情節中 (例如等候大廳),您可能會向大廳中的參與者播放音訊,並且讓他們隨時掌握其在佇列中的號碼。 當您使用插話支援時,這會取消進行中的音訊並播放您的新訊息。 然後,如果您想要繼續播放原始音訊,您會提出另一個播放要求。
var GoodbyePlaySource = new TextSource("Good bye")
{
VoiceName = "en-US-NancyNeural"
};
PlayToAllOptions playOptions = new PlayToAllOptions(GoodbyePlaySource)
{
InterruptCallMediaOperation = false,
OperationCallbackUri = new Uri(callbackUriHost),
Loop = true
};
await callConnectionMedia.PlayToAllAsync(playOptions);
// Interrupt media with text source
// Option1:
var interrupt = new TextSource("Interrupt prompt message")
{
VoiceName = "en-US-NancyNeural"
};
PlayToAllOptions playInterrupt = new PlayToAllOptions(interrupt)
{
InterruptCallMediaOperation = true,
OperationCallbackUri = new Uri(callbackUriHost),
Loop = false
};
await callConnectionMedia.PlayToAllAsync(playInterrupt);
/*
Option2: Interrupt media with file source
var interruptFile = new FileSource(new Uri(<AUDIO URL>));
PlayToAllOptions playFileInterrupt = new PlayToAllOptions(interruptFile)
{
InterruptCallMediaOperation = true,
OperationCallbackUri = new Uri(callbackUriHost),
Loop = false
};
await callConnectionMedia.PlayToAllAsync(playFileInterrupt);
*/
對特定參與者播放音訊
在此案例中,系統會對特定參與者播放音訊。
var playTo = new List<CommunicationIdentifier> { targetParticipant };
var playResponse = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.PlayAsync(playSource, playTo);
播放多個音訊提示
播放動作全都支援只透過一項要求傳送多個播放來源的能力。 這表示您會傳送一份提示清單來一次播放,而不是個別提出這些要求。
迴圈播放音訊
您可以用迴圈選項播放暫停音樂,反覆播放至應用程式準備好接受通話者為止。 您也可以根據應用程式業務邏輯,讓呼叫者進入下一個邏輯步驟。
var playOptions = new PlayToAllOptions(playSource)
{
Loop = true
};
var playResult = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.PlayToAllAsync(playOptions);
用音訊檔案快取增強播放
如果您要多次播放同樣的音訊檔案,則可透過應用程式提供包含音訊檔案的 sourceID 的 Azure 通訊服務。 Azure 通訊服務會快取 1 小時的此音訊檔案。
注意
快取音訊檔案不適用於動態提示。 如果您變更提供給 Azure 通訊服務的 URL,則不會立即更新快取的 URL。 更新會在現有快取過期之後發生。
var playTo = new List<CommunicationIdentifier> { targetParticipant };
var playSource = new FileSource(new Uri(audioUri))
{
PlaySourceCacheId = "<playSourceId>"
};
var playResult = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.PlayAsync(playSource, playTo);
處理播放動作事件更新
您的應用程式會在回撥 URL 上收到動作生命週期事件更新,回撥 URL 會在接通電話時提供給通話自動化服務。 成功播放事件更新的範例。
如何還原序列化 PlayCompleted 事件的範例:
if (acsEvent is PlayCompleted playCompleted)
{
logger.LogInformation("Play completed successfully, context={context}", playCompleted.OperationContext);
}
如何還原序列化 PlayStarted 事件的範例:
if (acsEvent is PlayStarted playStarted)
{
logger.LogInformation("Play started successfully, context={context}", playStarted.OperationContext);
}
如何還原序列化 PlayFailed 事件的範例:
if (acsEvent is PlayFailed playFailed)
{
if (MediaEventReasonCode.PlayDownloadFailed.Equals(playFailed.ReasonCode))
{
logger.LogInformation("Play failed: download failed, context={context}", playFailed.OperationContext);
}
else if (MediaEventReasonCode.PlayInvalidFileFormat.Equals(playFailed.ReasonCode))
{
logger.LogInformation("Play failed: invalid file format, context={context}", playFailed.OperationContext);
}
else
{
logger.LogInformation("Play failed, result={result}, context={context}", playFailed.ResultInformation?.Message, playFailed.OperationContext);
}
}
若要深入了解其他支援的事件,請造訪通話自動化概觀文件。
取消播放動作
取消所有媒體作業,所有擱置的媒體作業都會取消。 這個動作也會取消其他佇列中的播放動作。
var cancelResult = await callAutomationClient.GetCallConnection(callConnectionId)
.GetCallMedia()
.CancelAllMediaOperationsAsync();
如何還原序列化 PlayCanceled 事件的範例:
if (acsEvent is PlayCanceled playCanceled)
{
logger.LogInformation("Play canceled, context={context}", playCanceled.OperationContext);
}
必要條件
- 包含使用中訂用帳戶的 Azure 帳戶。如需詳細資料,請參閱建立免費帳戶。
- Azure 通訊服務資源。 請參閱建立 Azure 通訊服務資源
- 使用通話自動化 SDK 來建立新的 Web 服務應用程式。
- JAVA 開發套件第 8 版或更新版本。
- Apache Maven。
針對 AI 功能
- 建立 Azure AI 服務並將其連線至您的 Azure 通訊服務資源。
- 為您的 Azure AI 服務資源建立自訂子網域。
建立新的 Java 應用程式
在您的終端機或命令視窗中,瀏覽至您想要在其中建立 JAVA 應用程式的目錄。 執行此處顯示的命令,以從 maven-archetype-quickstart 範本產生 Java 專案。
mvn archetype:generate -DgroupId=com.communication.quickstart -DartifactId=communication-quickstart -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
上述命令會建立與 artifactId
引數相同名稱的目錄。 在此目錄底下,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
從 Azure SDK 開發摘要擷取 Azure 通訊服務通話自動化 SDK 套件。
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-communication-callautomation</artifactId>
<version>1.0.0</version>
</dependency>
(選擇性) 如果您想要使用音訊檔案來播放提示,請準備您的音訊檔案
如果您還沒有音訊檔案,請先建立後再用以向參與者播放提示和訊息。 音訊檔案必須裝載於 Azure 通訊服務可存取且支援驗證的位置。 請保留 URL 複本,以便於要求播放音訊檔案時使用。 Azure 通訊服務可支援搭配 ID3V2TAG 的 MP3 檔案,以及採樣速率 16 KHz 的單聲道 16 位元 PCM 的 WAV 檔案。 .
您可以用我們的使用音訊內容建立工具的語音合成來測試建立自己的音訊檔案。
(選擇性) 將您的 Azure 認知服務連線到您的 Azure 通訊服務
如果您要使用文字轉換語音功能,則必須連線 Azure 認知服務至 Azure 通訊服務。
以程式碼更新 App.java
在您選擇的編輯器中開啟 App.java 檔案,並以使用程式碼更新 app.java 一節中提供的程式碼予以更新。
建立通話
這時您應該已熟悉開始通話。如果您需要深入了解如何撥打電話,請遵循我們的快速入門。 您也可以使用這裡提供的程式碼片段來了解如何接聽來電。
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();
播放音訊
通話一旦建立,即可透過多個選項,選擇您希望播放音訊的方式。 您可以為加入通話的參與者播放音訊,或為通話中的所有參與者播放音訊。
播放來源 - 音訊檔案
若要使用音訊檔案對參與者播放音訊,您必須確定音訊檔案是 WAV 檔案、單聲道和 16 KHz。 若要播放音訊檔案,您必須確定將具有 URI 的 Azure 通訊服務提供給您在 Azure 通訊服務可存取的位置中裝載的檔案。 SDK 中的 FileSource 類型可用來指定播放動作的音訊檔案。
var playSource = new FileSource(new Uri(audioUri));
/* Multiple FileSource Prompts
var p1 = new FileSource().setUrl("https://www2.cs.uic.edu/~i101/SoundFiles/StarWars3.wav");
var p2 = new FileSource().setUrl("https://www2.cs.uic.edu/~i101/SoundFiles/preamble10.wav");
var playSources = new ArrayList();
playSources.add(p1);
playSources.add(p2);
*/
播放來源 - 文字轉換語音
若要透過 Azure AI 服務使用文字轉換語音播放音訊,您需要提供您想要播放的文字,以及您想要使用的 SourceLocale 和 VoiceKind 或 VoiceName。 我們支援 Azure AI 服務支援的所有語音名稱,完整清單請見此處。
// Provide SourceLocale and VoiceKind to select an appropriate voice.
var playSource = new TextSource()
.setText(textToPlay)
.setSourceLocale("en-US")
.setVoiceKind(VoiceKind.FEMALE);
/* Multiple Prompt list setup: Multiple TextSource prompt
var p1 = new TextSource().setText("recognize prompt one").setSourceLocale("en-US").setVoiceKind(VoiceKind.FEMALE);
var p2 = new TextSource().setText("recognize prompt two").setSourceLocale("en-US").setVoiceKind(VoiceKind.FEMALE);
var p3 = new TextSource().setText(content).setSourceLocale("en-US").setVoiceKind(VoiceKind.FEMALE);
var playSources = new ArrayList();
playSources.add(p1);
playSources.add(p2);
playSources.add(p3);
*/
// Provide VoiceName to select a specific voice.
var playSource = new TextSource()
.setText(textToPlay)
.setVoiceName("en-US-ElizabethNeural");
/* Multiple Prompt list setup: Multiple TextSource prompt
var p1 = new TextSource().setText("recognize prompt one").setVoiceName("en-US-NancyNeural");
var p2 = new TextSource().setText("recognize prompt two").setVoiceName("en-US-NancyNeural");
var p3 = new TextSource().setText(content).setVoiceName("en-US-NancyNeural");
var playSources = new ArrayList();
playSources.add(p1);
playSources.add(p2);
playSources.add(p3);
*/
播放來源 - 文字轉換語音 SSML
String ssmlToPlay = "<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\"><voice name=\"en-US-JennyNeural\">Hello World!</voice></speak>";
var playSource = new SsmlSource()
.setSsmlText(ssmlToPlay);
自訂語音模型
如果您想要更加強化提示並包含自訂語音模型,文字轉換語音播放動作現在支援這些自訂語音。 如果您嘗試為客戶提供更當地化、更個人化的體驗,或您有預設模型可能無法涵蓋您嘗試發音的字組和腔調的情況,這些是絕佳的選擇。 若要深入了如何建立和部署自訂模型,您可以閱讀本指南。
自訂語音名稱的一般文字範例
// Provide VoiceName and to select a specific voice.
var playSource = new TextSource()
.setText(textToPlay)
.setCustomVoiceName("YourCustomVoiceName")
.setCustomVoiceEndpointId("YourCustomEndpointId");
自訂語音名稱的 SSML 範例
String ssmlToPlay = "<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\"><voice name=\"YourCustomVoiceName\">Hello World!</voice></speak>";
var playSource = new SsmlSource()
.setSsmlText(ssmlToPlay)
.setCustomVoiceEndpointId("YourCustomEndpointId");
決定要用於播放音訊的 playSource 之後,您可以選擇要對特定參與者或所有參與者播放。
對所有參與者播放音訊
在此案例中,系統會對通話中的所有參與者播放音訊。
var playOptions = new PlayToAllOptions(playSource);
var playResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.playToAllWithResponse(playOptions)
.block();
log.info("Play result: " + playResponse.getStatusCode());
支援插話
在向所有參與者循環播放音訊的情節中 (例如等候大廳),您可能會向大廳中的參與者播放音訊,並且讓他們隨時掌握其在佇列中的號碼。 當您使用插話支援時,這會取消進行中的音訊並播放您的新訊息。 然後,如果您想要繼續播放原始音訊,您會提出另一個播放要求。
// Option1: Interrupt media with text source
var textPlay = new TextSource()
.setText("First Interrupt prompt message")
.setVoiceName("en-US-NancyNeural");
var playToAllOptions = new PlayToAllOptions(textPlay)
.setLoop(false)
.setOperationCallbackUrl(appConfig.getBasecallbackuri())
.setInterruptCallMediaOperation(false);
client.getCallConnection(callConnectionId)
.getCallMedia()
.playToAllWithResponse(playToAllOptions, Context.NONE);
/*
Option2: Interrupt media with text source
client.getCallConnection(callConnectionId)
.getCallMedia()
.playToAll(textPlay);
*/
/*
Option1: Barge-in with file source
var interruptFile = new FileSource()
.setUrl("https://www2.cs.uic.edu/~i101/SoundFiles/StarWars3.wav");
var playFileOptions = new PlayToAllOptions(interruptFile)
.setLoop(false)
.setOperationCallbackUrl(appConfig.getBasecallbackuri())
.setInterruptCallMediaOperation(true);
client.getCallConnection(callConnectionId)
.getCallMedia()
.playToAllWithResponse(playFileOptions, Context.NONE);
Option2: Barge-in with file source
client.getCallConnection(callConnectionId)
.getCallMedia()
.playToAll(interruptFile);
*/
對特定參與者播放音訊
在此案例中,系統會對特定參與者播放音訊。
var playTo = Arrays.asList(targetParticipant);
var playOptions = new PlayOptions(playSource, playTo);
var playResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.playWithResponse(playOptions)
.block();
迴圈播放音訊
您可以用迴圈選項播放暫停音樂,反覆播放至應用程式準備好接受通話者為止。 您也可以根據應用程式業務邏輯,讓呼叫者進入下一個邏輯步驟。
var playOptions = new PlayToAllOptions(playSource)
.setLoop(true);
var playResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.playToAllWithResponse(playOptions)
.block();
用音訊檔案快取增強播放
如果您要多次播放同樣的音訊檔案,則可透過應用程式提供包含音訊檔案的 sourceID 的 Azure 通訊服務。 Azure 通訊服務會快取 1 小時的此音訊檔案。
注意
快取音訊檔案不適用於動態提示。 如果您變更提供給 Azure 通訊服務的 URL,則不會立即更新快取的 URL。 更新會在現有快取過期之後發生。
var playTo = Arrays.asList(targetParticipant);
var playSource = new FileSource()
.setUrl(audioUri) \
.setPlaySourceCacheId("<playSourceId>");
var playOptions = new PlayOptions(playSource, playTo);
var playResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.playWithResponse(playOptions)
.block();
處理播放動作事件更新
您的應用程式會在回撥 URL 上收到動作生命週期事件更新,回撥 URL 會在接通電話時提供給通話自動化服務。 成功播放事件更新的範例。
如何還原序列化 PlayCompleted 事件的範例:
if (acsEvent instanceof PlayCompleted) {
PlayCompleted event = (PlayCompleted) acsEvent;
log.info("Play completed, context=" + event.getOperationContext());
}
如何還原序列化 PlayStarted 事件的範例:
if (acsEvent instanceof PlayStarted) {
PlayStarted event = (PlayStarted) acsEvent;
log.info("Play started, context=" + event.getOperationContext());
}
如何還原序列化 PlayFailed 事件的範例:
if (acsEvent instanceof PlayFailed) {
PlayFailed event = (PlayFailed) acsEvent;
if (ReasonCode.Play.DOWNLOAD_FAILED.equals(event.getReasonCode())) {
log.info("Play failed: download failed, context=" + event.getOperationContext());
} else if (ReasonCode.Play.INVALID_FILE_FORMAT.equals(event.getReasonCode())) {
log.info("Play failed: invalid file format, context=" + event.getOperationContext());
} else {
log.info("Play failed, result=" + event.getResultInformation().getMessage() + ", context=" + event.getOperationContext());
}
}
若要深入了解其他支援的事件,請造訪通話自動化概觀文件。
取消播放動作
取消所有媒體作業,所有擱置的媒體作業都會取消。 這個動作也會取消其他佇列中的播放動作。
var cancelResponse = callAutomationClient.getCallConnectionAsync(callConnectionId)
.getCallMediaAsync()
.cancelAllMediaOperationsWithResponse()
.block();
log.info("Cancel result: " + cancelResponse.getStatusCode());
如何還原序列化 PlayCanceled 事件的範例:
if (acsEvent instanceof PlayCanceled) {
PlayCanceled event = (PlayCanceled) acsEvent;
log.info("Play canceled, context=" + event.getOperationContext());
}
必要條件
- 包含使用中訂用帳戶的 Azure 帳戶。如需詳細資料,請參閱建立免費帳戶。
- Azure 通訊服務資源。 請參閱建立 Azure 通訊服務資源。 儲存此資源的連接字串。
- 使用通話自動化 SDK 來建立新的 Web 服務應用程式。
- 安裝 Node.js 後,您可以從官方網站進行安裝。
針對 AI 功能
- 建立 Azure AI 服務並將其連線至您的 Azure 通訊服務資源。
- 為您的 Azure AI 服務資源建立自訂子網域。
建立新的 JavaScript 應用程式
在您的專案目錄中建立新的 JavaScript 應用程式。 使用下列命令初始化新的 Node.js 專案。 這會為您的專案建立 package.json 檔案,用來管理專案的相依性。
npm init -y
安裝 Azure 通訊服務通話自動化套件
npm install @azure/communication-call-automation
例如,在您的專案目錄中建立新的 JavaScript 檔案,將其命名為 app.js。 您會在此檔案中撰寫 JavaScript 程式碼。 搭配使用 Node.js 與下列命令執行您的應用程式。 此程式碼會執行您已撰寫的 JavaScript 程式碼。
node app.js
(選擇性) 如果您想要使用音訊檔案來播放提示,請準備您的音訊檔案
如果您還沒有音訊檔案,請先建立後再用以向參與者播放提示和訊息。 音訊檔案必須裝載於 Azure 通訊服務可存取且支援驗證的位置。 請保留 URL 複本,以便於要求播放音訊檔案時使用。 Azure 通訊服務可支援搭配 ID3V2TAG 的 MP3 檔案,以及採樣速率 16 KHz 的單聲道 16 位元 PCM 的 WAV 檔案。
您可以用我們的使用音訊內容建立工具的語音合成來測試建立自己的音訊檔案。
(選擇性) 將您的 Azure 認知服務連線到您的 Azure 通訊服務
如果您要使用文字轉換語音功能,則必須連線 Azure 認知服務至 Azure 通訊服務。
建立通話
這時您應該已熟悉開始通話。如果您需要深入了解如何撥打電話,請遵循我們的快速入門。 您也可以使用這裡提供的程式碼片段來了解如何接聽來電。
const callIntelligenceOptions: CallIntelligenceOptions = { "<https://sample-callback-uri>" };
const answerCallOptions: AnswerCallOptions = { callIntelligenceOptions: callIntelligenceOptions };
await acsClient.answerCall("<Incoming call context>", "<https://sample-callback-uri>", answerCallOptions);
播放音訊
通話一旦建立,即可透過多個選項,選擇您希望播放音訊的方式。 您可以為加入通話的參與者播放音訊,或為通話中的所有參與者播放音訊。
播放來源 - 音訊檔案
若要使用音訊檔案對參與者播放音訊,您必須確定音訊檔案是 WAV 檔案、單聲道和 16 KHz。 若要播放音訊檔案,您必須確定將具有 URI 的 Azure 通訊服務提供給您在 Azure 通訊服務可存取的位置中裝載的檔案。 SDK 中的 FileSource 類型可用來指定播放動作的音訊檔案。
const playSource: FileSource = { url: audioUri, kind: "fileSource" };
播放來源 - 文字轉換語音
若要透過 Azure AI 服務使用文字轉換語音播放音訊,您需要提供您想要播放的文字,以及您想要使用的 SourceLocale 和 VoiceKind 或 VoiceName。 我們支援 Azure AI 服務支援的所有語音名稱,完整清單請見此處。
const textToPlay = "Welcome to Contoso";
// Provide SourceLocale and VoiceKind to select an appropriate voice.
const playSource: TextSource = { text: textToPlay, sourceLocale: "en-US", voiceKind: VoiceKind.Female, kind: "textSource" };
const textToPlay = "Welcome to Contoso";
// Provide VoiceName to select a specific voice.
const playSource: TextSource = { text: textToPlay, voiceName: "en-US-ElizabethNeural", kind: "textSource" };
播放來源 - 使用 SSML 的文字轉換語音
如果您想要使用 Azure AI 服務進一步自訂文字轉換語音輸出,您可以在透過通話自動化叫用您的播放動作時,使用語音合成標記語言 SSML。 使用 SSML 時,您可以微調音高、停頓、改善發音、變更說話速度、調整音量,以及歸因多個語音。
const ssmlToPlay = "<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\"><voice name=\"en-US-JennyNeural\">Hello World!</voice></speak>";
const playSource: SsmlSource = { ssmlText: ssmlToPlay, kind: "ssmlSource" };
自訂語音模型
如果您想要更加強化提示並包含自訂語音模型,文字轉換語音播放動作現在支援這些自訂語音。 如果您嘗試為客戶提供更當地化、更個人化的體驗,或您有預設模型可能無法涵蓋您嘗試發音的字組和腔調的情況,這些是絕佳的選擇。 若要深入了如何建立和部署自訂模型,您可以閱讀本指南。
自訂語音名稱的一般文字範例
const textToPlay = "Welcome to Contoso";
// Provide VoiceName and CustomVoiceEndpointID to play your custom voice
const playSource: TextSource = { text: textToPlay, voiceName: "YourCustomVoiceName", customVoiceEndpointId: "YourCustomEndpointId"}
自訂語音名稱的 SSML 範例
const ssmlToPlay = "<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\"><voice name=\"YourCustomVoiceName\">Hello World!</voice></speak>";
const playSource: SsmlSource = { ssmlText: ssmlToPlay, kind: "ssmlSource", customVoiceEndpointId: "YourCustomEndpointId"};
決定要用於播放音訊的 playSource 之後,您可以選擇要對特定參與者或所有參與者播放。
播放音訊:所有參與者
在此案例中,系統會對通話中的所有參與者播放音訊。
await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.playToAll([ playSource ]);
支援插話
在向所有參與者循環播放音訊的情節中 (例如等候大廳),您可能會向大廳中的參與者播放音訊,並且讓他們隨時掌握其在佇列中的號碼。 當您使用插話支援時,這會取消進行中的音訊並播放您的新訊息。 然後,如果您想要繼續播放原始音訊,您會提出另一個播放要求。
// Interrupt media with text source
//Option1:
const playSource: TextSource = { text: "Interrupt prompt", voiceName: "en-US-NancyNeural", kind: "textSource" };
const interruptOption: PlayToAllOptions = {
loop: false,
interruptCallMediaOperation: true,
operationContext: "interruptOperationContext",
operationCallbackUrl: process.env.CALLBACK_URI + "/api/callbacks"
};
await callConnectionMedia.playToAll([playSource], interruptOption);
/*
// Interrupt media with file source
Option2:
const playSource: FileSource = {
url: MEDIA_URI + "MainMenu.wav",
kind: "fileSource"
};
const interruptOption: PlayToAllOptions = {
loop: false,
interruptCallMediaOperation: true,
operationContext: "interruptOperationContext",
operationCallbackUrl: process.env.CALLBACK_URI + "/api/callbacks"
};
await callConnectionMedia.playToAll([playSource], interruptOption);
*/
播放音訊:特定參與者
在此案例中,系統會對特定參與者播放音訊。
await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.play([ playSource ], [ targetParticipant ]);
迴圈播放音訊
您可以用迴圈選項播放暫停音樂,反覆播放至應用程式準備好接受通話者為止。 您也可以根據應用程式業務邏輯,讓呼叫者進入下一個邏輯步驟。
const playOptions: PlayOptions = { loop: true };
await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.playToAll([ playSource ], playOptions);
用音訊檔案快取增強播放
如果您要多次播放同樣的音訊檔案,則可透過應用程式提供包含音訊檔案的 sourceID 的 Azure 通訊服務。 Azure 通訊服務會快取 1 小時的此音訊檔案。
注意
快取音訊檔案不適用於動態提示。 如果您變更提供給 Azure 通訊服務的 URL,則不會立即更新快取的 URL。 更新會在現有快取過期之後發生。
const playSource: FileSource = { url: audioUri, playsourcacheid: "<playSourceId>", kind: "fileSource" };
await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.play([ playSource ], [ targetParticipant ]);
處理播放動作事件更新
您的應用程式會在回撥 URL 上收到動作生命週期事件更新,回撥 URL 會在接通電話時提供給通話自動化服務。
如何還原序列化 PlayCompleted 事件的範例:
if (event.type === "Microsoft.Communication.PlayCompleted") {
console.log("Play completed, context=%s", eventData.operationContext);
}
如何還原序列化 PlayFailed 事件的範例:
if (event.type === "Microsoft.Communication.PlayFailed") {
console.log("Play failed: data=%s", JSON.stringify(eventData));
}
如何還原序列化 PlayStarted 事件的範例:
if (event.type === "Microsoft.Communication.PlayStarted") {
console.log("Play started: data=%s", JSON.stringify(eventData));
}
若要深入了解其他支援的事件,請造訪通話自動化概觀文件。
取消播放動作
取消所有媒體作業,所有擱置的媒體作業都會取消。 這個動作也會取消其他佇列中的播放動作。
await callAutomationClient.getCallConnection(callConnectionId)
.getCallMedia()
.cancelAllOperations();
如何還原序列化 PlayCanceled 事件的範例:
if (event.type === "Microsoft.Communication.PlayCanceled") {
console.log("Play canceled, context=%s", eventData.operationContext);
}
必要條件
- 包含使用中訂用帳戶的 Azure 帳戶。如需詳細資料,請參閱建立免費帳戶。
- Azure 通訊服務資源。 請參閱建立 Azure 通訊服務資源。 儲存此資源的連接字串。
- 使用通話自動化 SDK 來建立新的 Web 服務應用程式。
- 安裝 Python 後,您可以從官方網站進行安裝。
針對 AI 功能
- 建立 Azure AI 服務並將其連線至您的 Azure 通訊服務資源。
- 為您的 Azure AI 服務資源建立自訂子網域。
建立新的 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
(選擇性) 如果您想要使用音訊檔案來播放提示,請準備您的音訊檔案
如果您還沒有音訊檔案,請先建立後再用以向參與者播放提示和訊息。 音訊檔案必須裝載於 Azure 通訊服務可存取且支援驗證的位置。 請保留 URL 複本,以便於要求播放音訊檔案時使用。 Azure 通訊服務可支援 MP3 檔案,以及採樣速率 16 KHz 的單聲道 16 位元 PCM 的 WAV 檔案。 .
您可以用我們的使用音訊內容建立工具的語音合成來測試建立自己的音訊檔案。
(選擇性) 將您的 Azure 認知服務連線到您的 Azure 通訊服務
如果您要使用文字轉換語音功能,則必須連線 Azure 認知服務至 Azure 通訊服務。
建立通話
這時您應該已熟悉開始通話。如果您需要深入了解如何撥打電話,請遵循我們的快速入門。 您也可以使用這裡提供的程式碼片段來了解如何接聽來電。
call_automation_client.answer_call(
incoming_call_context="<Incoming call context>",
callback_url="<https://sample-callback-uri>",
cognitive_services_endpoint=COGNITIVE_SERVICE_ENDPOINT,
)
播放音訊
通話一旦建立,即可透過多個選項,選擇您希望播放音訊的方式。 您可以為加入通話的參與者播放音訊,或為通話中的所有參與者播放音訊。
播放來源 - 音訊檔案
若要使用音訊檔案對參與者播放音訊,您必須確定音訊檔案是 WAV 檔案、單聲道和 16 KHz。 若要播放音訊檔案,您必須確定將具有 URI 的 Azure 通訊服務提供給您在 Azure 通訊服務可存取的位置中裝載的檔案。 SDK 中的 FileSource 類型可用來指定播放動作的音訊檔案。
play_source = FileSource(url=audioUri)
#Play multiple audio files
#file_source1 = FileSource(MAIN_MENU_PROMPT_URI)
#file_source2 = FileSource(MAIN_MENU_PROMPT_URI)
#
# play_sources = [file_source1, file_source2]
#
# call_connection_client.play_media_to_all(
# play_source=play_sources,
# interrupt_call_media_operation=False,
# operation_context="multiplePlayContext",
# operation_callback_url=CALLBACK_EVENTS_URI,
# loop=False
# )
播放來源 - 文字轉換語音
若要透過 Azure AI 服務使用文字轉換語音播放音訊,您需要提供您想要播放的文字,以及您想要使用的 SourceLocale 和 VoiceKind 或 VoiceName。 我們支援 Azure AI 服務支援的所有語音名稱,完整清單請見此處。
text_to_play = "Welcome to Contoso"
# Provide SourceLocale and VoiceKind to select an appropriate voice.
play_source = TextSource(
text=text_to_play, source_locale="en-US", voice_kind=VoiceKind.FEMALE
)
play_to = [target_participant]
call_automation_client.get_call_connection(call_connection_id).play_media(
play_source=play_source, play_to=play_to
)
#Multiple text prompts
#play_source1 = TextSource(text="Hi, This is multiple play source one call media test.", source_locale="en-US", voice_kind=VoiceKind.FEMALE)
#play_source2 = TextSource(text="Hi, This is multiple play source two call media test.", source_locale="en-US", voice_kind=VoiceKind.FEMALE)
#
#play_sources = [play_source1, play_source2]
#
#call_connection_client.play_media_to_all(
# play_source=play_sources,
# interrupt_call_media_operation=False,
# operation_context="multiplePlayContext",
# operation_callback_url=CALLBACK_EVENTS_URI,
# loop=False
#)
text_to_play = "Welcome to Contoso"
# Provide VoiceName to select a specific voice.
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural")
play_to = [target_participant]
call_automation_client.get_call_connection(call_connection_id).play_media(
play_source=play_source, play_to=play_to
)
#Play multiple text prompts
#play_source1 = TextSource(text="Hi, This is multiple play source one call media test.", voice_name=SPEECH_TO_TEXT_VOICE)
#play_source2 = TextSource(text="Hi, This is multiple play source two call media test.", voice_name=SPEECH_TO_TEXT_VOICE)
#
#play_sources = [play_source1, play_source2]
#
#call_connection_client.play_media_to_all(
# play_source=play_sources,
# interrupt_call_media_operation=False,
# operation_context="multiplePlayContext",
# operation_callback_url=CALLBACK_EVENTS_URI,
# loop=False
#)
播放來源 - 使用 SSML 的文字轉換語音
如果您想要使用 Azure AI 服務進一步自訂文字轉換語音輸出,您可以在透過通話自動化叫用您的播放動作時,使用語音合成標記語言 SSML。 使用 SSML 時,您可以微調音高、停頓、改善發音、變更說話速度、調整音量,以及歸因多個語音。
ssmlToPlay = '<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US"><voice name="en-US-JennyNeural">Hello World!</voice></speak>'
play_source = SsmlSource(ssml_text=ssmlToPlay)
play_to = [target_participant]
call_automation_client.get_call_connection(call_connection_id).play_media(
play_source=play_source, play_to=play_to
)
自訂語音模型
如果您想要更加強化提示並包含自訂語音模型,文字轉換語音播放動作現在支援這些自訂語音。 如果您嘗試為客戶提供更當地化、更個人化的體驗,或您有預設模型可能無法涵蓋您嘗試發音的字組和腔調的情況,這些是絕佳的選擇。 若要深入了如何建立和部署自訂模型,您可以閱讀本指南。
自訂語音名稱的一般文字範例
text_to_play = "Welcome to Contoso"
# Provide VoiceName to select a specific voice.
play_source = TextSource(text=text_to_play, voice_name="YourCustomVoiceName", custom_voice_endpoint_id = "YourCustomEndpointId")
play_to = [target_participant]
call_automation_client.get_call_connection(call_connection_id).play_media(
play_source=play_source, play_to=play_to
)
自訂語音名稱的 SSML 範例
ssmlToPlay = '<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US"><voice name="YourCustomVoiceName">Hello World!</voice></speak>'
play_source = SsmlSource(ssml_text=ssmlToPlay, custom_voice_endpoint_id="YourCustomEndpointId")
play_to = [target_participant]
call_automation_client.get_call_connection(call_connection_id).play_media(
play_source=play_source, play_to=play_to
)
決定要用於播放音訊的 playSource 之後,您可以選擇要對特定參與者或所有參與者播放。
播放音訊:所有參與者
對通話中的所有參與者播放預先錄製的音訊檔案。
text_to_play = "Welcome to Contoso"
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural")
call_automation_client.get_call_connection(call_connection_id).play_media(
play_source=play_source
)
支援插話
在向所有參與者循環播放音訊的情節中 (例如等候大廳),您可能會向大廳中的參與者播放音訊,並且讓他們隨時掌握其在佇列中的號碼。 當您使用插話支援時,這會取消進行中的音訊並播放您的新訊息。 然後,如果您想要繼續播放原始音訊,您會提出另一個播放要求。
# Interrupt media with text source
# Option 1
play_source = TextSource(text="This is interrupt call media test.", voice_name=SPEECH_TO_TEXT_VOICE)
call_connection_client.play_media_to_all(
play_source,
interrupt_call_media_operation=True,
operation_context="interruptContext",
operation_callback_url=CALLBACK_EVENTS_URI,
loop=False
)
# Interrupt media with file source
# Option 2
#play_source = FileSource(MAIN_MENU_PROMPT_URI)
#call_connection_client.play_media_to_all(
# play_source,
# interrupt_call_media_operation=True,
# operation_context="interruptContext",
# operation_callback_url=CALLBACK_EVENTS_URI,
# loop=False
#)
播放音訊:特定參與者
向通話中的特定參與者播放預先錄製的音訊檔案。
play_to = [target_participant]
call_automation_client.get_call_connection(call_connection_id).play_media(
play_source=play_source, play_to=play_to
)
迴圈播放音訊
您可以用迴圈選項播放暫停音樂,反覆播放至應用程式準備好接受通話者為止。 您也可以根據應用程式業務邏輯,讓呼叫者進入下一個邏輯步驟。
text_to_play = "Welcome to Contoso"
play_source = TextSource(text=text_to_play, voice_name="en-US-ElizabethNeural")
call_automation_client.get_call_connection(call_connection_id).play_media(
play_source=play_source, loop=True
)
用音訊檔案快取增強播放
如果您要多次播放同樣的音訊檔案,則可透過應用程式提供包含音訊檔案的 sourceID 的 Azure 通訊服務。 Azure 通訊服務會快取 1 小時的此音訊檔案。
注意
快取音訊檔案不適用於動態提示。 如果您變更提供給 Azure 通訊服務的 URL,則不會立即更新快取的 URL。 更新會在現有快取過期之後發生。
play_source = FileSource(url=audioUri, play_source_cache_id="<playSourceId>")
play_to = [target_participant]
call_automation_client.get_call_connection(call_connection_id).play_media(
play_source=play_source, play_to=play_to
)
處理播放動作事件更新
您的應用程式會在回撥 URL 上收到動作生命週期事件更新,回撥 URL 會在接通電話時提供給通話自動化服務。
如何還原序列化 PlayCompleted 事件的範例:
if event.type == "Microsoft.Communication.PlayCompleted":
app.logger.info("Play completed, context=%s", event.data.get("operationContext"))
如何還原序列化 PlayStarted 事件的範例:
if event.type == "Microsoft.Communication.PlayStarted":
app.logger.info("Play started, context=%s", event.data.get("operationContext"))
如何還原序列化 PlayFailed 事件的範例:
if event.type == "Microsoft.Communication.PlayFailed":
app.logger.info("Play failed: data=%s", event.data)
若要深入了解其他支援的事件,請造訪通話自動化概觀文件。
取消播放動作
取消所有媒體作業,所有擱置的媒體作業都會取消。 這個動作也會取消其他佇列中的播放動作。
call_automation_client.get_call_connection(
call_connection_id
).cancel_all_media_operations()
如何還原序列化 PlayCanceled 事件的範例:
if event.type == "Microsoft.Communication.PlayCanceled":
app.logger.info("Play canceled, context=%s", event.data.get("operationContext"))
事件代碼
狀態 | 代碼 | 子代碼 | 訊息 |
---|---|---|---|
PlayCompleted | 200 | 0 | 動作已順利完成。 |
PlayCanceled | 400 | 8508 | 動作失敗,作業已取消。 |
PlayFailed | 400 | 8535 | 動作失敗,檔案格式無效。 |
PlayFailed | 400 | 8536 | 動作失敗,無法下載檔案。 |
PlayFailed | 400 | 8565 | 動作失敗,對 Azure AI 服務的要求不正確。 檢查輸入參數。 |
PlayFailed | 401 | 8565 | 動作失敗,Azure AI 服務驗證錯誤。 |
PlayFailed | 403 | 8565 | 動作失敗,對 Azure AI 服務的要求遭禁止,要求所使用的免費訂用帳戶已用盡配額。 |
PlayFailed | 429 | 8565 | 動作失敗,要求已超過 Azure AI 服務訂用帳戶允許的並行要求數目。 |
PlayFailed | 408 | 8565 | 動作失敗,對 Azure AI 服務的要求已逾時。 |
PlayFailed | 500 | 9999 | 未知內部伺服器錯誤 |
PlayFailed | 500 | 8572 | 動作因播放服務關閉而失敗。 |
已知的限制
- 文字轉換語音的文字提示最多支援 400 個字元,如果您的提示超出此長度,建議對文字轉換語音型播放動作使用 SSML。
- 針對超過語音服務配額限制的案例,您可以依照這裡所述的步驟,要求提高此限制。
清除資源
如果您想要清除並移除通訊服務訂用帳戶,您可以刪除資源或資源群組。 刪除資源群組也會刪除與其相關聯的任何其他資源。 深入了解如何清除資源。
下一步
- 深入了解通話自動化
- 深入了解在通話中收集使用者輸入