Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Это руководство поможет вам лучше понять различные способы использования функции транскрибирования в режиме реального времени, предлагаемой Службами коммуникации Azure, с помощью SDK для автоматизации вызовов.
Предварительные условия
- Учетная запись Azure с активной подпиской, для подробностей см. Создайте учетную запись бесплатно.
- Ресурс Службы коммуникации Azure, см. раздел Создание ресурса Службы коммуникации Azure
- Создайте и подключите службы ИИ Azure к Службы коммуникации Azure ресурсу.
- Создайте настраиваемый поддомен для ресурса служб искусственного интеллекта Azure.
- Создайте новое приложение веб-службы с помощью пакета SDK службы автоматизации вызовов.
Настройка сервера WebSocket
Службы коммуникации Azure требует, чтобы серверное приложение настроит сервер WebSocket для потоковой передачи транскрибирования в режиме реального времени. WebSocket — это стандартизованный протокол, предоставляющий полно дуплексный канал связи по одному TCP-подключению. При необходимости можно использовать службы Azure WebApps, позволяющие создать приложение для получения расшифровок через подключение websocket. Следуйте инструкциям из этого краткого руководства.
Установить вызов
В этом кратком руководстве предполагается, что вы уже знакомы с процессом начала звонков. Если вам нужно узнать больше о запуске и установке вызовов, ознакомьтесь с нашим кратким руководством. В целях этого краткого руководства мы рассмотрим процесс запуска транскрибирования для входящих и исходящих вызовов.
При работе с транскрибированием в режиме реального времени у вас есть несколько вариантов о том, когда и как начать транскрибирование:
Вариант 1. Запуск во время ответа или создания вызова
Вариант 2. Запуск транскрибирования во время текущего вызова
Вариант 3 - Запуск транскрибирования при подключении к вызову Azure Communication Services Rooms
В этом руководстве мы демонстрируем опции 2 и 3, начиная транскрибирование в то время как идет текущий вызов или при подключении к Rooms call. По умолчанию параметр startTranscription имеет значение false во время ответа или создания вызова.
Создание вызова и предоставление сведений о транскрибировании
Определите параметры транскрибирования для ACS, чтобы указать, когда начинать транскрибирование, указать локаль для транскрибирования и соединение веб-сокета для отправки транскрипта.
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);
Подключитесь к вызову Rooms и предоставьте сведения о транскрипции
Если вы подключаетесь к комнате 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
StartTranscriptionOptions options = new StartTranscriptionOptions()
{
OperationContext = "startMediaStreamingContext",
//Locale = "en-US",
//Only add the SpeechRecognitionModelEndpointId if you have a custom speech model you would like to use
SpeechRecognitionModelEndpointId = "YourCustomSpeechRecognitionModelEndpointId"
};
await callMedia.StartTranscriptionAsync(options);
// Alternative: Start transcription without options
// await callMedia.StartTranscriptionAsync();
Дополнительные заголовки:
Идентификатор корреляции и идентификатор подключения вызова теперь включены в заголовки WebSocket для улучшения трассировки x-ms-call-correlation-id
и x-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"
}
}
Получение данных транскрибирования
После метаданных следующие пакеты, получаемые веб-сокетом, будут содержать данные транскрипции для транскрибированного аудио.
{
"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"
}
}
Обработка потока транскрибирования на сервере веб-сокета
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("***************************************************************************************");
}
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);
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, чтобы сообщить службе автоматизации вызовов, чтобы остановить отправку данных расшифровки в веб-сокет.
StopTranscriptionOptions stopOptions = new StopTranscriptionOptions()
{
OperationContext = "stopTranscription"
};
await callMedia.StopTranscriptionAsync(stopOptions);
Создание вызова и предоставление сведений о транскрибировании
Определите транскрибированиеOptions для ACS, чтобы указать время начала транскрибирования, языкового стандарта для транскрибирования и подключения веб-сокета для отправки расшифровки.
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();
Подключитесь к вызову Rooms и предоставьте сведения о транскрипции
Если вы подключаетесь к комнате 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();
Дополнительные заголовки:
Идентификатор корреляции и идентификатор подключения вызова теперь включены в заголовки WebSocket для улучшения трассировки x-ms-call-correlation-id
и x-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"
}
}
Получение данных транскрибирования
После метаданных следующие пакеты, получаемые веб-сокетом, будут содержать данные транскрипции для транскрибированного аудио.
{
"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"
}
}
Обработка потока транскрибирования на сервере веб-сокета
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("IS SILENT: --> " + transcriptionMetadata.getLocale());
System.out.println("CALL CONNECTION ID: --> " + transcriptionMetadata.getCallConnectionId());
System.out.println("CORRELATION ID: --> " + transcriptionMetadata.getCorrelationId());
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("----------------------------------------------------------------");
}
}
}
Обновление транскрибирования
В ситуациях, когда ваше приложение позволяет пользователям выбирать предпочтительный язык, возможно, вы также захотите записывать транскрипцию на этом языке. Для этого пакет SDK службы автоматизации вызовов позволяет обновить языковой стандарт транскрибирования.
UpdateTranscriptionOptions transcriptionOptions = new UpdateTranscriptionOptions()
.setLocale(newLocale)
.setOperationContext("transcriptionContext")
.setSpeechRecognitionEndpointId("your-endpoint-id-here");
client.getCallConnection(callConnectionId)
.getCallMedia()
.updateTranscriptionWithResponse(transcriptionOptions, Context.NONE);
Остановка транскрибирования
Если приложению необходимо прекратить прослушивание транскрибирования, можно использовать запрос StopTranscription, чтобы сообщить службе автоматизации вызовов, чтобы остановить отправку данных расшифровки в веб-сокет.
// 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();
Создание вызова и предоставление сведений о транскрибировании
Определите транскрибированиеOptions для ACS, чтобы указать время начала транскрибирования, языкового стандарта для транскрибирования и подключения веб-сокета для отправки расшифровки.
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);
Подключитесь к вызову Rooms и предоставьте сведения о транскрипции
Если вы подключаетесь к комнате 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();
Дополнительные заголовки:
Идентификатор корреляции и идентификатор подключения вызова теперь включены в заголовки WebSocket для улучшения трассировки x-ms-call-correlation-id
и x-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"
}
}
Получение данных транскрибирования
После метаданных следующие пакеты, получаемые веб-сокетом, будут содержать данные транскрипции для транскрибированного аудио.
{
"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"
}
}
Обработка потока транскрибирования на сервере веб-сокета
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);
if ('locale' in response) {
console.log("Transcription Metadata");
console.log(response.callConnectionId);
console.log(response.correlationId);
console.log(response.locale);
console.log(response.subscriptionId);
}
if ('text' in response) {
console.log("Transcription Data");
console.log(response.text);
console.log(response.format);
console.log(response.confidence);
console.log(response.offset);
console.log(response.duration);
console.log(response.resultStatus);
if ('phoneNumber' in response.participant) {
console.log(response.participant.phoneNumber);
}
response.words.forEach((word) => {
console.log(word.text);
console.log(word.duration);
console.log(word.offset);
});
}
});
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, чтобы сообщить службе автоматизации вызовов, чтобы остановить отправку данных расшифровки в веб-сокет.
const stopTranscriptionOptions = {
operationContext: "stopTranscriptionContext"
};
// Stop transcription with options
await callMedia.stopTranscription(stopTranscriptionOptions);
// Alternative: Stop transcription without options
// await callMedia.stopTranscription();
Создание вызова и предоставление сведений о транскрибировании
Определите транскрибированиеOptions для ACS, чтобы указать время начала транскрибирования, языкового стандарта для транскрибирования и подключения веб-сокета для отправки расшифровки.
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
)
Подключитесь к вызову Rooms и предоставьте сведения о транскрипции
Если вы подключаетесь к комнате 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")
Дополнительные заголовки:
Идентификатор корреляции и идентификатор подключения вызова теперь включены в заголовки WebSocket для улучшения трассировки x-ms-call-correlation-id
и x-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"
}
}
Получение данных транскрибирования
После метаданных следующие пакеты, получаемые websocket, будут содержать данные транскрипции для транскрибированного звука.
{
"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"
}
}
Обработка потока транскрибирования на сервере веб-сокета
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'])
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'])
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, чтобы сообщить службе автоматизации вызовов, чтобы остановить отправку данных расшифровки в веб-сокет.
# 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 | Не удалось выполнить действие из-за неверного запроса к Cognitive Services. Проверьте входные параметры. |
Ошибка расшифровки | 400 | 8565 | Действие завершилось сбоем из-за того, что запрос к Cognitive Services завершился тайм-аутом. Повторите попытку позже или проверьте наличие проблем с сервисом. |
Ошибка расшифровки | 400 | 8605 | Пользовательская модель распознавания речи для транскрибирования не поддерживается. |
Ошибка расшифровки | 400 | 8523 | Недопустимый запрос, языковой стандарт отсутствует. |
Ошибка расшифровки | 400 | 8523 | Недопустимый запрос, поддерживаются только локали, содержащие сведения о регионе. |
Ошибка расшифровки | 405 | 8520 | Функции транскрибирования в настоящее время не поддерживаются. |
Ошибка расшифровки | 405 | 8520 | UpdateTranscription не поддерживается для подключения, созданного с помощью интерфейса Connect. |
Ошибка расшифровки | 400 | 8528 | Действие недопустимо, вызов уже завершен. |
Ошибка расшифровки | 405 | 8520 | В настоящее время функции транскрибирования обновлений не поддерживаются. |
Ошибка расшифровки | 405 | 8522 | Запрос не разрешен, если URL-адрес транскрибирования не задан во время настройки вызова. |
Ошибка расшифровки | 405 | 8522 | Запрос не разрешен, если конфигурация Cognitive Service не задана во время настройки вызова. |
Ошибка расшифровки | 400 | 8501 | Действие недопустимо, если вызов не находится в состоянии "Установлено". |
Ошибка расшифровки | 401 | 8565 | Сбой действия из-за ошибки аутентификации в Cognitive Services. Проверьте входные данные авторизации и убедитесь, что это правильно. |
Ошибка расшифровки | Ошибка 403: Доступ запрещён | 8565 | Не удалось выполнить действие из-за запрещенного запроса в Cognitive Services. Проверьте состояние подписки и убедитесь, что она активна. |
Ошибка расшифровки | 429 | 8565 | Ошибка выполнения действия: количество запросов превысило лимит разрешённых одновременных запросов для подписки на когнитивные службы. |
Ошибка расшифровки | 500 | 8578 | Действие не выполнено, так как не удалось установить подключение WebSocket. |
Ошибка расшифровки | 500 | 8580 | Не удалось выполнить действие, служба транскрибирования была завершена. |
Ошибка расшифровки | 500 | 8579 | Не удалось выполнить действие, транскрибирование было отменено. |
Ошибка расшифровки | 500 | 9999 | Неизвестная внутренняя ошибка сервера. |
Известные проблемы
- Для вызовов 1:1 с пользователями ACS с помощью клиентских пакетов SDK startTranscription = True в настоящее время не поддерживается.