visit
mkdir TARS
cd TARS
virtualenv venv
. venv/bin/activate
Once you activated venv, we need to install main libraries by following commands:
pip3 install gTTS SpeechRecognition PyAudio pygame
gTTS (Google Text-to-Speech) is a Python library and CLI tool to interface with Google Translate's text-to-speech API. This module helps to convert String text to Spoken text and can be saved as .mp3
Speech Recognition is an important feature in several applications used such as home automation, artificial intelligence, etc. Recognizing speech needs audio input, and SpeechRecognition makes it really simple to retrieve this input. Instead of building scripts from scratch to access microphones and process audio files, SpeechRecognition will have you up and running in just a few minutes.
To access your microphone with SpeechRecognizer, you’ll have to install the PyAudio package
Pygame is a cross-platform set of Python modules designed for writing video games. It includes computer graphics and sound libraries designed to be used with the Python programming language.
Now, let's build voice system of TARS:from gtts import gTTS
import speech_recognition as sr
from pygame import mixer
def talk(audio):
print(audio)
for line in audio.splitlines():
text_to_speech = gTTS(text=audio, lang='en-uk')
text_to_speech.save('audio.mp3')
mixer.init()
mixer.music.load("audio.mp3")
mixer.music.play()
We are passing audio as an argument to make the TARS speak. For instance, talk('Hey I am TARS! How can I help you?') program will loop these lines with the help of splitlines() method. This method is used to split the lines at line boundaries. Check for more. Then, gTTS will handle to convert all these texts to speech. text parameter defines text to be read and lang defines the language (IETF language tag) to read the text in. Once loop finished, save() method writes result to file.
pygame.mixer is a module for loading and playing sounds and must be initialized before using it.
Alright! Now, let's create a function that will listen for commands:def myCommand():
#Initialize the recognizer
r = sr.Recognizer()
with sr.Microphone() as source:
print('TARS is Ready...')
r.pause_threshold = 1
#wait for a second to let the recognizer adjust the
#energy threshold based on the surrounding noise level
r.adjust_for_ambient_noise(source, duration=1)
#listens for the user's input
audio = r.listen(source)
try:
command = r.recognize_google(audio).lower()
print('You said: ' + command + '\n')
#loop back to continue to listen for commands if unrecognizable speech is received
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
command = myCommand();
return command
import random
def tars(command):
errors=[
"I don\'t know what you mean!",
"Excuse me?",
"Can you repeat it please?",
]
if 'Hello' in command:
talk('Hello! I am TARS. How can I help you?')
else:
error = random.choice(errors)
talk(error)
talk('TARS is ready!')
while True:
assistant(myCommand())
from gtts import gTTS
import speech_recognition as sr
from pygame import mixer
import random
def talk(audio):
print(audio)
for line in audio.splitlines():
text_to_speech = gTTS(text=audio, lang='en-uk')
text_to_speech.save('audio.mp3')
mixer.init()
mixer.music.load("audio.mp3")
mixer.music.play()
def myCommand():
#Initialize the recognizer
#The primary purpose of a Recognizer instance is, of course, to recognize speech.
r = sr.Recognizer()
with sr.Microphone() as source:
print('TARS is Ready...')
r.pause_threshold = 2
#wait for a second to let the recognizer adjust the
#energy threshold based on the surrounding noise level
r.adjust_for_ambient_noise(source, duration=1)
#listens for the user's input
audio = r.listen(source)
try:
command = r.recognize_google(audio).lower()
print('You said: ' + command + '\n')
#loop back to continue to listen for commands if unrecognizable speech is received
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
command = myCommand();
return command
def tars(command):
errors=[
"I don't know what you mean",
"Did you mean astronaut?",
"Can you repeat it please?",
]
if 'hello' in command:
talk('Hello! I am TARS. How can I help you?')
else:
error = random.choice(errors)
talk(error)
talk('TARS is ready!')
#loop to continue executing multiple commands
while True:
tars(myCommand())
import re
import webbrowser
if 'open google' in command:
#matching command to check it is available
reg_ex = re.search('open google (.*)', command)
url = '//www.google.com/'
if reg_ex:
subgoogle = reg_ex.group(1)
url = url + 'r/' + subreddit
webbrowser.open(url)
print('Done!')
The re.search() method takes a regular expression pattern and a string and searches for that pattern within the string. If the search is successful, search() returns a match object or None otherwise. Therefore, the search is usually immediately followed by an if-statement to test if the search succeeded
The code reg_ex = re.search('open google (.*)', command) stores the search result in a variable named "reg_ex". Then the if-statement tests the match -- if true the search succeeded and group() is the matching text. Otherwise if the match is false (None to be more specific), then the search did not succeed, and there is no matching text. The 1 in represents the first parenthesized subgroup.
Even you can install Selenium to make search in Google by TARS. To install Selenium run the following command:pip3 install selenium
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
if 'open google and search' in command:
reg_ex = re.search('open google and search (.*)', command)
search_for = command.split("search",1)[1]
url = '//www.google.com/'
if reg_ex:
subgoogle = reg_ex.group(1)
url = url + 'r/' + subgoogle
talk('Okay!')
driver = webdriver.Firefox(executable_path='/path/to/geckodriver') #depends which web browser you are using
driver.get('//www.google.com')
search = driver.find_element_by_name('q') # finds search
search.send_keys(str(search_for)) #sends search keys
search.send_keys(Keys.RETURN) #hits enter
import smtplib
elif 'email' or 'gmail' in command:
talk('What is the subject?')
time.sleep(3)
subject = myCommand()
talk('What should I say?')
time.sleep(3)
message = myCommand()
content = 'Subject: {}\n\n{}'.format(subject, message)
#init gmail SMTP
mail = smtplib.SMTP('smtp.gmail.com', 587)
#identify to server
mail.ehlo()
#encrypt session
mail.starttls()
#login
mail.login('your_gmail', 'your_gmail_password')
#send message
mail.sendmail('FROM', 'TO', content)
#end mail connection
mail.close()
talk('Email sent.')
Note that, in a nutshell, google is not allowing you to log in via smtplib because it has flagged this sort of login as "less secure", so what you have to do is go to this link while you're logged in to your google account, and allow the access.
pip install beautifulsoup4
import bs4
import requests
elif 'wikipedia' in command:
reg_ex = re.search('search in wikipedia (.+)', command)
if reg_ex:
query = command.split()
response = requests.get("//en.wikipedia.org/wiki/" + query[3])
if response is not None:
html = bs4.BeautifulSoup(response.text, 'html.parser')
title = html.select("#firstHeading")[0].text
paragraphs = html.select("p")
for para in paragraphs:
print (para.text)
intro = '\n'.join([ para.text for para in paragraphs[0:5]])
print (intro)
mp3name = 'speech.mp3'
language = 'en'
myobj = gTTS(text=intro, lang=language, slow=False)
myobj.save(mp3name)
mixer.init()
mixer.music.load("speech.mp3")
mixer.music.play()
elif 'stop' in command:
mixer.music.stop()
If you say "search in wikipedia Mars" , TARS will take "Mars" as a keyword to search in Wikipedia. So, If you search something on Wikipedia you will see URL will look like //en.wikipedia.org/wiki/Keyword so we are sending get request with keyword(what to search) to access data. Once request succeed, beautifulsoup will parse content inside Wikipedia. The join() method is a string method and returns a string in which the elements of sequence have been joined by str separator and we are using it to separate paragraphs. You already familiar with gTTS and mixer so I am passing that part.
TARS will display the crawled data on console and start to reading it for you.import urllib.request #used to make requests
import urllib.parse #used to parse values into the url
elif 'youtube' in command:
talk('Ok!')
reg_ex = re.search('youtube (.+)', command)
if reg_ex:
domain = command.split("youtube",1)[1]
query_string = urllib.parse.urlencode({"search_query" : domain})
html_content = urllib.request.urlopen("//www.youtube.com/results?" + query_string)
search_results = re.findall(r'href=\"\/watch\?v=(.{11})', html_content.read().decode()) # finds all links in search result
webbrowser.open("//www.youtube.com/watch?v={}".format(search_results[0]))
pass
Search key must be encoded before parsing into url. If you search something on YouTube you can see after //www.youtube.com/results?" there is a encoded search keys. Once these search keys encoded program can successfully access search results. The expression returns all the non-overlapping matches of patterns in a string as a list of strings.
Each video on youtube has its own 11 characters ID (//www.youtube.com/watch?v=gEPmA3USJdI) and re.findall() will find all matches in decoded. html_content(in search results page).
is used to convert from one encoding scheme, in which argument string is encoded to the desired encoding scheme. This works opposite to the encode. It accepts the encoding of the encoding string to decode it and returns the original string. Finally, it plays first video in search results because usually the first video is nearest one for search keys.
Full Code:from gtts import gTTS
import speech_recognition as sr
import re
import time
import webbrowser
import random
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import smtplib
import requests
from pygame import mixer
import urllib.request
import urllib.parse
import bs4
def talk(audio):
"speaks audio passed as argument"
print(audio)
for line in audio.splitlines():
text_to_speech = gTTS(text=audio, lang='en-uk')
text_to_speech.save('audio.mp3')
mixer.init()
mixer.music.load("audio.mp3")
mixer.music.play()
def myCommand():
"listens for commands"
#Initialize the recognizer
#The primary purpose of a Recognizer instance is, of course, to recognize speech.
r = sr.Recognizer()
with sr.Microphone() as source:
print('TARS is Ready...')
r.pause_threshold = 1
#wait for a second to let the recognizer adjust the
#energy threshold based on the surrounding noise level
r.adjust_for_ambient_noise(source, duration=1)
#listens for the user's input
audio = r.listen(source)
print('analyzing...')
try:
command = r.recognize_google(audio).lower()
print('You said: ' + command + '\n')
time.sleep(2)
#loop back to continue to listen for commands if unrecognizable speech is received
except sr.UnknownValueError:
print('Your last command couldn\'t be heard')
command = myCommand();
return command
def tars(command):
errors=[
"I don't know what you mean",
"Excuse me?",
"Can you repeat it please?",
]
"if statements for executing commands"
# Search on Google
if 'open google and search' in command:
reg_ex = re.search('open google and search (.*)', command)
search_for = command.split("search",1)[1]
print(search_for)
url = '//www.google.com/'
if reg_ex:
subgoogle = reg_ex.group(1)
url = url + 'r/' + subgoogle
talk('Okay!')
driver = webdriver.Firefox(executable_path='/home/coderasha/Desktop/geckodriver')
driver.get('//www.google.com')
search = driver.find_element_by_name('q')
search.send_keys(str(search_for))
search.send_keys(Keys.RETURN) # hit return after you enter search text
#Send Email
elif 'email' in command:
talk('What is the subject?')
time.sleep(3)
subject = myCommand()
talk('What should I say?')
message = myCommand()
content = 'Subject: {}\n\n{}'.format(subject, message)
#init gmail SMTP
mail = smtplib.SMTP('smtp.gmail.com', 587)
#identify to server
mail.ehlo()
#encrypt session
mail.starttls()
#login
mail.login('your_mail', 'your_mail_password')
#send message
mail.sendmail('FROM', 'TO', content)
#end mail connection
mail.close()
talk('Email sent.')
# search in wikipedia (e.g. Can you search in wikipedia apples)
elif 'wikipedia' in command:
reg_ex = re.search('wikipedia (.+)', command)
if reg_ex:
query = command.split("wikipedia",1)[1]
response = requests.get("//en.wikipedia.org/wiki/" + query)
if response is not None:
html = bs4.BeautifulSoup(response.text, 'html.parser')
title = html.select("#firstHeading")[0].text
paragraphs = html.select("p")
for para in paragraphs:
print (para.text)
intro = '\n'.join([ para.text for para in paragraphs[0:3]])
print (intro)
mp3name = 'speech.mp3'
language = 'en'
myobj = gTTS(text=intro, lang=language, slow=False)
myobj.save(mp3name)
mixer.init()
mixer.music.load("speech.mp3")
while mixer.music.play()
elif 'stop' in command:
mixer.music.stop()
# Search videos on Youtube and play (e.g. Search in youtube believer)
elif 'youtube' in command:
talk('Ok!')
reg_ex = re.search('youtube (.+)', command)
if reg_ex:
domain = command.split("youtube",1)[1]
query_string = urllib.parse.urlencode({"search_query" : domain})
html_content = urllib.request.urlopen("//www.youtube.com/results?" + query_string)
search_results = re.findall(r'href=\"\/watch\?v=(.{11})', html_content.read().decode())
#print("//www.youtube.com/watch?v=" + search_results[0])
webbrowser.open("//www.youtube.com/watch?v={}".format(search_results[0]))
pass
elif 'hello' in command:
talk('Hello! I am TARS. How can I help you?')
time.sleep(3)
elif 'who are you' in command:
talk('I am one of four former U.S. Marine Corps tactical robots')
time.sleep(3)
else:
error = random.choice(errors)
talk(error)
time.sleep(3)
talk('TARS activated!')
#loop to continue executing multiple commands
while True:
time.sleep(4)
tars(myCommand())