Python: Creating your smart speaker ver. 12

Last Updated on January 1, 2022 by shibatau

I’m rewriting now. I have corrected typos and add some codes.

I. What do you learn?

Let’s learn how to create Alexa-like smart speaker according the following posts:

Don’t Buy Alexa! Build Your Own

Python Speech Recognition – a Step-by-Step Guide

ERROR: Command errored out with exit status 1 while installing pyaudio

You can change voices according to the tutorial:

Text-to-speech in Python with pyttsx3

My environments:

macOS Big Sur verson:11.4

Python 3.8.10

II. Speech Recognition

Run the following code in the terminal.

brew install portaudio
brew link portaudio

Create an environment for this project and install libraries on the environment.

pip install pyAudio
pip install SpeechRecognition
 

Run the following code in Python.

import speech_recognition as sr

r = sr.Recognizer()
micph = sr.Microphone()

with micph as source:
    print("You can now speak")
    r.adjust_for_ambient_noise(source)
    audio = r.listen(source)
print("Translating your speech...")
print("You said: " + r.recognize_google(audio))

After the execution, speak over the microphone, “Good morning. Hi, guys. How are you?”, and you can see the texts on the console.

You can now speak
Translating your speech…
You said: good morning hi guys how are you

III. Text to speech
Read out Japanese.
 
!pip install pyttsx3
engine = pyttsx3.init()
engine.say('我が家へようこそ!')
engine.runAndWait()
 
 
Read out English.
 
engine = pyttsx3.init()
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[0].id)
def speak(audio):
engine.say(audio)
engine.runAndWait()
speak("Don't Buy Alexa! Build Your Own Using Python") ## uncomment this to test the function
 

IV. Talk with your smart speaker

Explanation 1. In the former part of the scripts
 
話者の、”name”、”are you single”、”hate”、”love”、”time”のそれぞれのに対応した言葉を返します。
“are you single”には、2文のうちの1つをランダムに返します。
“time”に現在の時間を返すのに、f-Stringsを使っています。上の解説のスクリプトではfが抜けているので加えます。
 

Explanation 2. Play music

指定されたディレクトリにあるファイルをランダムに選んで実行します。

macの場合、解説のスクリプトのos.startfile()の代わりに、先に、subprocessを”import subprocess”して次の末尾のように書きます。

 
The last line in the above image is wrong. It should be:
 
subprocess.call(["open", os.path.join(music_dir, songs[song])]) 
 
Explanation 3. Read out news
 
### news
elif 'news' in query:
        def trndnews(): 
            url = "http://newsapi.org/v2/top-headlines?country=in&apiKey=59ff055b7c754a10a1f8afb4583ef1ab"
            page = requests.get(url).json() 
            article = page["articles"] 
            results = [] 
            for ar in article: 
                results.append(ar["title"]) 
            for i in range(len(results)): 
                print(i + 1, results[i]) 
            speak("here are the top trending news....!!")
            speak("Do yo want me to read!!!")
            reply = command().lower()
            reply = str(reply)
            if reply == "yes":
                results_string = " "
                speak(results_string.join(results))
            else:
                speak('ok!!!!')
                pass
        trndnews()

回答がyesの場合、ニュースを読み上げるコードは次です。speak()のアーギュメントは文字列です。resultsはリストなので、resultsををスペースで分けた文字列に変換します。

results_string = ” “
speak(results_string.join(results))

Explanation 4. Read out Wikipedia

スクリプト

### celebrity
elif 'who the heck is' in query:
query = query.replace('who the heck is',"")
speak(wikipedia.summary(query,2))
 

If you say, “Who the heck is Billie Eilish?”, this is shown in the console and read out aloud.

Explanation 5. Finish talking

Say, “Goodbye”.

Your smart phone says, “Have a nice day!” and finish talking.

2.The scripts I have changed for my use are here:

# !pip install pyttsx3
# !pip install SpeechRecognition
# !pip install wikipedia
# !pip install pyttsx3
import pyttsx3
import speech_recognition as sr
import wikipedia
import pyjokes
import random
import requests
import datetime
import os
import subprocess

engine = pyttsx3.init()
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[0].id)

def speak(audio):
    engine.say(audio)   
    engine.runAndWait()

def command():
    r = sr.Recognizer()
    while True:
        with sr.Microphone() as source:
            print("Alexa: Listening...")
            audio=r.listen(source)
            try:    
                query = r.recognize_google(audio)
                print(f"master:{query}")
                return query
                break
            except:
                print("Try Again")

while True:
    query = command().lower() ## takes user command 
    
    if 'name' in query:
        speak("Hi, my name is misho")
    elif 'are you single' in query:
        answers = ['No, I am too young, you know, father','No, I love spending time thinking about my future and your future']
        speak(random.choice(answers))
    elif 'hate' in query:
        speak("Please give me a time to think about it. What do I hate? I don't know")
    elif 'love' in query:
        speak("I love to chat with you, maybe")
    
    ### time
    elif 'time' in query:
        time = datetime.datetime.now().strftime('%I:%M %p')
        speak(f"It's {time} master")
    
    ### wikipedia
    elif 'who the heck is' in query:
       query = query.replace('who the heck is',"")
       info = wikipedia.summary(query, 2)
       print(info)
       speak(info)
    
    ### joke
    elif 'joke' in query:
        speak(pyjokes.get_joke())
    
    ### news
    elif 'news' in query:
            def trendnews(): 
                url = "http://newsapi.org/v2/top-headlines?country=in&apiKey=59ff055b7c754a10a1f8afb4583ef1ab"
                page = requests.get(url).json() 
                article = page["articles"] 
                results = [] 
                for ar in article: 
                    results.append(ar["title"]) 
                for i in range(len(results)): 
                    print(i + 1, results[i]) 
                speak("here are the top trending news.")
                speak("do you want me to read?")
                reply = command().lower()
                reply = str(reply)
                if reply == "yes":
                    results_string = " "
                    speak(results_string.join(results))
                else:
                    speak('ok!')
                    pass
            trendnews() 

    ### music
    elif 'music' in query:
        music_dir = '/YOURDIRECTORY' # or full path
        songs = os.listdir(music_dir)
        song = random.randint(0,len(songs)-1)
        print(songs[song])  
        speak(f"playing{songs[song]}")
        subprocess.call(["open", os.path.join(music_dir, songs[song])])

    elif "goodbye" in query:
        speak("Have a nice day!")
        break
    else:
        speak("I don't understand what you said")
 

About shibatau

I was born and grown up in Kyoto. I studied western philosophy at the University and specialized in analytic philosophy, especially Ludwig Wittgenstein at the postgraduate school. I'm interested in new technology, especially machine learning and have been learning R language for two years and began to learn Python last summer. Listening toParamore, Sia, Amazarashi and MIyuki Nakajima. Favorite movies I've recently seen: "FREEHELD". Favorite actors and actresses: Anthony Hopkins, Denzel Washington, Ellen Page, Meryl Streep, Mia Wasikowska and Robert DeNiro. Favorite books: Fyodor Mikhailovich Dostoyevsky, "The Karamazov Brothers", Shinran, "Lamentations of Divergences". Favorite phrase: Salvation by Faith. Twitter: @shibatau

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.