Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este guia ajuda você a entender melhor as diferentes maneiras de usar a oferta dos Serviços de Comunicação do Azure de transcrição em tempo real por meio de SDKs de Automação de Chamadas.
Pré-requisitos
- Conta do Azure com uma subscrição ativa, para obter detalhes, consulte Criar uma conta gratuitamente.
- Recurso dos Serviços de Comunicação do Azure, consulte Criar um recurso dos Serviços de Comunicação do Azure
- Crie e conecte os serviços de IA do Azure ao seu recurso dos Serviços de Comunicação do Azure.
- Crie um subdomínio personalizado para seu recurso de serviços de IA do Azure.
- Crie um novo aplicativo de serviço Web usando o SDK de automação de chamadas.
Configurar um servidor WebSocket
Os Serviços de Comunicação do Azure exigem que seu aplicativo de servidor configure um servidor WebSocket para transmitir transcrição em tempo real. WebSocket é um protocolo padronizado que fornece um canal de comunicação full-duplex através de uma única conexão TCP. Opcionalmente, você pode usar os serviços do Azure Azure WebApps que permitem criar um aplicativo para receber transcrições em uma conexão websocket. Siga este guia de início rápido.
Estabeleça uma chamada
Neste guia de início rápido, assumimos que você já está familiarizado com o início de chamadas. Se precisar de saber mais sobre como iniciar e estabelecer chamadas, pode seguir o nosso guia de início rápido. Para os fins deste início rápido, estamos passando pelo processo de iniciar a transcrição para chamadas de entrada e de saída.
Ao trabalhar com transcrição em tempo real, você tem algumas opções sobre quando e como iniciar a transcrição:
Opção 1 - Começar no momento de atender ou criar uma chamada
Opção 2 - Iniciar a transcrição durante uma chamada em curso
Opção 3 - Iniciar a transcrição ao conectar-se a uma chamada das Salas dos Serviços de Comunicação do Azure
Neste tutorial, estamos demonstrando as opções 2 e 3, iniciando a transcrição durante uma chamada em andamento ou ao se conectar a uma chamada de salas. Por padrão, o 'startTranscription' é definido como false no momento de atender ou criar uma chamada.
Crie uma chamada e forneça os detalhes da transcrição
Defina as TranscriptionOptions para ACS para especificar quando iniciar a transcrição, especifique a localidade para transcrição e a conexão de soquete da Web para enviar a transcrição.
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);
Conecte-se a uma chamada de salas e forneça detalhes de transcrição
Se você estiver se conectando a uma sala ACS e quiser usar a transcrição, configure as opções de transcrição da seguinte maneira:
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);
Iniciar transcrição
Quando estiver pronto para iniciar a transcrição, você pode fazer uma chamada explícita para o Call Automation para começar a transcrever a chamada.
// 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();
Cabeçalhos adicionais:
A ID de Correlação e a ID de Conexão de Chamada agora estão incluídas nos cabeçalhos WebSocket para melhor rastreabilidade x-ms-call-correlation-id
e x-ms-call-connection-id
.
Recebendo fluxo de transcrição
Quando a transcrição é iniciada, seu websocket recebe a carga útil de metadados de transcrição como o primeiro pacote.
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
Receber dados de transcrição
Após os metadados, os próximos pacotes que seu soquete da Web receberá serão TranscriptionData para o áudio transcrito.
{
"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"
}
}
Manipulando o fluxo de transcrição no servidor de soquete da Web
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();
Atualizações do código para o manipulador 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);
}
}
}
Atualizar transcrição
Para situações em que seu aplicativo permite que os usuários selecionem seu idioma preferido, você também pode querer capturar a transcrição nesse idioma. Para fazer isso, o Call Automation SDK permite que você atualize a localidade de transcrição.
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);
Parar transcrição
Quando seu aplicativo precisar parar de ouvir a transcrição, você poderá usar a solicitação StopTranscription para informar a Automação de Chamadas para parar de enviar dados de transcrição para seu soquete da Web.
StopTranscriptionOptions stopOptions = new StopTranscriptionOptions()
{
OperationContext = "stopTranscription"
};
await callMedia.StopTranscriptionAsync(stopOptions);
Crie uma chamada e forneça os detalhes da transcrição
Defina as TranscriptionOptions para ACS para especificar quando iniciar a transcrição, a localidade para transcrição e a conexão de soquete da Web para enviar a transcrição.
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();
Conecte-se a uma chamada de salas e forneça detalhes de transcrição
Se você estiver se conectando a uma sala ACS e quiser usar a transcrição, configure as opções de transcrição da seguinte maneira:
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();
Iniciar transcrição
Quando estiver pronto para iniciar a transcrição, você pode fazer uma chamada explícita para o Call Automation para começar a transcrever a chamada.
//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();
Cabeçalhos adicionais:
A ID de Correlação e a ID de Conexão de Chamada agora estão incluídas nos cabeçalhos WebSocket para melhor rastreabilidade x-ms-call-correlation-id
e x-ms-call-connection-id
.
Recebendo fluxo de transcrição
Quando a transcrição é iniciada, seu websocket recebe a carga útil de metadados de transcrição como o primeiro pacote.
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
Receber dados de transcrição
Após os metadados, os próximos pacotes que seu soquete da Web receberá serão TranscriptionData para o áudio transcrito.
{
"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"
}
}
Manipulando o fluxo de transcrição no servidor de soquete da Web
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();
}
}
}
Atualizações do código para o manipulador 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("----------------------------------------------------------------");
}
}
}
Atualizar transcrição
Para situações em que seu aplicativo permite que os usuários selecionem seu idioma preferido, você também pode querer capturar a transcrição nesse idioma. Para fazer isso, o Call Automation SDK permite que você atualize a localidade de transcrição.
UpdateTranscriptionOptions transcriptionOptions = new UpdateTranscriptionOptions()
.setLocale(newLocale)
.setOperationContext("transcriptionContext")
.setSpeechRecognitionEndpointId("your-endpoint-id-here");
client.getCallConnection(callConnectionId)
.getCallMedia()
.updateTranscriptionWithResponse(transcriptionOptions, Context.NONE);
Parar transcrição
Quando seu aplicativo precisar parar de ouvir a transcrição, você poderá usar a solicitação StopTranscription para informar a Automação de Chamadas para parar de enviar dados de transcrição para seu soquete da Web.
// 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();
Crie uma chamada e forneça os detalhes da transcrição
Defina as TranscriptionOptions para ACS para especificar quando iniciar a transcrição, a localidade para transcrição e a conexão de soquete da Web para enviar a transcrição.
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);
Conecte-se a uma chamada de salas e forneça detalhes de transcrição
Se você estiver se conectando a uma sala ACS e quiser usar a transcrição, configure as opções de transcrição da seguinte maneira:
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);
Iniciar transcrição
Quando estiver pronto para iniciar a transcrição, você pode fazer uma chamada explícita para o Call Automation para começar a transcrever a chamada.
const startTranscriptionOptions = {
locale: "en-AU",
operationContext: "startTranscriptionContext"
};
// Start transcription with options
await callMedia.startTranscription(startTranscriptionOptions);
// Alternative: Start transcription without options
// await callMedia.startTranscription();
Cabeçalhos adicionais:
A ID de Correlação e a ID de Conexão de Chamada agora estão incluídas nos cabeçalhos WebSocket para melhor rastreabilidade x-ms-call-correlation-id
e x-ms-call-connection-id
.
Recebendo fluxo de transcrição
Quando a transcrição é iniciada, seu websocket recebe a carga útil de metadados de transcrição como o primeiro pacote.
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
Receção de dados de transcrição
Após os metadados, os próximos pacotes que seu soquete da Web receberá serão TranscriptionData para o áudio transcrito.
{
"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"
}
}
Manipulando o fluxo de transcrição no servidor de soquete da Web
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');
Atualizar transcrição
Para situações em que seu aplicativo permite que os usuários selecionem seu idioma preferido, você também pode querer capturar a transcrição nesse idioma. Para fazer essa tarefa, o SDK de automação de chamadas permite que você atualize a localidade de transcrição.
async function updateTranscriptionAsync() {
const options: UpdateTranscriptionOptions = {
operationContext: "updateTranscriptionContext",
speechRecognitionModelEndpointId: "YOUR_CUSTOM_SPEECH_RECOGNITION_MODEL_ID"
};
await acsClient
.getCallConnection(callConnectionId)
.getCallMedia()
.updateTranscription("en-au", options);
}
Parar transcrição
Quando seu aplicativo precisar parar de ouvir a transcrição, você poderá usar a solicitação StopTranscription para informar a Automação de Chamadas para parar de enviar dados de transcrição para seu soquete da Web.
const stopTranscriptionOptions = {
operationContext: "stopTranscriptionContext"
};
// Stop transcription with options
await callMedia.stopTranscription(stopTranscriptionOptions);
// Alternative: Stop transcription without options
// await callMedia.stopTranscription();
Crie uma chamada e forneça os detalhes da transcrição
Defina as TranscriptionOptions para ACS para especificar quando iniciar a transcrição, a localidade para transcrição e a conexão de soquete da Web para enviar a transcrição.
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
)
Conecte-se a uma chamada de salas e forneça detalhes de transcrição
Se você estiver se conectando a uma sala ACS e quiser usar a transcrição, configure as opções de transcrição da seguinte maneira:
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
)
Iniciar transcrição
Quando estiver pronto para iniciar a transcrição, você pode fazer uma chamada explícita para o Call Automation para começar a transcrever a chamada.
# 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")
Cabeçalhos adicionais:
A ID de Correlação e a ID de Conexão de Chamada agora estão incluídas nos cabeçalhos WebSocket para melhor rastreabilidade x-ms-call-correlation-id
e x-ms-call-connection-id
.
Recebendo fluxo de transcrição
Quando a transcrição é iniciada, seu websocket recebe a carga útil de metadados de transcrição como o primeiro pacote.
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
Receção de dados de transcrição
Após os metadados, os próximos pacotes que seu websocket receberá serão TranscriptionData para o áudio transcrito.
{
"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"
}
}
Manipulando o fluxo de transcrição no servidor de soquete da Web
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()
Atualizar transcrição
Para situações em que seu aplicativo permite que os usuários selecionem seu idioma preferido, você também pode querer capturar a transcrição nesse idioma. Para fazer essa tarefa, o SDK de automação de chamadas permite que você atualize a localidade de transcrição.
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"
)
Parar transcrição
Quando seu aplicativo precisar parar de ouvir a transcrição, você poderá usar a solicitação StopTranscription para informar a Automação de Chamadas para parar de enviar dados de transcrição para seu soquete da Web.
# Stop transcription without options
call_connection_client.stop_transcription()
# Alternative: Stop transcription with operation context
# call_connection_client.stop_transcription(operation_context="stopTranscriptionContext")
Códigos de evento
Evento | código | subcódigo | Mensagem |
---|---|---|---|
Transcrição Iniciada | 200 | 0 | Ação concluída com êxito. |
Transcrição Interrompida | 200 | 0 | Ação concluída com êxito. |
Transcrição Atualizada | 200 | 0 | Ação concluída com êxito. |
Transcrição Falhou | 400 | 8581 | Falha na ação, StreamUrl não é válido. |
Transcrição Falhou | 400 | 8565 | A ação falhou devido a um mau pedido aos Serviços Cognitivos. Verifique os parâmetros de entrada. |
Transcrição Falhou | 400 | 8565 | A ação falhou devido a um pedido aos Serviços Cognitivos de tempo limite. Tente novamente mais tarde ou verifique se há problemas com o serviço. |
Transcrição Falhou | 400 | 8605 | Não há suporte para o modelo de reconhecimento de fala personalizado para transcrição. |
Transcrição Falhou | 400 | 8523 | Solicitação inválida, localidade em falta. |
Transcrição Falhou | 400 | 8523 | Solicitação inválida, somente localidades que contêm informações de região são suportadas. |
Transcrição Falhou | 405 | 8520 | A funcionalidade de transcrição não é suportada no momento. |
Transcrição Falhou | 405 | 8520 | UpdateTranscription não é suportado para conexão criada com a interface Connect. |
Transcrição Falhou | 400 | 8528 | A ação é inválida, a chamada já foi encerrada. |
Transcrição Falhou | 405 | 8520 | A funcionalidade de transcrição de atualização não é suportada no momento. |
Transcrição Falhou | 405 | 8522 | Solicitação não permitida quando a URL de transcrição não estiver definida durante a configuração da chamada. |
Transcrição Falhou | 405 | 8522 | Solicitação não permitida quando a Configuração do Serviço Cognitivo não estiver definida durante a configuração da chamada. |
Transcrição Falhou | 400 | 8501 | A ação é inválida quando a chamada não está no estado Estabelecido. |
Transcrição Falhou | 401 | 8565 | A ação falhou devido a um erro de autenticação dos Serviços Cognitivos. Verifique a sua entrada de autorização e certifique-se de que está correta. |
Transcrição Falhou | 403 | 8565 | A ação falhou devido a um pedido proibido aos Serviços Cognitivos. Verifique o estado da sua subscrição e certifique-se de que está ativa. |
Transcrição Falhou | 429 | 8565 | A ação falhou, as solicitações excederam o número de solicitações simultâneas permitidas para a assinatura de serviços cognitivos. |
Transcrição Falhou | 500 | 8578 | Falha na ação, não é possível estabelecer a conexão WebSocket. |
Transcrição Falhou | 500 | 8580 | A ação falhou, o serviço de transcrição foi encerrado. |
Transcrição Falhou | 500 | 8579 | A ação falhou, a transcrição foi cancelada. |
Transcrição Falhou | 500 | 9999 | Erro interno desconhecido do servidor. |
Problemas conhecidos
- Para chamadas 1:1 com usuários do ACS usando SDKs de cliente, startTranscription = True não é suportado no momento.