Compartir a través de


Incorpore la transcripción en tiempo real a su aplicación

Importante

La funcionalidad descrita en este artículo se encuentra actualmente en versión preliminar pública. Esta versión preliminar se ofrece sin un Acuerdo de Nivel de Servicio y no se recomienda para cargas de trabajo de producción. Es posible que algunas características no sean compatibles o que tengan sus funcionalidades limitadas. Para más información, consulte Términos de uso complementarios de las Versiones Preliminares de Microsoft Azure.

Esta guía le ayuda a comprender mejor las distintas formas en que puede utilizar la oferta de Azure Communication Services de transcripción en tiempo real a través de los SDK de automatización de llamadas.

Requisitos previos

Configurar un servidor WebSocket

Azure Communication Services requiere que su aplicación de servidor configure un servidor WebSocket para transmitir la transcripción en tiempo real. WebSocket es un protocolo estandarizado que proporciona un canal de comunicación dúplex completo a través de una única conexión TCP. Opcionalmente, puede utilizar los servicios Azure WebApps de Azure que le permite crear una aplicación para recibir transcripciones a través de una conexión websocket. Siga este inicio rápido.

Establecimiento de una llamada

En esta guía rápida, asumimos que ya está familiarizado con el inicio de llamadas. Si necesita más información sobre cómo iniciar y establecer llamadas, puede seguir nuestro inicio rápido. En esta guía rápida, vamos a iniciar la transcripción tanto de las llamadas entrantes como de las salientes.

Al trabajar con la transcripción en tiempo real, tiene varias opciones sobre cuándo y cómo empezar a transcribir:

Opción 1: a partir del momento en que se responde o se crea una llamada

Opción 2: iniciar la transcripción durante una llamada en curso

Opción 3: inicio de la transcripción al conectarse a una llamada de Azure Communication Services Rooms

En este tutorial, vamos a demostrar las opciones 2 y 3, iniciando la transcripción durante una llamada en curso o al conectarse a una llamada de Salas. De forma predeterminada, "startTranscription" se establece en falso en el momento de responder o crear una llamada.

Cree una convocatoria y proporcione los datos de transcripción

Defina las TranscriptionOptions para que ACS especifique cuándo iniciar la transcripción, especifique la configuración regional para la transcripción y la conexión de socket web para enviar la transcripción.

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);

Conectarse a una llamada de Salas y proporcionar detalles de la transcripción

Si se conecta a una sala ACS y desea utilizar la transcripción, configure las opciones de transcripción como se indica a continuación:

var transcriptionOptions = new TranscriptionOptions(
    transportUri: new Uri(""),
    locale: "en-US", 
    startTranscription: false,
    transcriptionTransport: TranscriptionTransport.Websocket
);

var connectCallOptions = new ConnectCallOptions(new RoomCallLocator("roomId"), callbackUri)
{
    CallIntelligenceOptions = new CallIntelligenceOptions() 
    { 
        CognitiveServicesEndpoint = new Uri(cognitiveServiceEndpoint) 
    },
    TranscriptionOptions = transcriptionOptions
};

var connectResult = await client.ConnectCallAsync(connectCallOptions);

Iniciar transcripción

Una vez que esté listo para iniciar la transcripción, puede realizar una llamada explícita a Automatización de llamadas para comenzar a transcribir la llamada.

// Start transcription with options
StartTranscriptionOptions options = new StartTranscriptionOptions()
{
    OperationContext = "startMediaStreamingContext",
    //Locale = "en-US",
};

await callMedia.StartTranscriptionAsync(options);

// Alternative: Start transcription without options
// await callMedia.StartTranscriptionAsync();

Recepción del flujo de transcripciones

Cuando se inicia la transcripción, su websocket recibe la carga útil de metadatos de transcripción como primer paquete.

{
    "kind": "TranscriptionMetadata",
    "transcriptionMetadata": {
        "subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
        "locale": "en-us",
        "callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
        "correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
    }
}

Recepción de datos de transcripción

Luego de los metadatos, los siguientes paquetes que recibirá su web socket serán TranscriptionData para el audio 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"
    }
}

Manejo del flujo de transcripción en el servidor 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();

Actualice su código para el controlador de 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);
        }
    }
}

Actualizar transcripción

En situaciones en las que su aplicación permite a los usuarios seleccionar su idioma preferido, es posible que también desee capturar la transcripción en ese idioma. Para ello, Call Automation SDK le permite actualizar la configuración regional de transcripción.

await callMedia.UpdateTranscriptionAsync("en-US-NancyNeural");

Detener la transcripción

Cuando su aplicación necesite dejar de escuchar la transcripción, puede utilizar la petición StopTranscription para indicar a Call Automation que deje de enviar datos de transcripción a su socket web.

StopTranscriptionOptions stopOptions = new StopTranscriptionOptions()
{
    OperationContext = "stopTranscription"
};

await callMedia.StopTranscriptionAsync(stopOptions);

Cree una convocatoria y proporcione los datos de transcripción

