Udostępnij za pośrednictwem


Dodawanie transkrypcji w czasie rzeczywistym do aplikacji

Ważne

Funkcje opisane w tym artykule są obecnie dostępne w publicznej wersji zapoznawczej. Ta wersja zapoznawcza jest udostępniana bez umowy dotyczącej poziomu usług i nie zalecamy korzystania z niej w przypadku obciążeń produkcyjnych. Niektóre funkcje mogą być nieobsługiwane lub ograniczone. Aby uzyskać więcej informacji, zobacz Uzupełniające warunki korzystania z wersji zapoznawczych platformy Microsoft Azure.

Ten przewodnik pomaga lepiej zrozumieć różne sposoby korzystania z usług Azure Communication Services oferujących transkrypcję w czasie rzeczywistym za pomocą zestawów SDK usługi Call Automation.

Wymagania wstępne

Konfigurowanie serwera WebSocket

Usługi Azure Communication Services wymagają, aby aplikacja serwera skonfigurowała serwer WebSocket w celu przesyłania strumieniowego transkrypcji w czasie rzeczywistym. WebSocket to ustandaryzowany protokół, który zapewnia kanał komunikacji pełnodupleksowej za pośrednictwem jednego połączenia TCP. Opcjonalnie możesz użyć usług platformy Azure WebApps, które umożliwiają tworzenie aplikacji w celu odbierania transkrypcji za pośrednictwem połączenia websocket. Postępuj zgodnie z tym quickstartem.

Nawiąż połączenie

W tym szybkim starcie zakładamy, że znasz już rozpoczynanie rozmów. Jeśli chcesz dowiedzieć się więcej na temat uruchamiania i nawiązywania połączeń, możesz skorzystać z naszego przewodnika Szybki start. Na potrzeby tego samouczka Quickstart, przeprowadzamy proces uruchamiania transkrypcji dla połączeń przychodzących i wychodzących.

Podczas pracy z transkrypcją w czasie rzeczywistym masz kilka opcji dotyczących tego, kiedy i jak rozpocząć transkrypcję:

Opcja 1 — Rozpoczęcie z chwilą odbierania lub nawiązywania połączenia

Opcja 2 — rozpoczynanie transkrypcji w trakcie trwającej rozmowy

Opcja 3 — rozpoczynanie transkrypcji podczas nawiązywania połączenia z Azure Communication Services Rooms

W tym samouczku demonstrujemy opcję 2 i 3, rozpoczynając transkrypcję podczas trwającego połączenia lub podczas łączenia się z połączeniem Rooms. Domyślnie parametr "startTranscription" jest ustawiony na wartość false w czasie odpowiadania lub tworzenia połączenia.

Utwórz wywołanie i podaj szczegóły transkrypcji

Zdefiniuj TranscriptionOptions dla usługi ACS, aby określić, kiedy rozpocząć transkrypcję, ustawić lokalizację dla transkrypcji i połączenie gniazda sieciowego do przesyłania transkryptu.

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

Nawiązywanie połączenia z usługą Rooms i podawanie szczegółów transkrypcji

Jeśli łączysz się z pokojem ACS i chcesz używać transkrypcji, skonfiguruj opcje transkrypcji w następujący sposób:

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

Rozpocznij transkrypcję

Gdy wszystko będzie gotowe do rozpoczęcia transkrypcji, możesz wykonać jawne wywołanie usługi Call Automation, aby rozpocząć transkrypcję wywołania.

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

Odbieranie strumienia transkrypcji

Po rozpoczęciu transkrypcji websocket odbiera ładunek metadanych transkrypcji jako pierwszy pakiet.

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

Odbieranie danych transkrypcji

Po metadanych kolejne pakiety odbierane przez gniazdo internetowe będą transkrypcjiData dla transkrypcji audio.

{
    "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"
    }
}

Zarządzanie strumieniem transkrypcji na serwerze WebSocket

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

Aktualizacje kodu programu obsługi protokołu 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);
        }
    }
}

Aktualizowanie transkrypcji

W sytuacjach, w których aplikacja umożliwia użytkownikom wybór preferowanego języka, możesz również przechwycić transkrypcję w tym języku. W tym celu zestaw Call Automation SDK umożliwia aktualizowanie ustawień regionalnych transkrypcji.

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

Zatrzymaj transkrypcję

Gdy aplikacja musi przestać nasłuchiwać transkrypcji, możesz użyć żądania StopTranscription, aby poinformować usługę Call Automation o zaprzestaniu wysyłania danych transkrypcji do gniazda internetowego.

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

await callMedia.StopTranscriptionAsync(stopOptions);

Utwórz połączenie i podaj szczegóły transkrypcji

