Начитавшись разных постов о Google Voice и его использовании, решил написать что-то свое. А именно — голосовое управление компьютером. Сразу оговорюсь, что ОС — Windows.
Нам понадобится:
— Python 2.7
— библиотеки:
pyaudio
pycurl
pywin32
+ набор стандартных библиотек
— какой-либо аудиоконвертер поддерживающий flac и wav, а также работу из командной строки, я использовал этот.
Как это работает
Мы записываем аудиофайл, отправляем Google Voice-у, получаем ответ в виде:
{«status»:0,«id»:«5e34348f2887c7a3cc27dc3695ab4575-1»,«hypotheses»:[{«utterance»:«пример»,«confidence»:0.7581704}]},
и далее его обрабатываем, также научим компьютер «разговаривать», с помощью того-же Google Voice.
Начинаем
Для начала нам необходимо подключить все модули, чтобы потом к этому не возвращаться:
import time, pyaudio, wave, os, urllib,urllib2,pycurl,httplib,sys,win32api,win32con,string from ctypes import *
Окей, теперь напишем функцию Talk, которая позволит компьютеру разговаривать с нами.
def Talk(text): def downloadFile(url, fileName): fp = open(fileName, "wb") curl = pycurl.Curl() curl.setopt(pycurl.URL, url) curl.setopt(pycurl.WRITEDATA, fp) curl.perform() curl.close() fp.close() def getGoogleSpeechURL(phrase): googleTranslateURL = "http://translate.google.com/translate_tts?tl=en&" parameters = {'q': phrase} data = urllib.urlencode(parameters) googleTranslateURL = "%s%s" % (googleTranslateURL,data) return googleTranslateURL def speakSpeechFromText(phrase): googleSpeechURL = getGoogleSpeechURL(phrase) downloadFile(googleSpeechURL,"ans.mp3")#файл, полученный с сервера сохраняется под именем ans.mp3 speakSpeechFromText(text) #используем кодеки, чтобы воспроизвести речь winmm = windll.winmm winmm.mciSendStringA('Open "ans.mp3" Type MPEGVideo Alias theMP3',0,0,0) winmm.mciSendStringA('Play theMP3 Wait',0,0,0) winmm.mciSendStringA("Close theMP3","",0,0)
В общем, получаем функцию Talk(text), которая соответственно «говорит» нам text.
Кодеки были единственным решением, которое позволило мне воспроизвести mp3 из Python.
Ах, да, еще Google общается с нами исключительно на английском (и воспринимает только англ.), т.к мне не удалось подружить Python и utf-8.
Запись
Следующий шаг — запись речи, которую будет обрабатывать Google. Смело копипастим:
def Record(): CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 16000 RECORD_SECONDS = 5 WAVE_OUTPUT_FILENAME = "output.wav" p = pyaudio.PyAudio() stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) print("Recording...") frames = [] for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)): data = stream.read(CHUNK) frames.append(data) print("Done recording.") stream.stop_stream() stream.close() p.terminate() wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb') wf.setnchannels(CHANNELS) wf.setsampwidth(p.get_sample_size(FORMAT)) wf.setframerate(RATE) wf.writeframes(b''.join(frames)) wf.close()
Этот код находится на сайте pyaudio и я его оставил практически без изменений.
Но, вот и первая проблема, мы получили файл wav, а Google понимает flac… Непорядок.
Здесь нас выручит конверетер и модуль os:
def Convert(): print "Converting" os.system('C:\Users\Егор\Desktop\Расширение\TotalAudioConverter\AudioConverter.exe C:\Users\Егор\Desktop\Расширение\output.wav C:\Users\Егор\Desktop\Расширение\output.flac') print "Done"
Здесь поясню, мы указываем путь к установленному конвертеру, а затем в качестве параметров передаем сначала входной файл, затем выходной (пути указывать полностью).
Посылаем нашу запись на сервер
def Send(): global ANSWER url = 'https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=en-EN'#Здесь можно выбрать язык flac=open('output.flac',"rb").read() header = {'Content-Type' : 'audio/x-flac; rate=16000'} req = urllib2.Request(url, flac, header) data = urllib2.urlopen(req) a = data.read() ANSWER = eval(a) if ANSWER['status'] == 5: print 'Sorry, I do not understand you.' Talk('Sorry, I do not understand you.') ANSWER = 0 else: ANSWER = ANSWER['hypotheses'][0]['utterance']#Отбираем то что google нам ответил(можно иначе) print ANSWER os.remove('C:\Users\Егор\Desktop\Расширение\output.wav')#Удаляем ненужные записи os.remove('C:\Users\Егор\Desktop\Расширение\output.flac') return ANSWER
Обработка
Получив ответ, мы можем ее использовать. Здесь все зависит исключительно от вашей фантазии.
Просто приведу несколько примеров:
def Processing(): global ANSWER if ANSWER == 0: return 0 elif 'chrome' in ANSWER.lower(): os.system('C:\Users\Егор\AppData\Local\Google\Chrome\Application\chrome.exe')#Запускаем Google Chrome, если он услышал слово chrome) elif 'skype' in ANSWER.lower(): os.system('C:\Users\Егор\Downloads\SkypePortable\SkypePortable.exe')#аналогично elif 'cd rom' in ANSWER.lower() or\ 'cd-rom' in ANSWER.lower() or\ 'open d' in ANSWER.lower() or\ 'dvd' in ANSWER.lower() or\ 'dvd-rom' in ANSWER.lower() or\ 'dvd rom' in ANSWER.lower() or\ 'cdrom' in ANSWER.lower() or\ 'cd - rom' in ANSWER.lower(): winmm = windll.winmm winmm.mciSendStringA("set cdaudio door open", "", 0,0)#Если слышит что- то связанное с dvd то открывает лоток дисковода
Также еще я добавил функцию, которая на указанное время останавливала выполнение программы, но там большой код и я не вижу смысла выкладывать его здесь, т.к польза от него стремится к нолю.
Запускаем
После того, как мы описали эти функции, добавим следующий код:
print 'Hi, what do you want?' Talk('Hi, what do you want?') Record() Convert() print ('Sending...') Send() print 'Done' Processing() while True: ANSWER = None #Talk('Done.') print 'Do you want something else? (Your command\No)' Talk('Do you want something else??') Record() Convert() print 'Sending...' Send() print 'Done' #print ANSWER if ANSWER == 0: continue if ANSWER.lower()== 'no' or\#Если ответили нет, завершаем программу ANSWER.lower()== 'nope' or\ ANSWER.lower()== 'not' or\ ANSWER.lower()== 'nay': break else: Processing() print 'Okay, bye' Talk('Okay, bye')
Готово!
На этом хотелось бы закончить. Я рад, если кому-то помог.
Спасибо за внимание.
ссылка на оригинал статьи http://habrahabr.ru/post/263423/
Добавить комментарий