Defina las TranscriptionOptions para que ACS especifique cuándo iniciar la transcripción, la configuración regional para la transcripción y la conexión de socket web para enviar la transcripción.

CallInvite callInvite = new CallInvite(target, caller); 

CallIntelligenceOptions callIntelligenceOptions = new CallIntelligenceOptions()
    .setCognitiveServicesEndpoint(appConfig.getCognitiveServiceEndpoint()); 

TranscriptionOptions transcriptionOptions = new TranscriptionOptions(
    appConfig.getWebSocketUrl(), 
    TranscriptionTransport.WEBSOCKET, 
    "en-US", 
    false
); 

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(); 

Conectarse a una llamada de Salas y proporcionar detalles de la transcripción

Si se conecta a una sala ACS y desea utilizar la transcripción, configure las opciones de transcripción como se indica a continuación:

TranscriptionOptions transcriptionOptions = new TranscriptionOptions(
    appConfig.getWebSocketUrl(), 
    TranscriptionTransport.WEBSOCKET, 
    "en-US", 
    false
);

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 transcripción

Una vez que esté listo para iniciar la transcripción, puede realizar una llamada explícita a Automatización de llamadas para comenzar a transcribir la llamada.

//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();

Recepción del flujo de transcripciones

Cuando se inicia la transcripción, su websocket recibe la carga útil de metadatos de transcripción como primer paquete.

{
    "kind": "TranscriptionMetadata",
    "transcriptionMetadata": {
        "subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
        "locale": "en-us",
        "callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
        "correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
    }
}

Recepción de datos de transcripción

Luego de los metadatos, los siguientes paquetes que recibirá su web socket serán TranscriptionData para el audio 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"
    }
}

Manejo del flujo de transcripción en el servidor 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();
        }
    }
}

Actualice su código para el controlador de 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("----------------------------------------------------------------");
        }
    }
}

Actualizar transcripción

En situaciones en las que su aplicación permite a los usuarios seleccionar su idioma preferido, es posible que también desee capturar la transcripción en ese idioma. Para ello, Call Automation SDK le permite actualizar la configuración regional de transcripción.

client.getCallConnection(callConnectionId)
    .getCallMedia()
    .updateTranscription("en-US-NancyNeural");

Detener la transcripción

Cuando su aplicación necesite dejar de escuchar la transcripción, puede utilizar la petición StopTranscription para indicar a Call Automation que deje de enviar datos de transcripción a su socket 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();

Cree una convocatoria y proporcione los datos de transcripción

Defina las TranscriptionOptions para que ACS especifique cuándo iniciar la transcripción, la configuración regional para la transcripción y la conexión de socket web para enviar la transcripción.

const transcriptionOptions = {
    transportUrl: "",
    transportType: "websocket",
    locale: "en-US",
    startTranscription: false
};

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);

Conectarse a una llamada de Salas y proporcionar detalles de la transcripción

Si se conecta a una sala ACS y desea utilizar la transcripción, configure las opciones de transcripción como se indica a continuación:

const transcriptionOptions = {
    transportUri: "",
    locale: "en-US",
    transcriptionTransport: "websocket",
    startTranscription: false
};

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 transcripción

Una vez que esté listo para iniciar la transcripción, puede realizar una llamada explícita a Automatización de llamadas para comenzar a transcribir la llamada.

const startTranscriptionOptions = {
    locale: "en-AU",
    operationContext: "startTranscriptionContext"
};

// Start transcription with options
await callMedia.startTranscription(startTranscriptionOptions);

// Alternative: Start transcription without options
// await callMedia.startTranscription();

Recepción del flujo de transcripciones

Cuando se inicia la transcripción, su websocket recibe la carga útil de metadatos de transcripción como primer paquete.

{
    "kind": "TranscriptionMetadata",
    "transcriptionMetadata": {
        "subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
        "locale": "en-us",
        "callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
        "correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
    }
}

Recepción de datos de transcripción

Luego de los metadatos, los siguientes paquetes que recibirá su web socket serán TranscriptionData para el audio 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"
    }
}

Manejo del flujo de transcripción en el servidor 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);
        
        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');

Actualizar transcripción

En situaciones en las que su aplicación permite a los usuarios seleccionar su idioma preferido, es posible que también desee capturar la transcripción en ese idioma. Para realizar esta tarea, el SDK de automatización de llamadas le permite actualizar la configuración regional de transcripción.

await callMedia.updateTranscription("en-US-NancyNeural");

Detener la transcripción

Cuando su aplicación necesite dejar de escuchar la transcripción, puede utilizar la petición StopTranscription para indicar a Call Automation que deje de enviar datos de transcripción a su socket web.

const stopTranscriptionOptions = {
    operationContext: "stopTranscriptionContext"
};

// Stop transcription with options
await callMedia.stopTranscription(stopTranscriptionOptions);

// Alternative: Stop transcription without options
// await callMedia.stopTranscription();

Cree una convocatoria y proporcione los datos de transcripción