Zdefiniuj Opcje transkrypcji dla ACS, aby określić, kiedy uruchomić transkrypcję, ustawienia regionalne transkrypcji oraz połączenie gniazda internetowego do wysyłania transkrypcji.

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

Nawiązywanie połączenia z usługą Rooms i podawanie szczegółów transkrypcji

Jeśli łączysz się z pokojem ACS i chcesz używać transkrypcji, skonfiguruj opcje transkrypcji w następujący sposób:

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

Rozpocznij transkrypcję

Gdy wszystko będzie gotowe do rozpoczęcia transkrypcji, możesz wykonać jawne wywołanie usługi Call Automation, aby rozpocząć transkrypcję wywołania.

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

Odbieranie strumienia transkrypcji

Po rozpoczęciu transkrypcji zestaw websocket odbiera ładunek metadanych transkrypcji jako pierwszy pakiet.

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

Odbieranie danych transkrypcji

Po metadanych kolejne pakiety odbierane przez gniazdo internetowe będą transkrypcjiData dla transkrypcji audio.

{
    "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"
    }
}

Obsługa strumienia transkrypcji na serwerze gniazd internetowych

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

Aktualizacje kodu programu obsługi protokołu 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("----------------------------------------------------------------");
        }
    }
}

Aktualizowanie transkrypcji

W sytuacjach, w których aplikacja umożliwia użytkownikom wybór preferowanego języka, możesz również przechwycić transkrypcję w tym języku. W tym celu zestaw Call Automation SDK umożliwia aktualizowanie ustawień regionalnych transkrypcji.

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

Zatrzymaj transkrypcję

Gdy aplikacja musi przestać nasłuchiwać transkrypcji, możesz użyć żądania StopTranscription, aby poinformować usługę Call Automation o zaprzestaniu wysyłania danych transkrypcji do gniazda internetowego.

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

Utwórz połączenie i podaj szczegóły transkrypcji

Zdefiniuj Opcje transkrypcji dla usługi ACS, aby określić, kiedy należy uruchomić transkrypcję, lokalizację transkrypcji i połączenie WebSocket na potrzeby wysyłania transkrypcji.

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

Nawiązywanie połączenia z usługą Rooms i podawanie szczegółów transkrypcji

Jeśli łączysz się z pokojem ACS i chcesz używać transkrypcji, skonfiguruj opcje transkrypcji w następujący sposób:

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

Rozpocznij transkrypcję

Gdy wszystko będzie gotowe do rozpoczęcia transkrypcji, możesz wykonać jawne wywołanie usługi Call Automation, aby rozpocząć transkrypcję wywołania.

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

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

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

Odbieranie strumienia transkrypcji

Po rozpoczęciu transkrypcji zestaw websocket odbiera ładunek metadanych transkrypcji jako pierwszy pakiet.

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

Odbieranie danych transkrypcji

Po metadanych kolejne pakiety odbierane przez gniazdo sieciowe będą danymi transkrypcji dla przetłumaczonego dźwięku.

{
    "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"
    }
}

Obsługa strumienia transkrypcji na serwerze WebSocket

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

Aktualizowanie transkrypcji

W sytuacjach, w których aplikacja umożliwia użytkownikom wybór preferowanego języka, możesz również przechwycić transkrypcję w tym języku. Aby wykonać to zadanie, zestaw Sdk usługi Call Automation umożliwia aktualizowanie ustawień regionalnych transkrypcji.

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

Zatrzymaj transkrypcję

Gdy aplikacja musi przestać nasłuchiwać transkrypcji, możesz użyć żądania StopTranscription, aby poinformować usługę Call Automation o zaprzestaniu wysyłania danych transkrypcji do gniazda internetowego.

const stopTranscriptionOptions = {
    operationContext: "stopTranscriptionContext"
};

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

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

Utwórz wywołanie i podaj szczegóły transkrypcji

Zdefiniuj OpcjeTranskrypcji dla usługi ACS, aby określić, kiedy należy uruchomić transkrypcję, ustawienia regionalne transkrypcji i połączenie przez gniazdo internetowe na potrzeby wysyłania transkrypcji.

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
)

Nawiązywanie połączenia z usługą Rooms i podawanie szczegółów transkrypcji

Jeśli łączysz się z pokojem ACS i chcesz używać transkrypcji, skonfiguruj opcje transkrypcji w następujący sposób:

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
)

Rozpocznij transkrypcję

Gdy wszystko będzie gotowe do rozpoczęcia transkrypcji, możesz wykonać jawne wywołanie usługi Call Automation, aby rozpocząć transkrypcję wywołania.

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

Odbieranie strumienia transkrypcji

Po rozpoczęciu transkrypcji zestaw websocket odbiera ładunek metadanych transkrypcji jako pierwszy pakiet.

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

