本指南可協助您進一步了解您可使用 Azure 通訊服務供應項目的不同方式,藉以透過通話自動化 SDK 進行即時謄寫。
必要條件
- 有效訂閱的 Azure 帳戶。如需詳細資料,請參閱建立免費帳戶。
- 如需 Azure 通訊服務資源,請參閱建立 Azure 通訊服務資源
- 建立並連結 Foundry 工具與您的 Azure 通訊服務資源。
- 為您的 Azure AI 服務資源建立自訂子網域。
- 使用通話自動化 SDK 來建立新的 Web 服務應用程式。
設定 WebSocket 伺服器
Azure 通訊服務需要您的伺服器應用程式設定 WebSocket 伺服器,以即時串流謄寫。 WebSocket 是一種標準化通訊協定,可透過單一 TCP 連線提供全雙工通訊通道。 您可以選擇性地使用 Azure 服務 Azure WebApps,讓您可以建立應用程式,以透過 WebSocket 連線來接收謄寫。 請遵循本快速入門。
建立通話
在本快速入門中,假設您已熟悉如何開始通話。 如果您需要深入了解如何開始和建立通話,則可以遵循快速入門。 為了本快速入門的目的,我們將逐步執行針對來電和撥出通話啟動謄寫的程序。
使用即時轉譯時,您有一些關於何時及如何開始轉譯的選項:
選項 1 - 在接聽或建立通話時啟動
選項 2 - 在進行中通話期間啟動謄寫
選項 3 - 連線到 Azure 通訊服務 會議室通話時開始轉譯
在本教學課程中,我們會示範選項 2 和 3,在進行中的通話或連線到會議室通話時開始轉譯。 根據預設,'startTranscription' 會在接聽或建立通話時設定為 False。
建立通話並提供謄寫詳細資料
定義 ACS 的轉譯選項,以指定何時開始轉譯、指定轉譯的地區設定,以及傳送文字記錄的 Web 套接字連線。
var createCallOptions = new CreateCallOptions(callInvite, callbackUri)
{
CallIntelligenceOptions = new CallIntelligenceOptions() { CognitiveServicesEndpoint = new Uri(cognitiveServiceEndpoint) },
TranscriptionOptions = new TranscriptionOptions(new Uri(""), "en-US", false, TranscriptionTransport.Websocket)
};
CreateCallResult createCallResult = await callAutomationClient.CreateCallAsync(createCallOptions);
情感分析 (預覽)
即時追蹤交談的情緒語調,以支援客戶和專員的互動,並在必要時讓主管能夠介入。 可透過 createCall、answerCall 和 startTranscription 以公開預覽提供。
建立已啟用情感分析的通話
// Define transcription options with sentiment analysis enabled
var transcriptionOptions = new TranscriptionOptions
{
IsSentimentAnalysisEnabled = true
};
var callIntelligenceOptions = new CallIntelligenceOptions
{
CognitiveServicesEndpoint = new Uri(cognitiveServiceEndpoint)
};
var createCallOptions = new CreateCallOptions(callInvite, new Uri("https://test"))
{
CallIntelligenceOptions = callIntelligenceOptions,
TranscriptionOptions = transcriptionOptions
};
CreateCallResult createCallResult = await callAutomationClient.CreateCallAsync(createCallOptions);
接聽已啟用情感分析的通話
// Define transcription options with sentiment analysis enabled
var transcriptionOptions = new TranscriptionOptions
{
IsSentimentAnalysisEnabled = true
};
var answerCallOptions = new AnswerCallOptions(incomingCallContext, callbackUri)
{
TranscriptionOptions = transcriptionOptions
};
var answerCallResult = await client.AnswerCallAsync(answerCallOptions);
PII 修訂 (預覽)
自動識別及遮罩處理敏感資訊 (例如姓名、地址或識別碼) 以確保隱私權和法規合規性。 在 createCall、answerCall 和 startTranscription 中提供。
接聽已啟用 PII 修訂的通話
var transcriptionOptions = new TranscriptionOptions
{
PiiRedactionOptions = new PiiRedactionOptions
{
IsEnabled = true,
RedactionType = RedactionType.MaskWithCharacter
},
};
var options = new AnswerCallOptions(incomingCallContext, callbackUri)
{
TranscriptionOptions = transcriptionOptions,
};
//Answer call request
var answerCallResult = await client.AnswerCallAsync(options);
備註
啟用 PII 修訂後,您只會收到已修訂的文字。
即時語言偵測 (預覽)
自動偵測口語語言,以實現自然且如同人類的通訊,並消除手動語言選擇。 在 createCall、answerCall 和 startTranscription 中提供。
建立已啟用即時語言偵測的通話
var transcriptionOptions = new TranscriptionOptions
{
Locales = new List<string> { "en-US", "fr-FR", "hi-IN" }
};
var createCallOptions = new CreateCallOptions(callInviteOption, new Uri("https://test"))
{
TranscriptionOptions = transcriptionOptions
};
//CreateCall request
var createCallRequest = await client.CreateCallAsync(createCallOptions);
備註
若要在語言識別開始之後將其停止,請使用 updateTranscription API,並明確設定您想要用於文字記錄的語言。 這會停用自動語言偵測,並鎖定對指定語言的謄寫。
連線至會議室通話並提供謄寫詳細資料
如果您要連線到 ACS 會議室並想要使用轉譯,請設定轉譯選項,如下所示:
var transcriptionOptions = new TranscriptionOptions(
transportUri: new Uri(""),
locale: "en-US",
startTranscription: false,
transcriptionTransport: TranscriptionTransport.Websocket,
//Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
SpeechRecognitionModelEndpointId = "YourCustomSpeechRecognitionModelEndpointId"
);
var connectCallOptions = new ConnectCallOptions(new RoomCallLocator("roomId"), callbackUri)
{
CallIntelligenceOptions = new CallIntelligenceOptions()
{
CognitiveServicesEndpoint = new Uri(cognitiveServiceEndpoint)
},
TranscriptionOptions = transcriptionOptions
};
var connectResult = await client.ConnectCallAsync(connectCallOptions);
啟動謄寫
準備好開始轉錄後,您可以呼叫通話自動化服務以開始轉寫通話。
// Start transcription with options
var transcriptionOptions = new StartTranscriptionOptions
{
OperationContext = "startMediaStreamingContext",
IsSentimentAnalysisEnabled = true,
// Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
SpeechRecognitionModelEndpointId = "YourCustomSpeechRecognitionModelEndpointId"
};
// Start transcription
await callMedia.StartTranscriptionAsync(transcriptionOptions);
// Alternative: Start transcription without options
// await callMedia.StartTranscriptionAsync();
取得通話中摘要 (預覽)
使用即時摘要來增強通話工作流程。 透過在謄寫選項中啟用摘要,ACS 可以自動產生精簡的通話中回顧 (包括決策、動作項目和重要討論點) 而不需要等待通話結束。 這可協助小組保持一致,並加快即時交談期間後續追蹤的速度。
// Define transcription options with call summarization enabled
var transcriptionOptions = new TranscriptionOptions
{
SummarizationOptions = new SummarizationOptions
{
Locale = "en-US"
}
};
// Answer call with transcription options
var answerCallOptions = new AnswerCallOptions(incomingCallContext, callbackUri)
{
TranscriptionOptions = transcriptionOptions
};
var answerCallResult = await client.AnswerCallAsync(answerCallOptions);
額外標題:
相互關聯識別碼和呼叫連線標識碼現在包含在 WebSocket 標頭中,以改善可追蹤性和 x-ms-call-correlation-idx-ms-call-connection-id。
接收謄寫串流
當轉譯開始時,您的websocket會以第一個封包的形式接收轉譯元數據承載。
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
接收謄寫資料
接收中繼資料之後,Web Socket 接收的下一個封包將是謄寫音訊的 TranscriptionData。
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "Testing transcription.",
"format": "display",
"confidence": 0.695223331451416,
"offset": 2516998782481234400,
"words": [
{
"text": "testing",
"offset": 2516998782481234400
},
{
"text": "testing",
"offset": 2516998782481234400
}
],
"participantRawID": "8:acs:",
"resultStatus": "Final"
}
}
接收已啟用 AI 功能的謄寫資料流 (預覽)
呼叫期間啟用謄寫時,Azure 通訊服務會發出中繼資料,描述謄寫工作階段的設定和內容。 這包括地區設定、通話連接識別碼、情感分析設定和 PII 修訂喜好設定等詳細資料。 開發人員可以使用此承載來確認謄寫設定、稽核設定,或疑難排解 AI 所增強即時謄寫功能的相關問題。
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "863b5e55-de0d-4fc3-8e58-2d68e976b5ad",
"locale": "en-US",
"callConnectionId": "02009180-9dc2-429b-a3eb-d544b7b6a0e1",
"correlationId": "62c8215b-5276-4d3c-bb6d-06a1b114651b",
"speechModelEndpointId": null,
"locales": [],
"enableSentimentAnalysis": true,
"piiRedactionOptions": {
"enable": true,
"redactionType": "MaskWithCharacter"
}
}
}
接收已啟用 AI 功能的謄寫資料 (預覽)
初始中繼資料封包之後,您的 WebSocket 連接會開始接收轉譯音訊中每個區段的 TranscriptionData 事件。 這些封包包括轉譯的文字、信賴度分數、時間資訊,以及 (如果啟用) 情感分析和 PII 修訂。 此資料可用來建立即時儀表板、觸發工作流程,或在通話期間分析交談動態。
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "My date of birth is *********.",
"format": "display",
"confidence": 0.8726407289505005,
"offset": 309058340,
"duration": 31600000,
"words": [],
"participantRawID": "4:+917020276722",
"resultStatus": "Final",
"sentimentAnalysisResult": {
"sentiment": "neutral"
}
}
}
處理 Web Socket 伺服器中的謄寫串流
using WebServerApi;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseWebSockets();
app.Map("/ws", async context =>
{
if (context.WebSockets.IsWebSocketRequest)
{
using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
await HandleWebSocket.Echo(webSocket);
}
else
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
}
});
app.Run();
對您的 Websocket 處理程式碼的更新
using Azure.Communication.CallAutomation;
using System.Net.WebSockets;
using System.Text;
namespace WebServerApi
{
public class HandleWebSocket
{
public static async Task Echo(WebSocket webSocket)
{
var buffer = new byte[1024 * 4];
var receiveResult = await webSocket.ReceiveAsync(
new ArraySegment(buffer), CancellationToken.None);
while (!receiveResult.CloseStatus.HasValue)
{
string msg = Encoding.UTF8.GetString(buffer, 0, receiveResult.Count);
var response = StreamingDataParser.Parse(msg);
if (response != null)
{
if (response is AudioMetadata audioMetadata)
{
Console.WriteLine("***************************************************************************************");
Console.WriteLine("MEDIA SUBSCRIPTION ID-->"+audioMetadata.MediaSubscriptionId);
Console.WriteLine("ENCODING-->"+audioMetadata.Encoding);
Console.WriteLine("SAMPLE RATE-->"+audioMetadata.SampleRate);
Console.WriteLine("CHANNELS-->"+audioMetadata.Channels);
Console.WriteLine("LENGTH-->"+audioMetadata.Length);
Console.WriteLine("***************************************************************************************");
}
if (response is AudioData audioData)
{
Console.WriteLine("***************************************************************************************");
Console.WriteLine("DATA-->"+audioData.Data);
Console.WriteLine("TIMESTAMP-->"+audioData.Timestamp);
Console.WriteLine("IS SILENT-->"+audioData.IsSilent);
Console.WriteLine("***************************************************************************************");
}
if (response is TranscriptionMetadata transcriptionMetadata)
{
Console.WriteLine("***************************************************************************************");
Console.WriteLine("TRANSCRIPTION SUBSCRIPTION ID-->"+transcriptionMetadata.TranscriptionSubscriptionId);
Console.WriteLine("LOCALE-->"+transcriptionMetadata.Locale);
Console.WriteLine("CALL CONNECTION ID--?"+transcriptionMetadata.CallConnectionId);
Console.WriteLine("CORRELATION ID-->"+transcriptionMetadata.CorrelationId);
Console.WriteLine("LOCALES-->" + transcriptionMetadata.Locales);
Console.WriteLine("PII REDACTION OPTIONS ISENABLED-->" + transcriptionMetadata.PiiRedactionOptions?.IsEnabled);
Console.WriteLine("PII REDACTION OPTIONS - REDACTION TYPE-->" + transcriptionMetadata.PiiRedactionOptions?.RedactionType);
Console.WriteLine("***************************************************************************************");
}
if (response is TranscriptionData transcriptionData)
{
Console.WriteLine("***************************************************************************************");
Console.WriteLine("TEXT-->"+transcriptionData.Text);
Console.WriteLine("FORMAT-->"+transcriptionData.Format);
Console.WriteLine("OFFSET-->"+transcriptionData.Offset);
Console.WriteLine("DURATION-->"+transcriptionData.Duration);
Console.WriteLine("PARTICIPANT-->"+transcriptionData.Participant.RawId);
Console.WriteLine("CONFIDENCE-->"+transcriptionData.Confidence);
Console.WriteLine("SENTIMENT ANALYSIS RESULT-->" + transcriptionData.SentimentAnalysisResult?.Sentiment);
foreach (var word in transcriptionData.Words)
{
Console.WriteLine("TEXT-->"+word.Text);
Console.WriteLine("OFFSET-->"+word.Offset);
Console.WriteLine("DURATION-->"+word.Duration);
}
Console.WriteLine("***************************************************************************************");
}
}
await webSocket.SendAsync(
new ArraySegment(buffer, 0, receiveResult.Count),
receiveResult.MessageType,
receiveResult.EndOfMessage,
CancellationToken.None);
receiveResult = await webSocket.ReceiveAsync(
new ArraySegment(buffer), CancellationToken.None);
}
await webSocket.CloseAsync(
receiveResult.CloseStatus.Value,
receiveResult.CloseStatusDescription,
CancellationToken.None);
}
}
}
更新謄寫
如果您的應用程式允許使用者選取使用者慣用的語言,您可能也想要擷取該語言的謄寫。 若要這麼做,通話自動化 SDK 可讓您更新謄寫地區設定。
UpdateTranscriptionOptions updateTranscriptionOptions = new UpdateTranscriptionOptions(locale)
{
OperationContext = "UpdateTranscriptionContext",
//Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
SpeechRecognitionModelEndpointId = "YourCustomSpeechRecognitionModelEndpointId"
};
await client.GetCallConnection(callConnectionId).GetCallMedia().UpdateTranscriptionAsync(updateTranscriptionOptions);
停止文字轉錄
當您的應用程式必須停止接聽謄寫時,您可以使用 StopTranscription 要求以讓通話自動化知道要停止將文字記錄資料傳送至您的 Web Socket。
StopTranscriptionOptions stopOptions = new StopTranscriptionOptions()
{
OperationContext = "stopTranscription"
};
await callMedia.StopTranscriptionAsync(stopOptions);
建立通話並提供謄寫詳細資料
定義 ACS 的轉譯選項,以指定何時開始轉譯、轉譯的地區設定,以及傳送文字記錄的 Web 套接字連線。
CallInvite callInvite = new CallInvite(target, caller);
CallIntelligenceOptions callIntelligenceOptions = new CallIntelligenceOptions()
.setCognitiveServicesEndpoint(appConfig.getCognitiveServiceEndpoint());
TranscriptionOptions transcriptionOptions = new TranscriptionOptions(
appConfig.getWebSocketUrl(),
TranscriptionTransport.WEBSOCKET,
"en-US",
false,
"your-endpoint-id-here" // speechRecognitionEndpointId
);
CreateCallOptions createCallOptions = new CreateCallOptions(callInvite, appConfig.getCallBackUri());
createCallOptions.setCallIntelligenceOptions(callIntelligenceOptions);
createCallOptions.setTranscriptionOptions(transcriptionOptions);
Response result = client.createCallWithResponse(createCallOptions, Context.NONE);
return result.getValue().getCallConnectionProperties().getCallConnectionId();
情感分析 (預覽)
即時追蹤交談的情緒語調,以支援客戶和專員的互動,並在必要時讓主管能夠介入。 可透過 createCall、answerCall 和 startTranscription 以公開預覽提供。
建立已啟用情感分析的通話
CallInvite callInvite = new CallInvite(target, caller);
CallIntelligenceOptions callIntelligenceOptions = new CallIntelligenceOptions()
.setCognitiveServicesEndpoint(cognitiveServicesEndpoint);
TranscriptionOptions transcriptionOptions = new TranscriptionOptions("en-ES")
.setTransportUrl(websocketUriHost)
.setEnableSentimentAnalysis(true) // Enable sentiment analysis
.setLocales(locales);
CreateCallOptions createCallOptions = new CreateCallOptions(callInvite, callbackUri.toString())
.setCallIntelligenceOptions(callIntelligenceOptions)
.setTranscriptionOptions(transcriptionOptions);
// Create call request
Response<CreateCallResult> result = client.createCallWithResponse(createCallOptions, Context.NONE);
接聽已啟用情感分析的通話
TranscriptionOptions transcriptionOptions = new TranscriptionOptions("en-ES")
.setTransportUrl(websocketUriHost)
.setEnableSentimentAnalysis(true) // Enable sentiment analysis
.setLocales(locales);
AnswerCallOptions answerCallOptions = new AnswerCallOptions(data.getString("incomingCallContext"), callbackUri)
.setCallIntelligenceOptions(callIntelligenceOptions)
.setTranscriptionOptions(transcriptionOptions);
// Answer call request
Response<AnswerCallResult> answerCallResponse = client.answerCallWithResponse(answerCallOptions, Context.NONE);
PII 修訂 (預覽)
自動識別及遮罩處理敏感資訊 (例如姓名、地址或識別碼) 以確保隱私權和法規合規性。 在 createCall、answerCall 和 startTranscription 中提供。
接聽已啟用 PII 修訂的通話
PiiRedactionOptions piiRedactionOptions = new PiiRedactionOptions()
.setEnabled(true)
.setRedactionType(RedactionType.MASK_WITH_CHARACTER);
TranscriptionOptions transcriptionOptions = new TranscriptionOptions("en-ES")
.setTransportUrl(websocketUriHost)
.setPiiRedactionOptions(piiRedactionOptions)
.setLocales(locales);
AnswerCallOptions answerCallOptions = new AnswerCallOptions(data.getString("incomingCallContext"), callbackUri)
.setCallIntelligenceOptions(callIntelligenceOptions)
.setTranscriptionOptions(transcriptionOptions);
// Answer call request
Response<AnswerCallResult> answerCallResponse = client.answerCallWithResponse(answerCallOptions, Context.NONE);
備註
啟用 PII 修訂後,您只會收到已修訂的文字。
即時語言偵測 (預覽)
自動偵測口語語言,以實現自然且如同人類的通訊,並消除手動語言選擇。 在 createCall、answerCall 和 startTranscription 中提供。
建立已啟用即時語言偵測的通話
var transcriptionOptions = new TranscriptionOptions
{
Locales = new List<string> { "en-US", "fr-FR", "hi-IN" },
};
var createCallOptions = new CreateCallOptions(callInviteOption, new Uri("https://test"))
{
TranscriptionOptions = transcriptionOptions
};
var createCallResult = await client.CreateCallAsync(createCallOptions);
備註
若要在語言識別開始之後將其停止,請使用 updateTranscription API,並明確設定您想要用於文字記錄的語言。 這會停用自動語言偵測,並鎖定對指定語言的謄寫。
連線至會議室通話並提供謄寫詳細資料
如果您要連線到 ACS 會議室並想要使用轉譯,請設定轉譯選項,如下所示:
TranscriptionOptions transcriptionOptions = new TranscriptionOptions(
appConfig.getWebSocketUrl(),
TranscriptionTransport.WEBSOCKET,
"en-US",
false,
"your-endpoint-id-here" // speechRecognitionEndpointId
);
ConnectCallOptions connectCallOptions = new ConnectCallOptions(new RoomCallLocator("roomId"), appConfig.getCallBackUri())
.setCallIntelligenceOptions(
new CallIntelligenceOptions()
.setCognitiveServicesEndpoint(appConfig.getCognitiveServiceEndpoint())
)
.setTranscriptionOptions(transcriptionOptions);
ConnectCallResult connectCallResult = Objects.requireNonNull(client
.connectCallWithResponse(connectCallOptions)
.block())
.getValue();
啟動謄寫
準備好開始轉錄後,您可以呼叫通話自動化服務以開始轉寫通話。
//Option 1: Start transcription with options
StartTranscriptionOptions transcriptionOptions = new StartTranscriptionOptions()
.setOperationContext("startMediaStreamingContext");
client.getCallConnection(callConnectionId)
.getCallMedia()
.startTranscriptionWithResponse(transcriptionOptions, Context.NONE);
// Alternative: Start transcription without options
// client.getCallConnection(callConnectionId)
// .getCallMedia()
// .startTranscription();
取得通話中摘要 (預覽)
使用即時摘要來增強通話工作流程。 透過在謄寫選項中啟用摘要,ACS 可以自動產生精簡的通話中回顧 (包括決策、動作項目和重要討論點) 而不需要等待通話結束。 這可協助小組保持一致,並加快即時交談期間後續追蹤的速度。
SummarizationOptions summarizationOptions = new SummarizationOptions()
.setEnableEndCallSummary(true)
.setLocale("en-US");
TranscriptionOptions transcriptionOptions = new TranscriptionOptions("en-ES")
.setTransportUrl(websocketUriHost)
.setSummarizationOptions(summarizationOptions)
.setLocales(locales);
AnswerCallOptions answerCallOptions = new AnswerCallOptions(data.getString("incomingCallContext"), callbackUri)
.setCallIntelligenceOptions(callIntelligenceOptions)
.setTranscriptionOptions(transcriptionOptions);
// Answer call request
Response<AnswerCallResult> answerCallResponse = client.answerCallWithResponse(answerCallOptions, Context.NONE);
額外標題:
相互關聯識別碼和呼叫連線標識碼現在包含在 WebSocket 標頭中,以改善可追蹤性和 x-ms-call-correlation-idx-ms-call-connection-id。
接收謄寫串流
當轉譯開始時,您的websocket會以第一個封包的形式接收轉譯元數據承載。
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
接收謄寫資料
接收中繼資料之後,Web Socket 接收的下一個封包將是謄寫音訊的 TranscriptionData。
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "Testing transcription.",
"format": "display",
"confidence": 0.695223331451416,
"offset": 2516998782481234400,
"words": [
{
"text": "testing",
"offset": 2516998782481234400
},
{
"text": "testing",
"offset": 2516998782481234400
}
],
"participantRawID": "8:acs:",
"resultStatus": "Final"
}
}
接收已啟用 AI 功能的謄寫資料流 (預覽)
呼叫期間啟用謄寫時,Azure 通訊服務會發出中繼資料,描述謄寫工作階段的設定和內容。 這包括地區設定、通話連接識別碼、情感分析設定和 PII 修訂喜好設定等詳細資料。 開發人員可以使用此承載來確認謄寫設定、稽核設定,或疑難排解 AI 所增強即時謄寫功能的相關問題。
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "863b5e55-de0d-4fc3-8e58-2d68e976b5ad",
"locale": "en-US",
"callConnectionId": "02009180-9dc2-429b-a3eb-d544b7b6a0e1",
"correlationId": "62c8215b-5276-4d3c-bb6d-06a1b114651b",
"speechModelEndpointId": null,
"locales": [],
"enableSentimentAnalysis": true,
"piiRedactionOptions": {
"enable": true,
"redactionType": "MaskWithCharacter"
}
}
}
接收已啟用 AI 功能的謄寫資料 (預覽)
初始中繼資料封包之後,您的 WebSocket 連接會開始接收轉譯音訊中每個區段的 TranscriptionData 事件。 這些封包包括轉譯的文字、信賴度分數、時間資訊,以及 (如果啟用) 情感分析和 PII 修訂。 此資料可用來建立即時儀表板、觸發工作流程,或在通話期間分析交談動態。
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "My date of birth is *********.",
"format": "display",
"confidence": 0.8726407289505005,
"offset": 309058340,
"duration": 31600000,
"words": [],
"participantRawID": "4:+917020276722",
"resultStatus": "Final",
"sentimentAnalysisResult": {
"sentiment": "neutral"
}
}
}
處理 Web Socket 伺服器中的謄寫串流
package com.example;
import org.glassfish.tyrus.server.Server;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class App {
public static void main(String[] args) {
Server server = new Server("localhost", 8081, "/ws", null, WebSocketServer.class);
try {
server.start();
System.out.println("Web socket running on port 8081...");
System.out.println("wss://localhost:8081/ws/server");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
reader.readLine();
} catch (Exception e) {
e.printStackTrace();
} finally {
server.stop();
}
}
}
對您的 Websocket 處理程式碼的更新
package com.example;
import javax.websocket.OnMessage;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import com.azure.communication.callautomation.models.streaming.StreamingData;
import com.azure.communication.callautomation.models.streaming.StreamingDataParser;
import com.azure.communication.callautomation.models.streaming.media.AudioData;
import com.azure.communication.callautomation.models.streaming.media.AudioMetadata;
import com.azure.communication.callautomation.models.streaming.transcription.TranscriptionData;
import com.azure.communication.callautomation.models.streaming.transcription.TranscriptionMetadata;
import com.azure.communication.callautomation.models.streaming.transcription.Word;
@ServerEndpoint("/server")
public class WebSocketServer {
@OnMessage
public void onMessage(String message, Session session) {
StreamingData data = StreamingDataParser.parse(message);
if (data instanceof AudioMetadata) {
AudioMetadata audioMetaData = (AudioMetadata) data;
System.out.println("----------------------------------------------------------------");
System.out.println("SUBSCRIPTION ID: --> " + audioMetaData.getMediaSubscriptionId());
System.out.println("ENCODING: --> " + audioMetaData.getEncoding());
System.out.println("SAMPLE RATE: --> " + audioMetaData.getSampleRate());
System.out.println("CHANNELS: --> " + audioMetaData.getChannels());
System.out.println("LENGTH: --> " + audioMetaData.getLength());
System.out.println("----------------------------------------------------------------");
}
if (data instanceof AudioData) {
AudioData audioData = (AudioData) data;
System.out.println("----------------------------------------------------------------");
System.out.println("DATA: --> " + audioData.getData());
System.out.println("TIMESTAMP: --> " + audioData.getTimestamp());
System.out.println("IS SILENT: --> " + audioData.isSilent());
System.out.println("----------------------------------------------------------------");
}
if (data instanceof TranscriptionMetadata) {
TranscriptionMetadata transcriptionMetadata = (TranscriptionMetadata) data;
System.out.println("----------------------------------------------------------------");
System.out.println("TRANSCRIPTION SUBSCRIPTION ID: --> " + transcriptionMetadata.getTranscriptionSubscriptionId());
System.out.println("LOCALE: --> " + transcriptionMetadata.getLocale());
System.out.println("CALL CONNECTION ID: --> " + transcriptionMetadata.getCallConnectionId());
System.out.println("CORRELATION ID: --> " + transcriptionMetadata.getCorrelationId());
// Check for PII Redaction Options locale
if (transcriptionMetadata.getPiiRedactionOptions() != null &&
transcriptionMetadata.getPiiRedactionOptions().getLocale() != null) {
System.out.println("PII Redaction Locale: --> " + transcriptionMetadata.getPiiRedactionOptions().getLocale());
}
// Check for detected locales
if (transcriptionMetadata.getLocales() != null) {
System.out.println("Detected Locales: --> " + transcriptionMetadata.getLocales());
}
System.out.println("----------------------------------------------------------------");
}
if (data instanceof TranscriptionData) {
TranscriptionData transcriptionData = (TranscriptionData) data;
System.out.println("----------------------------------------------------------------");
System.out.println("TEXT: --> " + transcriptionData.getText());
System.out.println("FORMAT: --> " + transcriptionData.getFormat());
System.out.println("CONFIDENCE: --> " + transcriptionData.getConfidence());
System.out.println("OFFSET: --> " + transcriptionData.getOffset());
System.out.println("DURATION: --> " + transcriptionData.getDuration());
System.out.println("RESULT STATUS: --> " + transcriptionData.getResultStatus());
for (Word word : transcriptionData.getWords()) {
System.out.println("Text: --> " + word.getText());
System.out.println("Offset: --> " + word.getOffset());
System.out.println("Duration: --> " + word.getDuration());
}
System.out.println("SENTIMENT:-->" + transcriptionData.getSentimentAnalysisResult().getSentiment());
System.out.println("LANGUAGE IDENTIFIED:-->" + transcriptionData.getLanguageIdentified());
System.out.println("----------------------------------------------------------------");
}
}
}
更新謄寫
如果您的應用程式允許使用者選取使用者慣用的語言,您可能也想要擷取該語言的謄寫。 若要這麼做,通話自動化 SDK 可讓您更新謄寫地區設定。
UpdateTranscriptionOptions transcriptionOptions = new UpdateTranscriptionOptions()
.setLocale(newLocale)
.setOperationContext("transcriptionContext")
.setSpeechRecognitionEndpointId("your-endpoint-id-here");
client.getCallConnection(callConnectionId)
.getCallMedia()
.updateTranscriptionWithResponse(transcriptionOptions, Context.NONE);
停止文字轉錄
當您的應用程式必須停止接聽謄寫時,您可以使用 StopTranscription 要求以讓通話自動化知道要停止將文字記錄資料傳送至您的 Web Socket。
// Option 1: Stop transcription with options
StopTranscriptionOptions stopTranscriptionOptions = new StopTranscriptionOptions()
.setOperationContext("stopTranscription");
client.getCallConnection(callConnectionId)
.getCallMedia()
.stopTranscriptionWithResponse(stopTranscriptionOptions, Context.NONE);
// Alternative: Stop transcription without options
// client.getCallConnection(callConnectionId)
// .getCallMedia()
// .stopTranscription();
建立通話並提供謄寫詳細資料
定義 ACS 的轉譯選項,以指定何時開始轉譯、轉譯的地區設定,以及傳送文字記錄的 Web 套接字連線。
const transcriptionOptions = {
transportUrl: "",
transportType: "websocket",
locale: "en-US",
startTranscription: false,
speechRecognitionModelEndpointId: "YOUR_CUSTOM_SPEECH_RECOGNITION_MODEL_ID"
};
const options = {
callIntelligenceOptions: {
cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT
},
transcriptionOptions: transcriptionOptions
};
console.log("Placing outbound call...");
acsClient.createCall(callInvite, process.env.CALLBACK_URI + "/api/callbacks", options);
情感分析 (預覽)
即時追蹤交談的情緒語調,以支援客戶和專員的互動,並在必要時讓主管能夠介入。 可透過 createCall、answerCall 和 startTranscription 以公開預覽提供。
建立已啟用情感分析的通話
const transcriptionOptions = {
transportUrl: "",
transportType: "websocket",
locale: "en-US",
startTranscription: false,
enableSentimentAnalysis: true,
speechRecognitionModelEndpointId: "YOUR_CUSTOM_SPEECH_RECOGNITION_MODEL_ID"
};
const options = {
callIntelligenceOptions: {
cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT
},
transcriptionOptions: transcriptionOptions
};
console.log("Placing outbound call...");
acsClient.createCall(callInvite, process.env.CALLBACK_URI + "/api/callbacks", options);
接聽已啟用情感分析的通話
const transcriptionOptions: TranscriptionOptions = {
transportUrl: transportUrl,
transportType: "websocket",
startTranscription: true,
enableSentimentAnalysis: true
};
const answerCallOptions: AnswerCallOptions = {
callIntelligenceOptions: {
cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT
},
transcriptionOptions: transcriptionOptions,
enableLoopbackAudio: true
};
await acsClient.answerCall(incomingCallContext, callbackUri, answerCallOptions);
PII 修訂 (預覽)
自動識別及遮罩處理敏感資訊 (例如姓名、地址或識別碼) 以確保隱私權和法規合規性。 在 createCall、answerCall 和 startTranscription 中提供。
接聽已啟用 PII 修訂的通話
const transcriptionOptions: TranscriptionOptions = {
transportUrl: transportUrl,
transportType: "websocket",
startTranscription: true,
piiRedactionOptions: {
enable: true,
redactionType: "maskWithCharacter"
}
};
const answerCallOptions: AnswerCallOptions = {
callIntelligenceOptions: {
cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT
},
transcriptionOptions: transcriptionOptions,
enableLoopbackAudio: true
};
await acsClient.answerCall(incomingCallContext, callbackUri, answerCallOptions);
備註
啟用 PII 修訂後,您只會收到已修訂的文字。
即時語言偵測 (預覽)
自動偵測口語語言,以實現自然且如同人類的通訊,並消除手動語言選擇。 在 createCall、answerCall 和 startTranscription 中提供。
建立已啟用即時語言偵測的通話
const transcriptionOptions: TranscriptionOptions = {
transportUrl: transportUrl,
transportType: "websocket",
startTranscription: true,
locales: ["es-ES", "en-US"]
};
const createCallOptions: CreateCallOptions = {
callIntelligenceOptions: {
cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT
},
transcriptionOptions: transcriptionOptions,
operationContext: "CreatPSTNCallContext",
enableLoopbackAudio: true
};
備註
若要在語言識別開始之後將其停止,請使用 updateTranscription API,並明確設定您想要用於文字記錄的語言。 這會停用自動語言偵測,並鎖定對指定語言的謄寫。
連線至會議室通話並提供謄寫詳細資料
如果您要連線到 ACS 會議室並想要使用轉譯,請設定轉譯選項,如下所示:
const transcriptionOptions = {
transportUri: "",
locale: "en-US",
transcriptionTransport: "websocket",
startTranscription: false,
speechRecognitionModelEndpointId: "YOUR_CUSTOM_SPEECH_RECOGNITION_MODEL_ID"
};
const callIntelligenceOptions = {
cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT
};
const connectCallOptions = {
callIntelligenceOptions: callIntelligenceOptions,
transcriptionOptions: transcriptionOptions
};
const callLocator = {
id: roomId,
kind: "roomCallLocator"
};
const connectResult = await client.connectCall(callLocator, callBackUri, connectCallOptions);
啟動謄寫
準備好開始轉錄後,您可以呼叫通話自動化服務以開始轉寫通話。
const startTranscriptionOptions = {
locale: "en-AU",
operationContext: "startTranscriptionContext"
};
// Start transcription with options
await callMedia.startTranscription(startTranscriptionOptions);
// Alternative: Start transcription without options
// await callMedia.startTranscription();
取得通話中摘要 (預覽)
使用即時摘要來增強通話工作流程。 透過在謄寫選項中啟用摘要,ACS 可以自動產生精簡的通話中回顧 (包括決策、動作項目和重要討論點) 而不需要等待通話結束。 這可協助小組保持一致,並加快即時交談期間後續追蹤的速度。
const transcriptionOptions: TranscriptionOptions = {
transportUrl: transportUrl,
transportType: "websocket",
startTranscription: true,
summarizationOptions: {
enableEndCallSummary: true,
locale: "es-ES"
}
};
const answerCallOptions: AnswerCallOptions = {
callIntelligenceOptions: {
cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT
},
transcriptionOptions: transcriptionOptions,
enableLoopbackAudio: true
};
await acsClient.answerCall(incomingCallContext, callbackUri, answerCallOptions);
額外標題:
相互關聯識別碼和呼叫連線標識碼現在包含在 WebSocket 標頭中,以改善可追蹤性和 x-ms-call-correlation-idx-ms-call-connection-id。
接收謄寫串流
當轉譯開始時,您的websocket會以第一個封包的形式接收轉譯元數據承載。
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
接收謄寫資料
接收中繼資料之後,Web Socket 接收的下一個封包將是謄寫音訊的 TranscriptionData。
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "Testing transcription.",
"format": "display",
"confidence": 0.695223331451416,
"offset": 2516998782481234400,
"words": [
{
"text": "testing",
"offset": 2516998782481234400
},
{
"text": "testing",
"offset": 2516998782481234400
}
],
"participantRawID": "8:acs:",
"resultStatus": "Final"
}
}
接收已啟用 AI 功能的謄寫資料流 (預覽)
呼叫期間啟用謄寫時,Azure 通訊服務會發出中繼資料,描述謄寫工作階段的設定和內容。 這包括地區設定、通話連接識別碼、情感分析設定和 PII 修訂喜好設定等詳細資料。 開發人員可以使用此承載來確認謄寫設定、稽核設定,或疑難排解 AI 所增強即時謄寫功能的相關問題。
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "863b5e55-de0d-4fc3-8e58-2d68e976b5ad",
"locale": "en-US",
"callConnectionId": "02009180-9dc2-429b-a3eb-d544b7b6a0e1",
"correlationId": "62c8215b-5276-4d3c-bb6d-06a1b114651b",
"speechModelEndpointId": null,
"locales": [],
"enableSentimentAnalysis": true,
"piiRedactionOptions": {
"enable": true,
"redactionType": "MaskWithCharacter"
}
}
}
接收已啟用 AI 功能的謄寫資料 (預覽)
初始中繼資料封包之後,您的 WebSocket 連接會開始接收轉譯音訊中每個區段的 TranscriptionData 事件。 這些封包包括轉譯的文字、信賴度分數、時間資訊,以及 (如果啟用) 情感分析和 PII 修訂。 此資料可用來建立即時儀表板、觸發工作流程,或在通話期間分析交談動態。
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "My date of birth is *********.",
"format": "display",
"confidence": 0.8726407289505005,
"offset": 309058340,
"duration": 31600000,
"words": [],
"participantRawID": "4:+917020276722",
"resultStatus": "Final",
"sentimentAnalysisResult": {
"sentiment": "neutral"
}
}
}
處理 Web Socket 伺服器中的謄寫串流
import WebSocket from 'ws';
import { streamingData } from '@azure/communication-call-automation/src/util/streamingDataParser';
const wss = new WebSocket.Server({ port: 8081 });
wss.on('connection', (ws) => {
console.log('Client connected');
ws.on('message', (packetData) => {
const decoder = new TextDecoder();
const stringJson = decoder.decode(packetData);
console.log("STRING JSON =>", stringJson);
const response = streamingData(packetData);
const kind = response?.kind;
if (kind === "TranscriptionMetadata") {
console.log("--------------------------------------------");
console.log("Transcription Metadata");
console.log("CALL CONNECTION ID: -->", response.callConnectionId);
console.log("CORRELATION ID: -->", response.correlationId);
console.log("LOCALE: -->", response.locale);
console.log("SUBSCRIPTION ID: -->", response.subscriptionId);
console.log("SPEECH MODEL ENDPOINT: -->", response.speechRecognitionModelEndpointId);
console.log("IS SENTIMENT ANALYSIS ENABLED: -->", response.enableSentimentAnalysis);
if (response.piiRedactionOptions) {
console.log("PII REDACTION ENABLED: -->", response.piiRedactionOptions.enable);
console.log("PII REDACTION TYPE: -->", response.piiRedactionOptions.redactionType);
}
if (response.locales) {
response.locales.forEach((language) => {
console.log("LOCALE DETECTED: -->", language);
});
}
console.log("--------------------------------------------");
} else if (kind === "TranscriptionData") {
console.log("--------------------------------------------");
console.log("Transcription Data");
console.log("TEXT: -->", response.text);
console.log("FORMAT: -->", response.format);
console.log("CONFIDENCE: -->", response.confidence);
console.log("OFFSET IN TICKS: -->", response.offsetInTicks);
console.log("DURATION IN TICKS: -->", response.durationInTicks);
console.log("RESULT STATE: -->", response.resultState);
if (response.participant?.phoneNumber) {
console.log("PARTICIPANT PHONE NUMBER: -->", response.participant.phoneNumber);
}
if (response.participant?.communicationUserId) {
console.log("PARTICIPANT USER ID: -->", response.participant.communicationUserId);
}
if (response.words?.length) {
response.words.forEach((word) => {
console.log("WORD TEXT: -->", word.text);
console.log("WORD DURATION IN TICKS: -->", word.durationInTicks);
console.log("WORD OFFSET IN TICKS: -->", word.offsetInTicks);
});
}
if (response.sentimentAnalysisResult) {
console.log("SENTIMENT: -->", response.sentimentAnalysisResult.sentiment);
}
console.log("LANGUAGE IDENTIFIED: -->", response.languageIdentified);
console.log("--------------------------------------------");
}
});
ws.on('close', () => {
console.log('Client disconnected');
});
});
console.log('WebSocket server running on port 8081');
更新謄寫
如果您的應用程式允許使用者選取使用者慣用的語言,您可能也想要擷取該語言的謄寫。 若要執行這項工作,呼叫自動化 SDK 可讓您更新轉譯地區設定。
async function updateTranscriptionAsync() {
const options: UpdateTranscriptionOptions = {
operationContext: "updateTranscriptionContext",
speechRecognitionModelEndpointId: "YOUR_CUSTOM_SPEECH_RECOGNITION_MODEL_ID"
};
await acsClient
.getCallConnection(callConnectionId)
.getCallMedia()
.updateTranscription("en-au", options);
}
停止文字轉錄
當您的應用程式必須停止接聽謄寫時,您可以使用 StopTranscription 要求以讓通話自動化知道要停止將文字記錄資料傳送至您的 Web Socket。
const stopTranscriptionOptions = {
operationContext: "stopTranscriptionContext"
};
// Stop transcription with options
await callMedia.stopTranscription(stopTranscriptionOptions);
// Alternative: Stop transcription without options
// await callMedia.stopTranscription();
建立通話並提供謄寫詳細資料
定義 ACS 的轉譯選項,以指定何時開始轉譯、轉譯的地區設定,以及傳送文字記錄的 Web 套接字連線。
transcription_options = TranscriptionOptions(
transport_url="WEBSOCKET_URI_HOST",
transport_type=TranscriptionTransportType.WEBSOCKET,
locale="en-US",
start_transcription=False,
#Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
speech_recognition_model_endpoint_id = "YourCustomSpeechRecognitionModelEndpointId"
);
)
call_connection_properties = call_automation_client.create_call(
target_participant,
CALLBACK_EVENTS_URI,
cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT,
source_caller_id_number=source_caller,
transcription=transcription_options
)
情感分析 (預覽)
即時追蹤交談的情緒語調,以支援客戶和專員的互動,並在必要時讓主管能夠介入。 可透過 createCall、answerCall 和 startTranscription 以公開預覽提供。
建立已啟用情感分析的通話
transcription_options = TranscriptionOptions(
transport_url=self.transport_url,
transport_type=StreamingTransportType.WEBSOCKET,
locale="en-US",
start_transcription=False,
enable_sentiment_analysis=True
)
call_connection_properties = await call_automation_client.create_call(
target_participant=[target_participant],
callback_url=CALLBACK_EVENTS_URI,
cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT,
source_caller_id_number=source_caller,
transcription=transcription_options
)
接聽已啟用情感分析的通話
transcription_options = TranscriptionOptions(
transport_url=self.transport_url,
transport_type=StreamingTransportType.WEBSOCKET,
locale="en-US",
start_transcription=False,
enable_sentiment_analysis=True
)
answer_call_result = await call_automation_client.answer_call(
incoming_call_context=incoming_call_context,
transcription=transcription_options,
cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT,
callback_url=callback_uri,
enable_loopback_audio=True,
operation_context="answerCallContext"
)
PII 修訂 (預覽)
自動識別及遮罩處理敏感資訊 (例如姓名、地址或識別碼) 以確保隱私權和法規合規性。 在 createCall、answerCall 和 startTranscription 中提供。
接聽已啟用 PII 修訂的通話
transcription_options = TranscriptionOptions(
transport_url=self.transport_url,
transport_type=StreamingTransportType.WEBSOCKET,
locale=["en-US", "es-ES"],
start_transcription=False,
pii_redaction=PiiRedactionOptions(
enable=True,
redaction_type=RedactionType.MASK_WITH_CHARACTER
)
)
answer_call_result = await call_automation_client.answer_call(
incoming_call_context=incoming_call_context,
transcription=transcription_options,
cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT,
callback_url=callback_uri,
enable_loopback_audio=True,
operation_context="answerCallContext"
)
備註
啟用 PII 修訂後,您只會收到已修訂的文字。
即時語言偵測 (預覽)
自動偵測口語語言,以實現自然且如同人類的通訊,並消除手動語言選擇。 在 createCall、answerCall 和 startTranscription 中提供。
建立已啟用即時語言偵測的通話
transcription_options = TranscriptionOptions(
transport_url=self.transport_url,
transport_type=StreamingTransportType.WEBSOCKET,
locale=["en-US", "es-ES","hi-IN"],
start_transcription=False,
enable_sentiment_analysis=True,
)
call_connection_properties = await call_automation_client.create_call(
target_participant=[target_participant],
callback_url=CALLBACK_EVENTS_URI,
cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT,
source_caller_id_number=source_caller,
transcription=transcription_options
)
備註
若要在語言識別開始之後將其停止,請使用 updateTranscription API,並明確設定您想要用於文字記錄的語言。 這會停用自動語言偵測,並鎖定對指定語言的謄寫。
連線至會議室通話並提供謄寫詳細資料
如果您要連線到 ACS 會議室並想要使用轉譯,請設定轉譯選項,如下所示:
transcription_options = TranscriptionOptions(
transport_url="",
transport_type=TranscriptionTransportType.WEBSOCKET,
locale="en-US",
start_transcription=False,
#Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
speech_recognition_model_endpoint_id = "YourCustomSpeechRecognitionModelEndpointId"
)
connect_result = client.connect_call(
room_id="roomid",
CALLBACK_EVENTS_URI,
cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT,
operation_context="connectCallContext",
transcription=transcription_options
)
啟動謄寫
準備好開始轉錄後,您可以呼叫通話自動化服務以開始轉寫通話。
# Start transcription without options
call_connection_client.start_transcription()
# Option 1: Start transcription with locale and operation context
# call_connection_client.start_transcription(locale="en-AU", operation_context="startTranscriptionContext")
# Option 2: Start transcription with operation context
# call_connection_client.start_transcription(operation_context="startTranscriptionContext")
取得通話中摘要 (預覽)
使用即時摘要來增強通話工作流程。 透過在謄寫選項中啟用摘要,ACS 可以自動產生精簡的通話中回顧 (包括決策、動作項目和重要討論點) 而不需要等待通話結束。 這可協助小組保持一致,並加快即時交談期間後續追蹤的速度。
transcription_options = TranscriptionOptions(
transport_url=self.transport_url,
transport_type=StreamingTransportType.WEBSOCKET,
locale="en-US",
start_transcription=False,
summarization=SummarizationOptions(
enable_end_call_summary=True,
locale="en-US"
)
)
answer_call_result = await call_automation_client.answer_call(
incoming_call_context=incoming_call_context,
transcription=transcription_options,
cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT,
callback_url=callback_uri,
enable_loopback_audio=True,
operation_context="answerCallContext"
)
await call_connection_client.summarize_call(
operation_context=self.operation_context,
operation_callback_url=self.operation_callback_url,
summarization=transcription_options.summarization
)
額外標題:
相互關聯識別碼和呼叫連線標識碼現在包含在 WebSocket 標頭中,以改善可追蹤性和 x-ms-call-correlation-idx-ms-call-connection-id。
接收謄寫串流
當轉譯開始時,您的websocket會以第一個封包的形式接收轉譯元數據承載。
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
接收謄寫資料
接收中繼資料之後,Web Socket 接收的下一個封包將是謄寫音訊的 TranscriptionData。
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "Testing transcription.",
"format": "display",
"confidence": 0.695223331451416,
"offset": 2516998782481234400,
"words": [
{
"text": "testing",
"offset": 2516998782481234400
},
{
"text": "testing",
"offset": 2516998782481234400
}
],
"participantRawID": "8:acs:",
"resultStatus": "Final"
}
}
接收已啟用 AI 功能的謄寫資料流 (預覽)
呼叫期間啟用謄寫時,Azure 通訊服務會發出中繼資料,描述謄寫工作階段的設定和內容。 這包括地區設定、通話連接識別碼、情感分析設定和 PII 修訂喜好設定等詳細資料。 開發人員可以使用此承載來確認謄寫設定、稽核設定,或疑難排解 AI 所增強即時謄寫功能的相關問題。
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "863b5e55-de0d-4fc3-8e58-2d68e976b5ad",
"locale": "en-US",
"callConnectionId": "02009180-9dc2-429b-a3eb-d544b7b6a0e1",
"correlationId": "62c8215b-5276-4d3c-bb6d-06a1b114651b",
"speechModelEndpointId": null,
"locales": [],
"enableSentimentAnalysis": true,
"piiRedactionOptions": {
"enable": true,
"redactionType": "MaskWithCharacter"
}
}
}
接收已啟用 AI 功能的謄寫資料 (預覽)
初始中繼資料封包之後,您的 WebSocket 連接會開始接收轉譯音訊中每個區段的 TranscriptionData 事件。 這些封包包括轉譯的文字、信賴度分數、時間資訊,以及 (如果啟用) 情感分析和 PII 修訂。 此資料可用來建立即時儀表板、觸發工作流程,或在通話期間分析交談動態。
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "My date of birth is *********.",
"format": "display",
"confidence": 0.8726407289505005,
"offset": 309058340,
"duration": 31600000,
"words": [],
"participantRawID": "4:+917020276722",
"resultStatus": "Final",
"sentimentAnalysisResult": {
"sentiment": "neutral"
}
}
}
處理 Web Socket 伺服器中的謄寫串流
import asyncio
import json
import websockets
from azure.communication.callautomation._shared.models import identifier_from_raw_id
async def handle_client(websocket, path):
print("Client connected")
try:
async for message in websocket:
json_object = json.loads(message)
kind = json_object['kind']
if kind == 'TranscriptionMetadata':
print("Transcription metadata")
print("-------------------------")
print("Subscription ID:", json_object['transcriptionMetadata']['subscriptionId'])
print("Locale:", json_object['transcriptionMetadata']['locale'])
print("Call Connection ID:", json_object['transcriptionMetadata']['callConnectionId'])
print("Correlation ID:", json_object['transcriptionMetadata']['correlationId'])
print("Locales:", json_object['transcriptionMetadata']['locales'])
print("PII Redaction Options:", json_object['transcriptionMetadata']['piiRedactionOptions'])
if kind == 'TranscriptionData':
participant = identifier_from_raw_id(json_object['transcriptionData']['participantRawID'])
word_data_list = json_object['transcriptionData']['words']
print("Transcription data")
print("-------------------------")
print("Text:", json_object['transcriptionData']['text'])
print("Format:", json_object['transcriptionData']['format'])
print("Confidence:", json_object['transcriptionData']['confidence'])
print("Offset:", json_object['transcriptionData']['offset'])
print("Duration:", json_object['transcriptionData']['duration'])
print("Participant:", participant.raw_id)
print("Result Status:", json_object['transcriptionData']['resultStatus'])
print("Sentiment Analysis Result:", json_object['transcriptionData']['sentimentAnalysisResult'])
print("Result Status:", json_object['transcriptionData']['resultStatus'])
for word in word_data_list:
print("Word:", word['text'])
print("Offset:", word['offset'])
print("Duration:", word['duration'])
except websockets.exceptions.ConnectionClosedOK:
print("Client disconnected")
except websockets.exceptions.ConnectionClosedError as e:
print("Connection closed with error: %s", e)
except Exception as e:
print("Unexpected error: %s", e)
start_server = websockets.serve(handle_client, "localhost", 8081)
print('WebSocket server running on port 8081')
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
更新謄寫
如果您的應用程式允許使用者選取使用者慣用的語言,您可能也想要擷取該語言的謄寫。 若要執行這項工作,呼叫自動化 SDK 可讓您更新轉譯地區設定。
await call_automation_client.get_call_connection(
call_connection_id=call_connection_id
).update_transcription(
operation_context="UpdateTranscriptionContext",
locale="en-au",
#Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
speech_recognition_model_endpoint_id = "YourCustomSpeechRecognitionModelEndpointId"
)
停止文字轉錄
當您的應用程式必須停止接聽謄寫時,您可以使用 StopTranscription 要求以讓通話自動化知道要停止將文字記錄資料傳送至您的 Web Socket。
# Stop transcription without options
call_connection_client.stop_transcription()
# Alternative: Stop transcription with operation context
# call_connection_client.stop_transcription(operation_context="stopTranscriptionContext")
事件代碼
| 事件 | 字碼 | 子代碼 | 訊息 |
|---|---|---|---|
| 轉錄開始 | 200 | 0 | 動作已順利完成。 |
| 錄音停止 | 200 | 0 | 動作已順利完成。 |
| 轉錄已更新 | 200 | 0 | 動作已順利完成。 |
| 轉錄失敗 | 400 | 8581 | 動作失敗,StreamUrl 無效。 |
| 轉錄失敗 | 400 | 8565 | 由於對人工智慧服務的請求錯誤,導致操作失敗。 檢查您的輸入參數。 |
| 轉錄失敗 | 400 | 8565 | 由於傳遞給認知服務的要求逾時,因此動作失敗。請稍後再試,或檢查服務是否發生任何問題。 |
| 轉錄失敗 | 400 | 8605 | 謄寫不支援自訂語音辨識。 |
| 轉錄失敗 | 400 | 8523 | 要求無效,缺少地區設定。 |
| 轉錄失敗 | 400 | 8523 | 要求無效,僅支援包含區域資訊的地區。 |
| 轉錄失敗 | 405 | 8520 | 目前不支援謄寫功能。 |
| 轉錄失敗 | 405 | 8520 | 使用 Connect 介面建立的連線不支援 UpdateTranscription。 |
| 轉錄失敗 | 400 | 8528 | 動作無效,已終止通話。 |
| 轉錄失敗 | 405 | 8520 | 目前不支援更新轉錄功能。 |
| 轉錄失敗 | 405 | 8522 | 當通話設定期間未設定轉錄URL時,不允許進行請求。 |
| 轉錄失敗 | 405 | 8522 | 若在通話設定期間未設定認知服務組態,則不允許要求。 |
| 轉錄失敗 | 400 | 8501 | 當通話不是「已建立」狀態時,動作無效。 |
| 轉錄失敗 | 401 | 8565 | 由於發生認知服務驗證錯誤,因此動作失敗。 檢查您的授權輸入並確保正確無誤。 |
| 轉錄失敗 | 403 | 8565 | 由於傳遞給認知服務的要求禁止,因此動作失敗。 檢查您的訂用帳戶狀態並確保其為作用中。 |
| 轉錄失敗 | 429 | 8565 | 動作失敗,要求已超過認知服務訂用帳戶允許的並行要求數目。 |
| 轉錄失敗 | 500 | 8578 | 動作失敗,無法建立 WebSocket 連線。 |
| 轉錄失敗 | 500 | 8580 | 動作失敗,已關閉謄寫服務。 |
| 轉錄失敗 | 500 | 8579 | 動作失敗,轉錄已取消。 |
| 轉錄失敗 | 500 | 9999 | 未知內部伺服器錯誤。 |
已知問題
- 針對使用用戶端 SDK 的 ACS 使用者 1:1 通話,目前不支援 startTranscription = True。