Defina las TranscriptionOptions para que ACS especifique cuándo iniciar la transcripción, la configuración regional para la transcripción y la conexión de socket web para enviar la transcripción.

transcription_options = TranscriptionOptions(
    transport_url=" ",
    transport_type=TranscriptionTransportType.WEBSOCKET,
    locale="en-US",
    start_transcription=False
)

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
)

Conectarse a una llamada de Salas y proporcionar detalles de la transcripción

Si se conecta a una sala ACS y desea utilizar la transcripción, configure las opciones de transcripción como se indica a continuación:

transcription_options = TranscriptionOptions(
    transport_url="",
    transport_type=TranscriptionTransportType.WEBSOCKET,
    locale="en-US",
    start_transcription=False
)

connect_result = client.connect_call(
    room_id="roomid",
    CALLBACK_EVENTS_URI,
    cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT,
    operation_context="connectCallContext",
    transcription=transcription_options
)

Iniciar transcripción

Una vez que esté listo para iniciar la transcripción, puede realizar una llamada explícita a Automatización de llamadas para comenzar a transcribir la llamada.

# 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")

Recepción del flujo de transcripciones

Cuando se inicia la transcripción, su websocket recibe la carga útil de metadatos de transcripción como primer paquete.

{
    "kind": "TranscriptionMetadata",
    "transcriptionMetadata": {
        "subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
        "locale": "en-us",
        "callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
        "correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
    }
}

Recepción de datos de transcripción

Después de los metadatos, los siguientes paquetes que recibirá su websocket serán TranscriptionData para el audio 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"
    }
}

Manejo del flujo de transcripción en el servidor 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'])
            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()

Actualizar transcripción

En situaciones en las que su aplicación permite a los usuarios seleccionar su idioma preferido, es posible que también desee capturar la transcripción en ese idioma. Para realizar esta tarea, el SDK de automatización de llamadas le permite actualizar la configuración regional de transcripción.

await call_connection_client.update_transcription(locale="en-US-NancyNeural")

Detener la transcripción

Cuando su aplicación necesite dejar de escuchar la transcripción, puede utilizar la petición StopTranscription para indicar a Call Automation que deje de enviar datos de transcripción a su socket 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 code subcódigo Mensaje
TranscriptionStarted 200 0 La acción se ha completado correctamente.
TranscriptionStopped 200 0 La acción se ha completado correctamente.
TranscriptionUpdated 200 0 La acción se ha completado correctamente.
TranscriptionFailed 400 8581 Acción fallida, StreamUrl no es válido.
TrasncriptionFailed 400 8565 Acción fallida debido a una mala solicitud a Cognitive Services. Compruebe los parámetros de entrada.
TranscriptionFailed 400 8565 La acción falló debido a que se agotó el tiempo de espera de la solicitud a los Cognitive Services. Vuelva a intentarlo más tarde o compruebe si hay algún problema con el servicio.
TranscriptionFailed 400 8605 No se admite el modelo de reconocimiento de voz personalizado para la transcripción.
TranscriptionFailed 400 8523 Solicitud no válida, falta la configuración regional.
TranscriptionFailed 400 8523 Solicitud no válida, solo se admiten las configuraciones regionales que contienen información sobre la región.
TranscriptionFailed 405 8520 La función de transcripción no está disponible en este momento.
TranscriptionFailed 405 8520 UpdateTranscription no es compatible con la conexión creada con la interfaz Connect.
TranscriptionFailed 400 8528 La acción no es válida, la llamada ya ha finalizado.
TranscriptionFailed 405 8520 La función de transcripción de actualizaciones no está disponible en este momento.
TranscriptionFailed 405 8522 Solicitud no permitida cuando la URL de transcripción no está configurada durante la configuración de la llamada.
TranscriptionFailed 405 8522 Solicitud no permitida cuando la Configuración del Cognitive Service no se ha establecido durante el establecimiento de la llamada.
TranscriptionFailed 400 8501 La acción no es válida cuando la llamada no está en estado Establecido.
TranscriptionFailed 401 8565 La acción ha fallado debido a un error de autenticación de Cognitive Services. Compruebe la entrada de autorización y asegúrese de que es correcta.
TranscriptionFailed 403 8565 Acción fallida debido a una petición prohibida a Cognitive Services. Compruebe el estado de su suscripción y asegúrese de que está activa.
TranscriptionFailed 429 8565 Acción fallida, las peticiones excedieron el número de peticiones concurrentes permitidas para la suscripción de servicios cognitivos.
TranscriptionFailed 500 8578 Acción fallida, no se ha podido establecer la conexión WebSocket.
TranscriptionFailed 500 8580 Acción fallida, el servicio de transcripción se cerró.
TranscriptionFailed 500 8579 Acción fallida, transcripción cancelada.
TranscriptionFailed 500 9999 Error interno desconocido del servidor.

Problemas conocidos

  • Para llamadas 1:1 con usuarios de ACS que utilicen SDKs de cliente, startTranscription = True no está soportado actualmente.