Odbieranie danych transkrypcji

Po metadanych kolejne pakiety odbierane przez websocket będą zawierały dane transkrypcji dla przetworzonego audio.

{
    "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"
    }
}

Obsługa strumienia transkrypcji na serwerze gniazda sieciowego

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

Aktualizowanie transkrypcji

W sytuacjach, w których aplikacja umożliwia użytkownikom wybór preferowanego języka, możesz również przechwycić transkrypcję w tym języku. Aby wykonać to zadanie, zestaw Sdk usługi Call Automation umożliwia aktualizowanie ustawień regionalnych transkrypcji.

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

Zatrzymaj transkrypcję

Gdy aplikacja musi przestać nasłuchiwać transkrypcji, możesz użyć żądania StopTranscription, aby poinformować usługę Call Automation o zaprzestaniu wysyłania danych transkrypcji do gniazda internetowego.

# Stop transcription without options
call_connection_client.stop_transcription()

# Alternative: Stop transcription with operation context
# call_connection_client.stop_transcription(operation_context="stopTranscriptionContext")

Kody zdarzeń

Zdarzenie kod Subkod Komunikat
Rozpoczęto transkrypcję 200 0 Akcja została ukończona pomyślnie.
TranskrypcjaZatrzymana 200 0 Akcja została ukończona pomyślnie.
Zaktualizowana transkrypcja 200 0 Akcja została ukończona pomyślnie.
Transkrypcja nie powiodła się 400 8581 Akcja nie powiodła się. Usługa StreamUrl jest nieprawidłowa.
NieudanaTranskrypcja 400 8565 Akcja nie powiodła się z powodu nieprawidłowego żądania do Cognitive Services. Sprawdź parametry wejściowe.
Nieudana transkrypcja 400 8565 Akcja nie powiodła się, ponieważ żądanie do usług Cognitive Services przekroczyło limit czasu. Spróbuj ponownie później lub sprawdź, czy nie ma problemów z usługą.
TranskrypcjaNiepowodzenie 400 8605 Niestandardowy model rozpoznawania mowy dla transkrypcji nie jest obsługiwany.
NieudanaTranskrypcja 400 8523 Żądanie jest nieprawidłowe, brakuje ustawień regionalnych.
Transkrypcja nieudana 400 8523 Nieprawidłowe żądanie, obsługiwane są tylko ustawienia regionalne zawierające informacje o regionie.
Niepowodzenie transkrypcji 405 8520 Obecnie funkcja transkrypcji nie jest obsługiwana.
TranskrypcjaNieudana 405 8520 Funkcja UpdateTranscription nie jest obsługiwana w przypadku połączenia utworzonego za pomocą interfejsu Connect.
TranskrypcjaNieudana 400 8528 Działanie jest nieprawidłowe, wywołanie zostało już zakończone.
NieudanaTranskrypcja 405 8520 Aktualizacja funkcjonalności transkrypcji nie jest obecnie wspierana.
TranskrypcjaNieudana 405 8522 Żądanie jest niedozwolone, gdy adres URL transkrypcji nie jest ustawiony podczas konfigurowania wywołania.
TranskrypcjaNieudana 405 8522 Żądanie jest niedozwolone, jeśli konfiguracja usługi Cognitive Service nie jest ustawiona przy inicjacji połączenia.
Niepowodzenie transkrypcji 400 8501 Akcja jest nieprawidłowa, gdy połączenie nie jest w stanie nawiązanym.
TranskrypcjaNieudana 401 8565 Akcja nie powiodła się z powodu błędu uwierzytelniania usług Cognitive Services. Sprawdź dane wejściowe autoryzacji i upewnij się, że jest ona poprawna.
Niepowodzenie transkrypcji 403 8565 Akcja nie powiodła się z powodu niedozwolonego żądania do usługi Cognitive Services. Sprawdź stan subskrypcji i upewnij się, że jest ona aktywna.
TranskrypcjaNieudana 429 8565 Akcja nie powiodła się. Żądania przekroczyły liczbę dozwolonych współbieżnych żądań dla subskrypcji usług Cognitive Services.
NieudanaTranskrypcja 500 8578 Akcja nie powiodła się, nie można nawiązać połączenia protokołu WebSocket.
TranskrypcjaNieudana 500 8580 Akcja nie powiodła się. Usługa transkrypcji została zamknięta.
TranskrypcjaNieudana 500 8579 Akcja nie powiodła się, transkrypcja została anulowana.
TranskrypcjaNieudana 500 9999 Nieznany wewnętrzny błąd serwera.

Znane problemy

  • Dla wywołań 1:1 z użytkownikami usługi ACS, korzystając z klienta SDK, startTranscription = True nie jest obecnie obsługiwane.