###実現したいこと
pythonでの会話AIの作成中に起こった問題の解決
###発生している問題・エラーメッセージ
https://api.repl-ai.jp/v1/registration
https://api.repl-ai.jp/v1/dialogue
こんにちは
https://api.repl-ai.jp/v1/dialogue
ひどい
lestening...
speaking...こんにちは、今日の調子はどうですか?。
lestening...
listened:7272ms
voice data size=97325
recognizing...
results: {"result":[]}
{"result":[{"alternative":[{"transcript":"こんにちは 今日はあまり調子は良くないです","confidence":0.99055183},{"transcript":"今日は 今日はあまり調子は良くないです"},{"transcript":"こんにちは 今日はあまり調子が良くないです"},{"transcript":"今日は 今日はあまり調子が良くないです"},{"transcript":"こんにちは 今日はあまり調子はよくないです"}],"final":true}],"result_index":0}
recognized:10573ms
speaking...
WARNING: JPCommonLabel_make() in jcomon_label.c: No phoneme.
Error: waveform cannot be synthesized.
https://api.repl-ai.jp/v1/dialogue
replied:1772ms
speaking...こんにちは
###以下がエラーです
Traceback (most recent call last):
File "/home/pi/ai/ai/2月1日.py", line 172, in <module>
speak(reply)
File "/home/pi/ai/ai/2月1日.py", line 117, in speak
print(commands.getoutput(cmdline))
File "/usr/lib/python2.7/commands.py", line 50, in getoutput
return getstatusoutput(cmd)[1]
File "/usr/lib/python2.7/commands.py", line 59, in getstatusoutput
pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r')
UnicodeEncodeError: 'ascii' codec can't encode characters in position 7-11: ordinal not in range(128) '
###作成したプログラム
'''python
#!/usr/bin/env python
-- coding: utf-8 --
import requests
import json
import os
import commands
import time
GOOGLE_APIKEY = 'AIzaSyCcd2JFQt_1D6cBgFOHcJv53Wn1QmfM-_4'
DOCOMO_APIKEY = '6b57447369556f3432332e5a73453553776d64624d7a4a447235314530477767476b393975313748765234'
LISTEN_SECONDS = 7
VOICE_IN_PATH = '/home/pi/tmp.flac'
VOICE_OUT_PATH = '/home/pi/tmp.wav'
録音
def listen(seconds):
print 'lestening...'
cmdline = 'AUDIODEV=hw:1 rec -c 1 -r 17000 ' + VOICE_IN_PATH +
' trim 0 ' + str(seconds)
os.system(cmdline)
return os.path.getsize(VOICE_IN_PATH)
音声認識
def recognize():
print('recognizing...')
f = open(VOICE_IN_PATH, 'rb')
voice = f.read()
f.close()
url = 'https://www.google.com/speech-api/v2/recognize?xjerr=1&client=chromium&'\ 'lang=ja-JP&maxresults=10&pfilter=0&xjerr=1&key=' + GOOGLE_APIKEY hds = {'Content-type': 'audio/x-flac; rate=17000'} try: reply = requests.post(url, data=voice, headers=hds).text except IOError: return '#CONN_ERR' except: return '#ERROR' print 'results:', reply objs = reply.split(os.linesep) for obj in objs: if not obj: continue alternatives = json.loads(obj)['result'] if len(alternatives) == 0: continue return alternatives[0]['alternative'][0]['transcript'] return ""
対話
import requests
import time
REPLAI_API_KEY = "tIbYtdhqLp4GFArA93Np791lpiBM1f7M6pUAns61"
REPLAI_API_BOTID = "sample"
REPLAI_API_URLBASE = "https://api.repl-ai.jp/v1/"
REPLAI_API_TOPICID = "docomoapi"
def request_replai_api(url, params):
print(url)
headers = {}
headers['content-type'] = 'application/json'
headers['x-api-key'] = REPLAI_API_KEY
r = requests.post(url, headers=headers, json=params) return r.json()
def registration():
url = requests.compat.urljoin(REPLAI_API_URLBASE, 'registration')
params = {}
params['botId'] = REPLAI_API_BOTID
return request_replai_api(url, params)['appUserId']
初回の発話(initialize=True)時は tipic_id を設定する
def dialogue(app_id, message, initialize=False, topic_id=None):
url = requests.compat.urljoin(REPLAI_API_URLBASE, 'dialogue')
params = {}
params['appUserId'] = app_id
params['botId'] = REPLAI_API_BOTID
params['voiceText'] = message
if initialize and topic_id:
params['initTalkingFlag'] = True
params['initTopicId'] = topic_id
else:
params['initTalkingFlag'] = False
return request_replai_api(url, params)['systemText']['utterance']
動作確認
app_id = registration()
first_time = True
while True:
if first_time:
ret = dialogue(app_id, 'こんにちは', True, REPLAI_API_TOPICID)
print(ret)
first_time = False
else:
ret = dialogue(app_id, 'さようなら')
print(ret)
break
time.sleep(10)
読み上げ
def speak(message):
print('speaking...' + message)
JDIC_DIR='/var/lib/mecab/dic/open-jtalk/naist-jdic/'
VOICE_DATA='/home/pi/ai/ai/mei/mei_happy.htsvoice'
cmdline = 'echo ' + message + ' | open_jtalk -x ' + JDIC_DIR + \ ' -m ' + VOICE_DATA + ' -ow ' + VOICE_OUT_PATH + \ ' -s 17000 -p 100 -a 0.03' print(commands.getoutput(cmdline)) os.system('play ' + VOICE_OUT_PATH)
def current_milli_time():
return int(round(time.time() * 1000))
if name == 'main':
#first time record will be failed.
listen(1)
speak('こんにちは、今日の調子はどうですか?。')
no_word = 0
wifi_err = 0
try:
while True:
# 録音
t0 = current_milli_time()
size = listen(LISTEN_SECONDS)
t = current_milli_time() - t0
if (t < 2000):
print 'USB microphone not available'
speak('マイクロホンを確認してください。')
time.sleep(10)
continue
print 'listened:' + str(t) + 'ms'
print 'voice data size=' + str(size)
# 音声認識 t0 = current_milli_time() message = recognize().encode('utf-8') print 'recognized:' + str(current_milli_time() - t0) + 'ms' if (message == '#CONN_ERR'): print 'internet not available' speak('イーターネット接続を確認してください。') time.sleep(10) continue elif (message == '#ERROR'): print 'voice recognize failed' speak('音声認識サービスを確認してください。') time.sleep(10) continue # 対話 speak('') t0 = current_milli_time() reply = dialogue(app_id, 'さようなら') print 'replied:' + str(current_milli_time() - t0) + 'ms' if (reply == '#ERROR'): print 'dialogue failed' speak('雑談会話サービスを確認してください。') time.sleep(10) continue # 読み上げ t0 = current_milli_time() speak(reply) print 'talked:' + str(current_milli_time() - t0) + 'ms'
except KeyboardInterrupt:
'''
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。