Голосовое управление компьютером и Python

от автора

Начитавшись разных постов о 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *