共用方式為


用「播放」動作自訂使用者語音提示

本指南將協助您開始使用 Azure 通訊服務通話自動化 SDK 提供的播放動作,為參與者播放音訊檔案。

必要條件

針對 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); 
} 

必要條件

針對 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()); 
} 

必要條件

針對 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);
}

必要條件

針對 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。
  • 針對超過語音服務配額限制的案例,您可以依照這裡所述的步驟,要求提高此限制。

清除資源

如果您想要清除並移除通訊服務訂用帳戶,您可以刪除資源或資源群組。 刪除資源群組也會刪除與其相關聯的任何其他資源。 深入了解如何清除資源

下一步