애플리케이션에 실시간 전사 추가
Important
이 문서에 설명된 기능은 현재 공개 미리 보기로 제공됩니다. 이 미리 보기 버전은 서비스 수준 계약 없이 제공되며, 프로덕션 워크로드에는 권장되지 않습니다. 특정 기능이 지원되지 않거나 기능이 제한될 수 있습니다. 자세한 내용은 Microsoft Azure Preview에 대한 추가 사용 약관을 참조하세요.
이 가이드는 통화 자동화 SDK를 통해 실시간 전사의 Azure Communication Services 제품을 사용할 수 있는 다양한 방법을 더 잘 이해하는 데 도움이 됩니다.
필수 조건
- 활성 구독이 있는 Azure 계정입니다. 자세한 내용은 무료 계정 만들기를 참조하세요.
- Azure Communication Services 리소스. Azure Communication Services 리소스 만들기를 참조하세요.
- Azure AI 서비스를 만들고 Azure Communication Services 리소스에 연결합니다.
- Azure AI Services 리소스에 대한 사용자 지정 하위 도메인을 만듭니다.
- 통화 자동화 SDK를 사용하여 새 웹 서비스 애플리케이션을 만듭니다.
WebSocket 서버 설정
Azure Communication Services를 사용하려면 서버 애플리케이션에서 WebSocket 서버를 설정하여 전사를 실시간으로 스트리밍해야 합니다. WebSocket은 단일 TCP 연결을 통해 전체 이중 통신 채널을 제공하는 표준화된 프로토콜입니다. 필요에 따라 websocket 연결을 통해 스크립트를 수신하는 애플리케이션을 만들 수 있는 Azure 서비스 Azure WebApps를 사용할 수 있습니다. 이 빠른 시작을 따릅니다.
통화 설정
이 빠른 시작에서는 통화를 시작하는 데 이미 익숙하다고 가정합니다. 호출 시작 및 설정에 대해 자세히 알아보아야 하는 경우 빠른 시작을 따를 수 있습니다. 이 빠른 시작에서는 수신 전화와 발신 전화 모두에 대해 전사를 시작하는 프로세스를 진행합니다.
실시간 전사로 작업할 때 전사를 시작하는 시기와 방법에 대해 다음과 같은 몇 가지 옵션이 있습니다.
옵션 1 - 전화를 받거나 전화를 할 때 시작
옵션 2 - 진행 중인 통화 중에 전사 시작
이 자습서에서는 진행 중인 통화 중에 전사를 시작하는 옵션 2를 시연합니다. 기본적으로 'startTranscription'은 전화를 받거나 전화를 할 때 false로 설정됩니다.
전화하기 및 전사 세부 정보 제공
전사를 바로 시작할지 나중에 시작할지, 전사할 로캘 및 스크립트를 보내는 데 사용할 웹 소켓 연결을 알 수 있도록 ACS용 TranscriptionOptions를 정의합니다.
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);
전사 시작
전사를 시작할 준비가 되면 통화 자동화를 명시적으로 호출하여 통화 전사를 시작할 수 있습니다.
// 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();
전사 스트림 수신
전사가 시작되면 websocket은 전사 메타데이터 페이로드를 첫 번째 패킷으로 받습니다. 이 페이로드는 구성에 대한 호출 메타데이터 및 로캘을 전달합니다.
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
전사 데이터 수신
메타데이터 후에 웹 소켓이 수신하는 다음 패킷은 전사된 오디오에 대한 TranscriptionData가 됩니다.
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "Testing transcription.",
"format": "display",
"confidence": 0.695223331451416,
"offset": 2516998782481234400,
"words": [
{
"text": "testing",
"offset": 2516998782481234400
},
{
"text": "testing",
"offset": 2516998782481234400
}
],
"participantRawID": "8:acs:",
"resultStatus": "Final"
}
}
웹 소켓 서버에서 전사 스트림 처리
using WebServerApi;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseWebSockets();
app.Map("/ws", async context =>
{
if (context.WebSockets.IsWebSocketRequest)
{
using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
await HandleWebSocket.Echo(webSocket);
}
else
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
}
});
app.Run();
websocket 처리기에 대한 코드 업데이트
using Azure.Communication.CallAutomation;
using System.Net.WebSockets;
using System.Text;
namespace WebServerApi
{
public class HandleWebSocket
{
public static async Task Echo(WebSocket webSocket)
{
var buffer = new byte[1024 * 4];
var receiveResult = await webSocket.ReceiveAsync(
new ArraySegment(buffer), CancellationToken.None);
while (!receiveResult.CloseStatus.HasValue)
{
string msg = Encoding.UTF8.GetString(buffer, 0, receiveResult.Count);
var response = StreamingDataParser.Parse(msg);
if (response != null)
{
if (response is AudioMetadata audioMetadata)
{
Console.WriteLine("***************************************************************************************");
Console.WriteLine("MEDIA SUBSCRIPTION ID-->"+audioMetadata.MediaSubscriptionId);
Console.WriteLine("ENCODING-->"+audioMetadata.Encoding);
Console.WriteLine("SAMPLE RATE-->"+audioMetadata.SampleRate);
Console.WriteLine("CHANNELS-->"+audioMetadata.Channels);
Console.WriteLine("LENGTH-->"+audioMetadata.Length);
Console.WriteLine("***************************************************************************************");
}
if (response is AudioData audioData)
{
Console.WriteLine("***************************************************************************************");
Console.WriteLine("DATA-->"+audioData.Data);
Console.WriteLine("TIMESTAMP-->"+audioData.Timestamp);
Console.WriteLine("IS SILENT-->"+audioData.IsSilent);
Console.WriteLine("***************************************************************************************");
}
if (response is TranscriptionMetadata transcriptionMetadata)
{
Console.WriteLine("***************************************************************************************");
Console.WriteLine("TRANSCRIPTION SUBSCRIPTION ID-->"+transcriptionMetadata.TranscriptionSubscriptionId);
Console.WriteLine("LOCALE-->"+transcriptionMetadata.Locale);
Console.WriteLine("CALL CONNECTION ID--?"+transcriptionMetadata.CallConnectionId);
Console.WriteLine("CORRELATION ID-->"+transcriptionMetadata.CorrelationId);
Console.WriteLine("***************************************************************************************");
}
if (response is TranscriptionData transcriptionData)
{
Console.WriteLine("***************************************************************************************");
Console.WriteLine("TEXT-->"+transcriptionData.Text);
Console.WriteLine("FORMAT-->"+transcriptionData.Format);
Console.WriteLine("OFFSET-->"+transcriptionData.Offset);
Console.WriteLine("DURATION-->"+transcriptionData.Duration);
Console.WriteLine("PARTICIPANT-->"+transcriptionData.Participant.RawId);
Console.WriteLine("CONFIDENCE-->"+transcriptionData.Confidence);
foreach (var word in transcriptionData.Words)
{
Console.WriteLine("TEXT-->"+word.Text);
Console.WriteLine("OFFSET-->"+word.Offset);
Console.WriteLine("DURATION-->"+word.Duration);
}
Console.WriteLine("***************************************************************************************");
}
}
await webSocket.SendAsync(
new ArraySegment(buffer, 0, receiveResult.Count),
receiveResult.MessageType,
receiveResult.EndOfMessage,
CancellationToken.None);
receiveResult = await webSocket.ReceiveAsync(
new ArraySegment(buffer), CancellationToken.None);
}
await webSocket.CloseAsync(
receiveResult.CloseStatus.Value,
receiveResult.CloseStatusDescription,
CancellationToken.None);
}
}
}
전사 업데이트
애플리케이션에서 사용자가 원하는 언어를 선택할 수 있는 경우 해당 언어로 전사를 캡처할 수도 있습니다. 이를 위해 통화 자동화 SDK를 사용하여 전사 로캘을 업데이트할 수 있습니다.
await callMedia.UpdateTranscriptionAsync("en-US-NancyNeural");
전사 중지
애플리케이션에서 전사 수신 대기를 중지해야 하는 경우 StopTranscription 요청을 사용하여 통화 자동화 기능에 스크립트 데이터를 웹 소켓으로 보내는 것을 중지할 것을 알릴 수 있습니다.
StopTranscriptionOptions stopOptions = new StopTranscriptionOptions()
{
OperationContext = "stopTranscription"
};
await callMedia.StopTranscriptionAsync(stopOptions);
전화하기 및 전사 세부 정보 제공
전사를 바로 시작할지 나중에 시작할지, 전사할 로캘 및 스크립트를 보내는 데 사용할 웹 소켓 연결을 알 수 있도록 ACS용 TranscriptionOptions를 정의합니다.
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();
전사 시작
전사를 시작할 준비가 되면 통화 자동화를 명시적으로 호출하여 통화 전사를 시작할 수 있습니다.
//Option 1: Start transcription with options
StartTranscriptionOptions transcriptionOptions = new StartTranscriptionOptions()
.setOperationContext("startMediaStreamingContext");
client.getCallConnection(callConnectionId)
.getCallMedia()
.startTranscriptionWithResponse(transcriptionOptions, Context.NONE);
// Alternative: Start transcription without options
// client.getCallConnection(callConnectionId)
// .getCallMedia()
// .startTranscription();
전사 스트림 수신
전사가 시작되면 websocket은 전사 메타데이터 페이로드를 첫 번째 패킷으로 받습니다. 이 페이로드는 구성에 대한 호출 메타데이터 및 로캘을 전달합니다.
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
전사 데이터 수신
메타데이터 후에 웹 소켓이 수신하는 다음 패킷은 전사된 오디오에 대한 TranscriptionData가 됩니다.
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "Testing transcription.",
"format": "display",
"confidence": 0.695223331451416,
"offset": 2516998782481234400,
"words": [
{
"text": "testing",
"offset": 2516998782481234400
},
{
"text": "testing",
"offset": 2516998782481234400
}
],
"participantRawID": "8:acs:",
"resultStatus": "Final"
}
}
웹 소켓 서버에서 전사 스트림 처리
package com.example;
import org.glassfish.tyrus.server.Server;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class App {
public static void main(String[] args) {
Server server = new Server("localhost", 8081, "/ws", null, WebSocketServer.class);
try {
server.start();
System.out.println("Web socket running on port 8081...");
System.out.println("wss://localhost:8081/ws/server");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
reader.readLine();
} catch (Exception e) {
e.printStackTrace();
} finally {
server.stop();
}
}
}
websocket 처리기에 대한 코드 업데이트
package com.example;
import javax.websocket.OnMessage;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import com.azure.communication.callautomation.models.streaming.StreamingData;
import com.azure.communication.callautomation.models.streaming.StreamingDataParser;
import com.azure.communication.callautomation.models.streaming.media.AudioData;
import com.azure.communication.callautomation.models.streaming.media.AudioMetadata;
import com.azure.communication.callautomation.models.streaming.transcription.TranscriptionData;
import com.azure.communication.callautomation.models.streaming.transcription.TranscriptionMetadata;
import com.azure.communication.callautomation.models.streaming.transcription.Word;
@ServerEndpoint("/server")
public class WebSocketServer {
@OnMessage
public void onMessage(String message, Session session) {
StreamingData data = StreamingDataParser.parse(message);
if (data instanceof AudioMetadata) {
AudioMetadata audioMetaData = (AudioMetadata) data;
System.out.println("----------------------------------------------------------------");
System.out.println("SUBSCRIPTION ID: --> " + audioMetaData.getMediaSubscriptionId());
System.out.println("ENCODING: --> " + audioMetaData.getEncoding());
System.out.println("SAMPLE RATE: --> " + audioMetaData.getSampleRate());
System.out.println("CHANNELS: --> " + audioMetaData.getChannels());
System.out.println("LENGTH: --> " + audioMetaData.getLength());
System.out.println("----------------------------------------------------------------");
}
if (data instanceof AudioData) {
AudioData audioData = (AudioData) data;
System.out.println("----------------------------------------------------------------");
System.out.println("DATA: --> " + audioData.getData());
System.out.println("TIMESTAMP: --> " + audioData.getTimestamp());
System.out.println("IS SILENT: --> " + audioData.isSilent());
System.out.println("----------------------------------------------------------------");
}
if (data instanceof TranscriptionMetadata) {
TranscriptionMetadata transcriptionMetadata = (TranscriptionMetadata) data;
System.out.println("----------------------------------------------------------------");
System.out.println("TRANSCRIPTION SUBSCRIPTION ID: --> " + transcriptionMetadata.getTranscriptionSubscriptionId());
System.out.println("IS SILENT: --> " + transcriptionMetadata.getLocale());
System.out.println("CALL CONNECTION ID: --> " + transcriptionMetadata.getCallConnectionId());
System.out.println("CORRELATION ID: --> " + transcriptionMetadata.getCorrelationId());
System.out.println("----------------------------------------------------------------");
}
if (data instanceof TranscriptionData) {
TranscriptionData transcriptionData = (TranscriptionData) data;
System.out.println("----------------------------------------------------------------");
System.out.println("TEXT: --> " + transcriptionData.getText());
System.out.println("FORMAT: --> " + transcriptionData.getFormat());
System.out.println("CONFIDENCE: --> " + transcriptionData.getConfidence());
System.out.println("OFFSET: --> " + transcriptionData.getOffset());
System.out.println("DURATION: --> " + transcriptionData.getDuration());
System.out.println("RESULT STATUS: --> " + transcriptionData.getResultStatus());
for (Word word : transcriptionData.getWords()) {
System.out.println("Text: --> " + word.getText());
System.out.println("Offset: --> " + word.getOffset());
System.out.println("Duration: --> " + word.getDuration());
}
System.out.println("----------------------------------------------------------------");
}
}
}
전사 업데이트
애플리케이션에서 사용자가 원하는 언어를 선택할 수 있는 경우 해당 언어로 전사를 캡처할 수도 있습니다. 이를 위해 통화 자동화 SDK를 사용하여 전사 로캘을 업데이트할 수 있습니다.
client.getCallConnection(callConnectionId)
.getCallMedia()
.updateTranscription("en-US-NancyNeural");
전사 중지
애플리케이션에서 전사 수신 대기를 중지해야 하는 경우 StopTranscription 요청을 사용하여 통화 자동화 기능에 스크립트 데이터를 웹 소켓으로 보내는 것을 중지할 것을 알릴 수 있습니다.
// Option 1: Stop transcription with options
StopTranscriptionOptions stopTranscriptionOptions = new StopTranscriptionOptions()
.setOperationContext("stopTranscription");
client.getCallConnection(callConnectionId)
.getCallMedia()
.stopTranscriptionWithResponse(stopTranscriptionOptions, Context.NONE);
// Alternative: Stop transcription without options
// client.getCallConnection(callConnectionId)
// .getCallMedia()
// .stopTranscription();
전화하기 및 전사 세부 정보 제공
전사를 바로 시작할지 나중에 시작할지, 전사할 로캘 및 스크립트를 보내는 데 사용할 웹 소켓 연결을 알 수 있도록 ACS용 TranscriptionOptions를 정의합니다.
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);
전사 시작
전사를 시작할 준비가 되면 통화 자동화를 명시적으로 호출하여 통화 전사를 시작할 수 있습니다.
const startTranscriptionOptions = {
locale: "en-AU",
operationContext: "startTranscriptionContext"
};
// Start transcription with options
await callMedia.startTranscription(startTranscriptionOptions);
// Alternative: Start transcription without options
// await callMedia.startTranscription();
전사 스트림 수신
전사가 시작되면 websocket은 전사 메타데이터 페이로드를 첫 번째 패킷으로 받습니다. 이 페이로드는 구성에 대한 호출 메타데이터 및 로캘을 전달합니다.
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
전사 데이터 수신
메타데이터 후에 웹 소켓이 수신하는 다음 패킷은 전사된 오디오에 대한 TranscriptionData가 됩니다.
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "Testing transcription.",
"format": "display",
"confidence": 0.695223331451416,
"offset": 2516998782481234400,
"words": [
{
"text": "testing",
"offset": 2516998782481234400
},
{
"text": "testing",
"offset": 2516998782481234400
}
],
"participantRawID": "8:acs:",
"resultStatus": "Final"
}
}
웹 소켓 서버에서 전사 스트림 처리
import WebSocket from 'ws';
import { streamingData } from '@azure/communication-call-automation/src/util/streamingDataParser';
const wss = new WebSocket.Server({ port: 8081 });
wss.on('connection', (ws) => {
console.log('Client connected');
ws.on('message', (packetData) => {
const decoder = new TextDecoder();
const stringJson = decoder.decode(packetData);
console.log("STRING JSON => " + stringJson);
const response = streamingData(packetData);
if ('locale' in response) {
console.log("Transcription Metadata");
console.log(response.callConnectionId);
console.log(response.correlationId);
console.log(response.locale);
console.log(response.subscriptionId);
}
if ('text' in response) {
console.log("Transcription Data");
console.log(response.text);
console.log(response.format);
console.log(response.confidence);
console.log(response.offset);
console.log(response.duration);
console.log(response.resultStatus);
if ('phoneNumber' in response.participant) {
console.log(response.participant.phoneNumber);
}
response.words.forEach((word) => {
console.log(word.text);
console.log(word.duration);
console.log(word.offset);
});
}
});
ws.on('close', () => {
console.log('Client disconnected');
});
});
console.log('WebSocket server running on port 8081');
전사 업데이트
애플리케이션에서 사용자가 원하는 언어를 선택할 수 있는 경우 해당 언어로 전사를 캡처할 수도 있습니다. 이를 위해 통화 자동화 SDK를 사용하여 전사 로캘을 업데이트할 수 있습니다.
await callMedia.updateTranscription("en-US-NancyNeural");
전사 중지
애플리케이션에서 전사 수신 대기를 중지해야 하는 경우 StopTranscription 요청을 사용하여 통화 자동화 기능에 스크립트 데이터를 웹 소켓으로 보내는 것을 중지할 것을 알릴 수 있습니다.
const stopTranscriptionOptions = {
operationContext: "stopTranscriptionContext"
};
// Stop transcription with options
await callMedia.stopTranscription(stopTranscriptionOptions);
// Alternative: Stop transcription without options
// await callMedia.stopTranscription();
전화하기 및 전사 세부 정보 제공
전사를 바로 시작할지 나중에 시작할지, 전사할 로캘 및 스크립트를 보내는 데 사용할 웹 소켓 연결을 알 수 있도록 ACS용 TranscriptionOptions를 정의합니다.
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
)
전사 시작
전사를 시작할 준비가 되면 통화 자동화를 명시적으로 호출하여 통화 전사를 시작할 수 있습니다.
# Start transcription without options
call_connection_client.start_transcription()
# Option 1: Start transcription with locale and operation context
# call_connection_client.start_transcription(locale="en-AU", operation_context="startTranscriptionContext")
# Option 2: Start transcription with operation context
# call_connection_client.start_transcription(operation_context="startTranscriptionContext")
전사 스트림 수신
전사가 시작되면 websocket은 전사 메타데이터 페이로드를 첫 번째 패킷으로 받습니다. 이 페이로드는 구성에 대한 호출 메타데이터 및 로캘을 전달합니다.
{
"kind": "TranscriptionMetadata",
"transcriptionMetadata": {
"subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
"locale": "en-us",
"callConnectionId": "65c57654=f12c-4975-92a4-21668e61dd98",
"correlationId": "65c57654=f12c-4975-92a4-21668e61dd98"
}
}
전사 데이터 수신
메타데이터 후에 websocket이 수신하는 다음 패킷은 전사된 오디오에 대한 TranscriptionData가 됩니다.
{
"kind": "TranscriptionData",
"transcriptionData": {
"text": "Testing transcription.",
"format": "display",
"confidence": 0.695223331451416,
"offset": 2516998782481234400,
"words": [
{
"text": "testing",
"offset": 2516998782481234400
},
{
"text": "testing",
"offset": 2516998782481234400
}
],
"participantRawID": "8:acs:",
"resultStatus": "Final"
}
}
웹 소켓 서버에서 전사 스트림 처리
import asyncio
import json
import websockets
from azure.communication.callautomation._shared.models import identifier_from_raw_id
async def handle_client(websocket, path):
print("Client connected")
try:
async for message in websocket:
json_object = json.loads(message)
kind = json_object['kind']
if kind == 'TranscriptionMetadata':
print("Transcription metadata")
print("-------------------------")
print("Subscription ID:", json_object['transcriptionMetadata']['subscriptionId'])
print("Locale:", json_object['transcriptionMetadata']['locale'])
print("Call Connection ID:", json_object['transcriptionMetadata']['callConnectionId'])
print("Correlation ID:", json_object['transcriptionMetadata']['correlationId'])
if kind == 'TranscriptionData':
participant = identifier_from_raw_id(json_object['transcriptionData']['participantRawID'])
word_data_list = json_object['transcriptionData']['words']
print("Transcription data")
print("-------------------------")
print("Text:", json_object['transcriptionData']['text'])
print("Format:", json_object['transcriptionData']['format'])
print("Confidence:", json_object['transcriptionData']['confidence'])
print("Offset:", json_object['transcriptionData']['offset'])
print("Duration:", json_object['transcriptionData']['duration'])
print("Participant:", participant.raw_id)
print("Result Status:", json_object['transcriptionData']['resultStatus'])
for word in word_data_list:
print("Word:", word['text'])
print("Offset:", word['offset'])
print("Duration:", word['duration'])
except websockets.exceptions.ConnectionClosedOK:
print("Client disconnected")
except websockets.exceptions.ConnectionClosedError as e:
print("Connection closed with error: %s", e)
except Exception as e:
print("Unexpected error: %s", e)
start_server = websockets.serve(handle_client, "localhost", 8081)
print('WebSocket server running on port 8081')
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
전사 업데이트
애플리케이션에서 사용자가 원하는 언어를 선택할 수 있는 경우 해당 언어로 전사를 캡처할 수도 있습니다. 이를 위해 통화 자동화 SDK를 사용하여 전사 로캘을 업데이트할 수 있습니다.
await call_connection_client.update_transcription(locale="en-US-NancyNeural")
전사 중지
애플리케이션에서 전사 수신 대기를 중지해야 하는 경우 StopTranscription 요청을 사용하여 통화 자동화 기능에 스크립트 데이터를 웹 소켓으로 보내는 것을 중지할 것을 알릴 수 있습니다.
# Stop transcription without options
call_connection_client.stop_transcription()
# Alternative: Stop transcription with operation context
# call_connection_client.stop_transcription(operation_context="stopTranscriptionContext")
이벤트 코드
이벤트 | 코드 | SubCode | 메시지 |
---|---|---|---|
TranscriptionStarted | 200 | 0 | 작업이 완료되었습니다. |
TranscriptionStopped | 200 | 0 | 작업이 완료되었습니다. |
TranscriptionUpdated | 200 | 0 | 작업이 완료되었습니다. |
TranscriptionFailed | 400 | 8581 | 작업이 실패했습니다. StreamUrl이 올바르지 않습니다. |
TrasncriptionFailed | 400 | 8565 | Cognitive Services에 대한 금지된 요청으로 인해 작업이 실패했습니다. 입력 매개 변수를 확인하세요. |
TranscriptionFailed | 400 | 8565 | Cognitive Services에 대한 요청이 시간 초과되어 작업이 실패했습니다. 나중에 다시 시도하거나 서비스와 관련된 문제를 확인하세요. |
TranscriptionFailed | 400 | 8605 | 전사에 대한 사용자 지정 음성 인식 모델은 지원되지 않습니다. |
TranscriptionFailed | 400 | 8523 | 요청이 잘못되었습니다. 로캘이 없습니다. |
TranscriptionFailed | 400 | 8523 | 요청이 잘못되었습니다. 지역 정보가 포함된 로캘만 지원됩니다. |
TranscriptionFailed | 405 | 8520 | 현재, 전사 기능은 지원되지 않습니다. |
TranscriptionFailed | 405 | 8520 | Connect 인터페이스를 사용하여 만든 연결에는 UpdateTranscription이 지원되지 않습니다. |
TranscriptionFailed | 400 | 8528 | 작업이 잘못되었습니다. 통화가 이미 종료되었습니다. |
TranscriptionFailed | 405 | 8520 | 현재, 업데이트 전사 기능은 지원되지 않습니다. |
TranscriptionFailed | 405 | 8522 | 통화 설정 중에 전사 URL이 설정되지 않은 경우 요청이 허용되지 않습니다. |
TranscriptionFailed | 405 | 8522 | 통화 설정 중에 Cognitive Service 구성이 설정되지 않은 경우 요청이 허용되지 않습니다. |
TranscriptionFailed | 400 | 8501 | 통화가 설정된 상태가 아닌 경우 작업이 올바르지 않습니다. |
TranscriptionFailed | 401 | 8565 | Cognitive Services 인증 오류로 인해 작업이 실패했습니다. 권한 부여 입력이 올바른지 확인합니다. |
TranscriptionFailed | 403 | 8565 | Cognitive Services에 대한 금지된 요청으로 인해 작업이 실패했습니다. 구독 상태를 확인하고 활성 상태인지 알아봅니다. |
TranscriptionFailed | 429 | 8565 | 작업이 실패했습니다. 요청이 Cognitive Services 구독에 대해 허용되는 동시 요청 수를 초과했습니다. |
TranscriptionFailed | 500 | 8578 | 작업이 실패했습니다. WebSocket 연결을 설정할 수 없습니다. |
TranscriptionFailed | 500 | 8580 | 작업이 실패했습니다. 전사 서비스가 종료되었습니다. |
TranscriptionFailed | 500 | 8579 | 작업이 실패했습니다. 전사가 취소되었습니다. |
TranscriptionFailed | 500 | 9999 | 알 수 없는 내부 서버 오류입니다. |
알려진 문제
- 클라이언트 SDK를 사용하는 ACS 사용자와의 1:1 통화에서 startTranscription = True는 현재 지원되지 않습니다.