메인 콘텐츠로 건너뛰기

실시간 음성 인식 라이브러리 Wrp 사용 방법

Wrp 라이브러리를 사용하면 AmiVoice SDK와 유사한 인터페이스로 AmiVoice API의 WebSocket 인터페이스를 사용하여 실시간 애플리케이션을 개발할 수 있습니다. 스트리밍 음성을 전송하고 순차적으로 결과를 받을 수 있습니다. 이 라이브러리는 Java, C#, C++, Python, PHP 등의 언어에서 사용할 수 있습니다.

클라이언트 프로그램 개요

Wrp를 사용한 프로그램은 다음과 같은 흐름을 가집니다.

그림. 명령어와 이벤트

메서드

클라이언트 프로그램은 다음 처리를 순서대로 수행합니다. ()안에는 해당하는 Wrp의 메서드를 표기했습니다.

  1. 연결 (connect)
  2. 음성 인식 요청 (feedDataResume)
  3. 음성 데이터 전송 (feedData)
  4. 음성 데이터 전송 종료 (feedDataPause)
  5. 연결 해제 (disconnect)

이벤트

서버로부터의 발화 감지나 음성 인식 알림 이벤트는 모두 리스너 클래스의 메서드를 통해 얻을 수 있습니다. 다음 5가지 이벤트가 있습니다. ()안에는 Wrp에서 구현해야 할 메서드 이름을 표기했습니다.

  • 발화 시작 감지 시 통지되는 이벤트 utteranceStarted(startTime)
  • 발화 종료 감지 시 통지되는 이벤트 utteranceEnded(endTime)
  • 음성 인식 처리 시작 시 통지되는 이벤트 resultCreated()
  • 인식 중간 결과 통지 이벤트 resultUpdated(result)
  • 인식 결과 통지 이벤트 resultFinalized(result)

인식 결과 통지 이벤트 resultFinalized(result)는 반드시 구현해야 합니다. 기타 필요에 따라 서버로부터의 통지에 대응하는 처리를 구현하세요.

구현 가이드

각 언어별 샘플을 보여주며 단계별로 Wrp 사용 방법을 설명합니다.

아래에 게시된 코드 예제는 모두 GitHub 저장소 advanced-media-inc/amivoice-api-client-library에 공개된 WrpSimpleTester에서 발췌한 것입니다. 전체 코드는 다음 소스 파일을 참조하세요.

실행 방법이나 파일 구성 등에 대한 설명은 클라이언트 라이브러리의 샘플 프로그램 WrpSimpleTester를 참조하세요.

1. 초기화

Wrp 클래스의 인스턴스를 생성합니다.

		// WebSocket 음성 인식 서버 초기화
com.amivoice.wrp.Wrp wrp = com.amivoice.wrp.Wrp.construct();

2. 리스너 클래스 구현

com.amivoice.wrp.WrpListener 클래스를 상속하여 이벤트 핸들러를 구현합니다.

음성 인식 결과는 resultFinalized의 인자 result로 얻을 수 있습니다. 자세한 내용은 음성 인식 결과 형식의 WebSocket 인터페이스를 참조하세요. 또한 인식 결과 텍스트는 UTF-8로 인코딩되어 유니코드 이스케이프됩니다. 결과 텍스트에 대해도 참조하세요.

아래 코드에서는 utteranceStarted, utteranceEnded, resultCreated, resultUpdated, resultFinalized의 각 메서드에서 표준 출력에 로그를 출력하도록 구현되어 있습니다. 이러한 메서드를 구현한 리스너의 인스턴스를 wrp 인스턴스의 wrp.setListener(listener)로 설정합니다. 결과 텍스트의 유니코드 이스케이프를 text_ 메서드로 디코딩하고 있습니다. text_ 메서드는 GitHub에서 전체 코드를 공개하고 있습니다.

public class WrpTester implements com.amivoice.wrp.WrpListener {
public static void main(String[] args) {
// WebSocket 음성 인식 서버 이벤트 리스너 생성
com.amivoice.wrp.WrpListener listener = new WrpTester(verbose);
wrp.setListener(listener);
}

@Override
public void utteranceStarted(int startTime) {
System.out.println("S " + startTime);
}

@Override
public void utteranceEnded(int endTime) {
System.out.println("E " + endTime);
}

@Override
public void resultCreated() {
System.out.println("C");
}

@Override
public void resultUpdated(String result) {
System.out.println("U " + result);
String text = text_(result);
if (text != null) {
System.out.println(" -> " + text);
}
}

@Override
public void resultFinalized(String result) {
System.out.println("F " + result);
String text = text_(result);
if (text != null) {
System.out.println(" -> " + text);
}
}

3. 연결 (connect)

음성 인식 서버에 연결합니다.

이 메서드를 호출하기 전에 반드시 설정해야 하는 파라미터는 다음과 같습니다.

