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 przewodnikiem Szybki start.

Ustanawianie połączenia

W tym przewodniku Szybki start założono, że znasz już uruchamianie wywołań. 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 przewodnika Szybki start przeprowadzimy proces uruchamiania transkrypcji zarówno dla wywołań przychodzących, jak i wywołań wychodzących.

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

Opcja 1 — rozpoczynanie odpowiedzi lub tworzenie połączenia

Opcja 2 — rozpoczynanie transkrypcji podczas trwającego wywołania

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

Tworzenie wywołania i podawanie szczegółów transkrypcji

Zdefiniuj transkrypcjęOpcje dla usługi ACS, aby wiedzieć, czy od razu rozpocząć transkrypcję, czy później, które ustawienia regionalne do transkrypcji mają być transkrypcyjne i połączenie gniazda sieci Web używane do wysyłania transkrypcji.

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

Rozpocznij transkrypcję

Gdy wszystko będzie gotowe do rozpoczęcia transkrypcji, możesz utworzyć 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 zestaw websocket otrzyma ładunek metadanych transkrypcji jako pierwszy pakiet. Ten ładunek zawiera metadane wywołań i ustawienia regionalne dla konfiguracji.

{
    "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ą transkrypcjaData 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

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

Zatrzymywanie transkrypcji

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

Tworzenie wywołania i podawanie szczegółów transkrypcji

Zdefiniuj transkrypcjęOpcje dla usługi ACS, aby wiedzieć, czy od razu rozpocząć transkrypcję, czy później, które ustawienia regionalne do transkrypcji mają być transkrypcyjne i połączenie gniazda sieci Web używane 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(); 

Rozpocznij transkrypcję

Gdy wszystko będzie gotowe do rozpoczęcia transkrypcji, możesz utworzyć 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 otrzyma ładunek metadanych transkrypcji jako pierwszy pakiet. Ten ładunek zawiera metadane wywołań i ustawienia regionalne dla konfiguracji.

{
    "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ą transkrypcjaData 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");

Zatrzymywanie transkrypcji

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

Tworzenie wywołania i podawanie szczegółów transkrypcji

Zdefiniuj transkrypcjęOpcje dla usługi ACS, aby wiedzieć, czy od razu rozpocząć transkrypcję, czy później, które ustawienia regionalne mają być transkrypcyjne, oraz połączenie gniazda sieci Web używane do 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);

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 otrzyma ładunek metadanych transkrypcji jako pierwszy pakiet. Ten ładunek zawiera metadane wywołań i ustawienia regionalne dla konfiguracji.

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

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. W tym celu zestaw SDK usługi Call Automation umożliwia aktualizowanie ustawień regionalnych transkrypcji.

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

Zatrzymywanie transkrypcji

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

Tworzenie wywołania i podawanie szczegółów transkrypcji

Zdefiniuj transkrypcjęOpcje dla usługi ACS, aby wiedzieć, czy od razu rozpocząć transkrypcję, czy później, które ustawienia regionalne mają być transkrypcyjne, oraz połączenie gniazda sieci Web używane do 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
)

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 otrzyma ładunek metadanych transkrypcji jako pierwszy pakiet. Ten ładunek zawiera metadane wywołań i ustawienia regionalne dla konfiguracji.

{
    "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 zestaw websocket będą transkrypcjiData dla transkrypcji 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 gniazd internetowych

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. W tym celu zestaw SDK usługi Call Automation umożliwia aktualizowanie ustawień regionalnych transkrypcji.

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

Zatrzymywanie transkrypcji

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 code Subcode Komunikat
TranskrypcjaStarted 200 0 Akcja została ukończona pomyślnie.
TranskrypcjaStopped 200 0 Akcja została ukończona pomyślnie.
TranskrypcjaUpdated 200 0 Akcja została ukończona pomyślnie.
TranskrypcjaFailed 400 8581 Akcja nie powiodła się. Usługa StreamUrl jest nieprawidłowa.
TrasncriptionFailed 400 8565 Akcja nie powiodła się z powodu nieprawidłowego żądania do usług Cognitive Services. Sprawdź parametry wejściowe.
TranskrypcjaFailed 400 8565 Akcja nie powiodła się z powodu limitu czasu żądania do usług Cognitive Services. Spróbuj ponownie później lub sprawdź, czy występują problemy z usługą.
TranskrypcjaFailed 400 8605 Niestandardowy model rozpoznawania mowy dla transkrypcji nie jest obsługiwany.
TranskrypcjaFailed 400 8523 Brak nieprawidłowych ustawień regionalnych.
TranskrypcjaFailed 400 8523 Nieprawidłowe żądanie— obsługiwane są tylko ustawienia regionalne zawierające informacje o regionie.
TranskrypcjaFailed 405 8520 Obecnie funkcja transkrypcji nie jest obsługiwana.
TranskrypcjaFailed 405 8520 Funkcja UpdateTranscription nie jest obsługiwana w przypadku połączenia utworzonego za pomocą interfejsu Connect.
TranskrypcjaFailed 400 8528 Akcja jest nieprawidłowa, wywołanie zostało już zakończone.
TranskrypcjaFailed 405 8520 Aktualizacja funkcji transkrypcji nie jest obecnie obsługiwana.
TranskrypcjaFailed 405 8522 Żądanie jest niedozwolone, gdy adres URL transkrypcji nie jest ustawiony podczas konfigurowania wywołania.
TranskrypcjaFailed 405 8522 Żądanie jest niedozwolone, gdy konfiguracja usługi Cognitive Service nie jest ustawiona podczas konfigurowania wywołania.
TranskrypcjaFailed 400 8501 Akcja jest nieprawidłowa, gdy wywołanie nie jest w stanie Ustanowione.
TranskrypcjaFailed 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.
TranskrypcjaFailed 403 8565 Akcja nie powiodła się z powodu niedozwolonego żądania do usług Cognitive Services. Sprawdź stan subskrypcji i upewnij się, że jest ona aktywna.
TranskrypcjaFailed 429 8565 Akcja nie powiodła się. Żądania przekroczyły liczbę dozwolonych współbieżnych żądań dla subskrypcji usług Cognitive Services.
TranskrypcjaFailed 500 8578 Akcja nie powiodła się, nie można nawiązać połączenia protokołu WebSocket.
TranskrypcjaFailed 500 8580 Akcja nie powiodła się. Usługa transkrypcji została zamknięta.
TranskrypcjaFailed 500 8579 Akcja nie powiodła się, transkrypcja została anulowana.
TranskrypcjaFailed 500 9999 Nieznany wewnętrzny błąd serwera.

Znane problemy

  • W przypadku wywołań 1:1 z użytkownikami usługi ACS przy użyciu zestawów SDK klienta startTranscription = True nie jest obecnie obsługiwane.