본문 바로가기
IoT 디바이스 활용/Raspberry Pi

Raspberry Pi - 카카오 음성합성, 음성인식

by cooluk 2020. 10. 19.

카카오 음성합성, 음성인식

카카오 음성 API

  • 음성 인식(뉴톤)
    • Speech-to-Text(STT): 음성을 텍스트로 변환
  • 음성 합성(뉴톤톡)
    • Text-to-Speech(TTS): 텍스트를 음성으로 변환
  • 무료 가격 정책
    • 음성 인식 5,400초(90분)
    • 음성 합성 20,000자

카카오 개발자 등록


애플리케이션 추가

  • 내 애플리케이션 > 애플리케이션 추가하기

image-20200929163340688

REST API 키 얻기

image-20200929170850353

음성 API 활성화

image-20200929164143687



음성 합성

음성 합성 요청 xml

  • <speak> 루트

    • <voice>

      • 음성 합성할 텍스트 지정

      • name 속성: 보이스 선택(성별, 음색)

        MAN_READ_CALM

        WOMAN_READ_CALM

        MAN_DIALOG_BRIGHT

        WOMAN_DIALOG_BRIGHT

      • 텍스트는 반드시 UTF-8 인코딩이어야 함

  • 예제

<speak>
    <voice name="WOMAN_READ_CALM"> 지금은 여성 차분한 낭독체입니다.</voice>
    <voice name="MAN_READ_CALM"> 지금은 남성 차분한 낭독체입니다.</voice>
    <voice name="WOMAN_DIALOG_BRIGHT"> 안녕하세요. 여성 밝은 대화체예요.</voice>
    <voice name="MAN_DIALOG_BRIGHT">안녕하세요. 남성 밝은 대화체예요.</voice>
</speak>

새 디렉토리 > 가상환경 설정 > 활성화 > pip install requests


kakao_synthesize.py

> pip install pydub

> conda install -c anaconda pyaudio

https://www.gyan.dev/ffmpeg/builds/ > release full 다운로드

환경변수 경로 설정

import requests
import io
from pydub import AudioSegment
from pydub.playback import play

URL = "https://kakaoi-newtone-openapi.kakao.com/v1/synthesize"
HEADERS = {
    "Content-Type" : "application/xml",
    "Authorization" : "KakaoAK 2d7bbeaca71e61a89bef469ece9f01bd"
}
DATA = """
<speak>
    그는 그렇게 말했습니다.
    <voice name="MAN_DIALOG_BRIGHT">잘 지냈어? 나도 잘 지냈어.</voice>
    <voice name="WOMAN_DIALOG_BRIGH">금요일이 좋아요.</voice>
</speak>
"""
res = requests.post(URL, headers = HEADERS, data = DATA.encode('utf-8'))

# 음성 합성 결과를 파일로 저장하기
with open("result.mp3", "wb") as f:
  f.write(res.content)

# 바로 재생하기
# https://ffmpeg.zeranoe.com/builds/
# 환경 변수에 경로 지정

sound = io.BytesIO(res.content)
song = AudioSegment.from_mp3(sound)

# 파일에서 재생하기
# song = AudioSegment.from_mp3("./result.mp3")
play(song)

result.mp3 파일 생성, 재생



음성 인식

음성 인식 오디오 포맷

  • Mono Channel
  • 16000 Hz
  • 16bit depth
  • RAW PCM 포맷

kakao_dictation.py

import requests
import json
kakao_speech_url = "https://kakaoi-newtone-openapi.kakao.com/v1/recognize"

rest_api_key = '2d7bbeaca71e61a89bef469ece9f01bd'

headers = {
    "Content-Type": "application/octet-stream",
    "X-DSS-Service": "DICTATION",
    "Authorization": "KakaoAK " + rest_api_key,
}
with open('heykakao.wav', 'rb') as fp:
    audio = fp.read()

res = requests.post(kakao_speech_url, headers=headers, data=audio)

print(res.text)

------newtone7tIbXkDoBbheagfG
Content-Type: application/json; charset=UTF-8

{"type":"beginPointDetection","value":"BPD"}
------newtone7tIbXkDoBbheagfG
Content-Type: application/json; charset=UTF-8

{"type":"partialResult","value":"he"}
------newtone7tIbXkDoBbheagfG
Content-Type: application/json; charset=UTF-8

{"type":"partialResult","value":"헤이"}
------newtone7tIbXkDoBbheagfG
Content-Type: application/json; charset=UTF-8

{"type":"partialResult","value":"헤이 카카오"}
------newtone7tIbXkDoBbheagfG
Content-Type: application/json; charset=UTF-8

{"type":"endPointDetection","value":"EPD"}
------newtone7tIbXkDoBbheagfG
Content-Type: application/json; charset=UTF-8
Speech-Length: 2

{"type":"finalResult","value":"헤이 카카오","nBest":[{"value":"헤이 카카오","score":98},{"value":"헤이 카카오야","score":0}]}
------newtone7tIbXkDoBbheagfG--



응답 해석(type)

  • beginPointDetection
    • 사용자가 말하기 시작하는 것으로 판단되었을 때
  • partialResult
    • 사용자가 말을 끝내기 전에 음성의 중간 인식 결과가 나왔을 때
    • value에 중간 결과가 담김. 여러 번 발생할 수 있음
  • endPointDetection
    • 사용자가 말하는 것을 끝마친 것으로 판단되었을 때
  • finalResult
    • 사용자가 말한 음성의 최종 인식 결과가 나왔을 때
    • value에 최종 인식 결과가 담김
  • errorCalled
    • 음성 인식이 실패 했을 때
    • value에 에러 메시지가 담김

finalResult 를 추출하는 방법

result_json_string = res.text[
    res.text.index('{"type":"finalResult"'):res.text.rindex('}')+1
]

result = json.loads(result_json_string)
print(result)
print(result['value'])

{'type': 'finalResult', 'value': '헤이 카카오', 'nBest': [{'value': '헤이 카카오', 'score': 98}, {'value': '헤이 카카오야', 'score': 0}]}
헤이 카카오

슬라이싱




dictation 함수화

import requests
import json
kakao_speech_url = "https://kakaoi-newtone-openapi.kakao.com/v1/recognize"

rest_api_key = '2d7bbeaca71e61a89bef469ece9f01bd'

headers = {
    "Content-Type": "application/octet-stream",
    "X-DSS-Service": "DICTATION",
    "Authorization": "KakaoAK " + rest_api_key,
}


def dictation(audio):
    res = requests.post(kakao_speech_url, headers=headers, data=audio)

    result_json_string = res.text[
                         res.text.index('{"type":"finalResult"'):res.text.rindex('}') + 1
                         ]

    result = json.loads(result_json_string)
    return result['value']


if __name__ == "__main__":
    with open('heykakao.wav', 'rb') as fp:
        audio = fp.read()
        result = dictation(audio)
        print(result)

댓글