  • serverURL ... WebSocket 인터페이스의 엔드포인트

다음 URL을 지정하십시오.

wss://acp-api.amivoice.com/v1/     (로그 저장 있음)
wss://acp-api.amivoice.com/v1/nolog/ (로그 저장 없음)

다음 파라미터를 설정하여 동작을 조정할 수 있습니다.

  • proxyServerName ... 클라이언트 프로그램이 프록시 서버를 통해 연결하는 경우 지정
  • connectTimeout ... 서버와의 연결 타임아웃. 단위는 밀리초입니다.
  • receiveTimeout ... 서버로부터의 데이터 수신 타임아웃. 단위는 밀리초입니다.

서버 측 타임아웃에 대해서는 제한 사항을 참조하십시오.

다음 코드는 음성 인식 서버에 연결합니다. verbosefalse인 경우 오류 메시지를 표시하지 않습니다.

		wrp.setServerURL(serverURL);
wrp.setProxyServerName(proxyServerName);
wrp.setConnectTimeout(connectTimeout);
wrp.setReceiveTimeout(receiveTimeout);

// WebSocket 음성 인식 서버에 연결
if (!wrp.connect()) {
if (!verbose) {
System.out.println(wrp.getLastMessage());
}
System.out.println("WebSocket 音声認識サーバ " + serverURL + " への接続に失敗しました。");
return;
}

4. 음성 인식 요청 (feedDataResume)

음성 인식 요청을 전송합니다. 이 메서드는 요청 파라미터에 지정한 적절한 음성 인식 서버에 연결하거나 단어 등록 준비가 완료될 때까지 차단됩니다. 실패한 경우 오류를 반환합니다. 자세한 내용은 s 명령어 응답 패킷의 오류 메시지를 참조하십시오.

이 메서드를 호출하기 전에 반드시 설정해야 하는 파라미터는 다음과 같습니다.

  • codec ... 음성 형식 지정. 지원되는 음성 형식은 음성 인식 결과 형식을 참조하십시오.
  • grammarFileNames ... 연결 엔진 이름. 지원되는 엔진은 음성 인식 엔진을 참조하십시오.
  • authorization ... 인증 정보. 마이페이지에 기재된 APPKEY를 지정하십시오. 또는 원타임 APPKEY를 지정하십시오.

다음 파라미터를 설정하여 동작을 조정할 수 있습니다.

  • profileId
  • profileWords
  • keepFillerToken
  • segmenterProperties
  • resultUpdatedInterval

자세한 내용은 파라미터 상세를 참조하십시오.

경고

데드락이 발생할 수 있으므로 feedDataResume 메서드를 이벤트 통지를 받기 위한 리스너 클래스의 메서드인 resultFinalized 등에서 호출하지 마십시오.

다음 코드는 위의 파라미터를 기반으로 음성 인식 요청을 서버로 전송하고, 오류가 발생한 경우 표준 출력에 메시지를 표시합니다. verbosefalse인 경우에는 오류 메시지를 표시하지 않습니다.

        wrp.setCodec(codec);
wrp.setGrammarFileNames(grammarFileNames);
wrp.setAuthorization(authorization);

// WebSocket 음성 인식 서버로의 음성 데이터 전송 시작
if (!wrp.feedDataResume()) {
if (!verbose) {
System.out.println(wrp.getLastMessage());
}
System.out.println("WebSocket 音声認識サーバへの音声データの送信の開始に失敗しました。");
break;
}

5. 음성 데이터 전송 (feedData)

다음으로 음성 데이터를 전송합니다. 이 메소드는 블록되지 않습니다. 서버 측에서 어떤 오류가 발생한 경우, 다음 메소드 호출 시 오류를 반환합니다. 오류 내용은 p 명령어 응답 패킷의 오류 메시지를 참조하십시오. 음성 데이터 전송을 시작하면 서버 측 처리에 따라 리스너 클래스의 메소드가 호출됩니다.

정보
  • feedDataResume에서 지정한 codec에 맞는 음성 데이터를 전송하십시오. 포맷이 다르더라도 오류가 발생하지는 않지만, 응답에 매우 시간이 오래 걸리거나 인식 결과가 올바르게 얻어지지 않습니다.
  • 전송한 음성 데이터에서 발화를 감지하지 못한 경우, 리스너 클래스의 메소드는 호출되지 않습니다. 다음과 같은 이유가 있을 수 있으므로 확인하십시오.
    • 음성이 전혀 포함되어 있지 않거나 음량이 매우 작음. 녹음 시스템이 음소거되어 있지 않은지, 음량 설정이 적절한지 등을 확인하십시오.
    • 음성 포맷과 음성 데이터가 일치하지 않음. 음성 포맷을 확인하십시오.
노트
  • 1회의 feedData 메소드로 전송할 수 있는 음성 데이터의 크기는 최대 16MB입니다. 데이터 크기가 그 이상이면 분할하십시오.
  • 음성 데이터의 분할은 임의의 위치에서 수행해도 문제없습니다. wav의 청크나 mp3, flac, opus 등의 프레임 경계를 의식할 필요는 없습니다.
  • 중간에 전송하는 데이터의 포맷을 변경할 수 없습니다. 음성 포맷을 변경하려면 e 명령어로 종료하고 s부터 새로운 음성 인식 요청을 하십시오. 헤더가 있는 음성 파일의 경우도 마찬가지로 파일마다 e 명령어로 종료하고 s부터 새로운 음성 인식 요청을 하십시오.

다음 코드는 audioFileName에 지정된 음성 데이터 파일에서 음성 데이터를 읽어 WebSocket 음성 인식 서버로 전송하는 처리입니다. sleepTime-1인 경우 인식 결과 정보 대기 수가 1 이하가 될 때까지 대기합니다. verbosefalse인 경우 오류 메시지를 표시하지 않습니다.

					try (FileInputStream audioStream = new FileInputStream(audioFileName)) {
// 오디오 데이터 파일에서 오디오 데이터 읽기
byte[] audioData = new byte[4096];
int audioDataReadBytes = audioStream.read(audioData, 0, audioData.length);
while (audioDataReadBytes > 0) {
// 슬립 시간이 계산되었는지 확인
if (sleepTime >= 0) {
// 슬립 시간이 계산된 경우...
// 짧은 시간 동안 슬립
wrp.sleep(sleepTime);
} else {
// 슬립 시간이 계산되지 않은 경우...
// 짧은 시간 동안 슬립
wrp.sleep(1);

// 인식 결과 정보 대기 수가 1 이하가 될 때까지 슬립
int maxSleepTime = 50000;
while (wrp.getWaitingResults() > 1 && maxSleepTime > 0) {
wrp.sleep(100);
maxSleepTime -= 100;
}
}

// WebSocket 음성 인식 서버로 오디오 데이터 전송
if (!wrp.feedData(audioData, 0, audioDataReadBytes)) {
if (!verbose) {
System.out.println(wrp.getLastMessage());
}
System.out.println("WebSocket 音声認識サーバへの音声データの送信に失敗しました。");
break;
}

// 오디오 데이터 파일에서 오디오 데이터 읽기
audioDataReadBytes = audioStream.read(audioData, 0, audioData.length);
}
} catch (IOException e) {
System.out.println("音声データファイル " + audioFileName + " の読み込みに失敗しました。");
}

6. 오디오 데이터 전송 종료 (feedDataPause)

오디오 데이터 전송이 완료되면 이 메서드를 호출하십시오. 이 메서드는 음성 인식 처리가 완료될 때까지 블록됩니다. 어떤 이유로 요청이 실패할 수 있습니다. 자세한 내용은 e 명령 응답 패킷의 오류 메시지를 참조하십시오.

경고

데드락을 방지하기 위해 feedDataPause 메서드를 이벤트 알림을 받기 위한 리스너 클래스의 메서드, 예를 들어 resultFinalized 등에서 호출하지 마십시오.

정보

스트리밍이 아닌 한 번에 오디오 데이터를 전송한 경우 음성 인식 처리에 시간이 걸리므로 결과가 반환될 때까지 시간이 걸립니다. 전송된 오디오의 0.5~1.5배 정도의 시간을 예상하십시오.

다음 코드는 모든 오디오 데이터가 전송되었음을 서버에 알리고 결과가 반환될 때까지 블록됩니다. verbosefalse인 경우 오류 메시지를 표시하지 않습니다.

					// WebSocket 음성 인식 서버로 오디오 데이터 전송 완료
if (!wrp.feedDataPause()) {
if (!verbose) {
System.out.println(wrp.getLastMessage());
}
System.out.println("WebSocket 音声認識サーバへの音声データの送信の完了に失敗しました。");
break;
}

7. 연결 해제 (disconnect)

마지막으로 음성 인식 서버와의 연결을 해제합니다.

			// WebSocket 음성 인식 서버와의 연결 해제
wrp.disconnect();

클라이언트 프로그램의 상태 전이

클라이언트 프로그램은 다음과 같은 상태 전이를 수행합니다.

기타 문서