Making my Raspberry Pi Tell Me the News

In my previous Raspberry Pi post I just told you quickly how to use your Pi to watch movies in a pinch, today I am going to walk through how I got my Raspberry Pi to speak out the current trending news headlines from reddit.com/r/worldnews.

To begin with I built a small Java application that made use of the freetts text to speech library and a Java wrapper for the Reddit API called jReddit. This worked well but the implementation seemed a bit too heavy for putting on the Pi, I had to make sure to have all the library files and make sure Java behaved itself etc.

For those interested you can see my Java Source file here. Please note it’s rather messy code and makes use of another time library.

So I opted to then recode it using Python since it came on with the Pi (as I am using a Linux based OS). In order to do this I needed to install a few Python modules for use, specifically pyttsx (the text to voice module) and praw (Reddit API module). Installing these was relatively easy using pip, the go to tool for installing Python modules.

Just to make sure you have python installed and to check the version you are running you can attempt to run the following command on your command line:

python --version

You should then see something along the lines of the following on your console output:

Python 2.7.3rc2

That is my version of python on my Raspberry Pi, yours will likely be similar! This isn’t a tutorial on Python programming itself (I know very little about it myself) but it’s worth mentioning there are some big differences between Python 3.x and Python 2.x, so programs written in one do not always work in the other.

Now in order to install modules easily I needed to install a module called pip.For this I found somebody had written a simple python script/program to do it for you. Instructions I found recommended running the following on the command line:

curl https://bitbucket.org/pdubroy/pip/raw/tip/getpip.py | python

This should pipe the contents of that url (it’s a pip installer someone made) into python to execute. Of course I ran into a problem doing this since I forgot to run this as a root user (by placing sudo in front of the command) and then resorted to downloading the script in the following and installing it with another command:

wget https://bitbucket.org/pdubroy/pip/raw/tip/getpip.py
sudo python getpip.py

As far as I know this will do the same thing, it installs pip so you can now easily install other packages/modules. And when I say easily, I mean easily. To install praw and pyttsx all I needed to do was the following:

sudo pip install praw
sudo pip install pyttsx

As easy as installing a Linux program using apt-get!

So after installing them I began my task of first learning Python. Having never coded in it before I found it surprisingly easy to get started in even with it’s strict white space rules. As a language it feels like it takes some of the best bits of C/C++ and JavaScript and rolls them together. I’ve yet to program anything Object Orientated in it yet but from the looks of it it’s easy to pick that up too.

To start with I wanted to test both modules separately. So after starting up an instance of the python interpreter (by running the command python) I typed the following:

import pyttsx
engine = pyttsx.init()
engine.say("Hello World!")
engine.runAndWait()

And got a bunch of errors to do with the ALSA library (that’s for the sound output cable I believe)! I then tried again and it worked through my HDMI lead. It also worked headless from an SSH connection with speakers plugged into the correct socket.

So now I had my Pi talking I needed to make sure I could get it something interesting to say. So I then wrote a simple python program to get the top ten news articles from Reddit based on the examples on praw’s documentation:

import praw
r = praw.Reddit(user_agent="Lyndon's news reader  by /u/LyndonArmitage")

subs = r.get_subreddit("worldnews").get_hot(limit=limit)
headlines = []
for sub in subs:
    print sub.title

This printed out the titles of the headlines to my console. Success!

Now I knew both of them were working I set out to translate my Java code to Python and dumped the Object Oriented aspects of it too simplify the problem. My code looked something like this:

import praw
import pyttsx
__author__ = "Lyndon Armitage"

engine = pyttsx.init()
r = praw.Reddit(user_agent="Lyndon's news reader  by /u/LyndonArmitage")

def get_headlines(limit=10):
    subs = r.get_subreddit("worldnews").get_hot(limit=limit)
    headlines = []
    for sub in subs:
        headlines.append(sub.title)
    return headlines

def speak_headlines(headlines=[]):
    for s in headlines:
        print s
        engine.say(s)
        engine.runAndWait()

titles = get_headlines()
speak_headlines(titles)

Assuming the modules are installed correctly it should also work for you! You might notice it’s pretty similar to both simple tests I made above. That shows how simple it was to make!

What I have done here is created two functions (using the keyword def), one returns a list of headlines from Reddit using praw and the other speaks them aloud using pyttsx. Very simple stuff.

And that’s it! I did create a modified version that will loop indefinitely (a bit like my Java version), only speaking at a set interval using Python but you can do similar things using cron on the Pi, which is my next step in playing with my Raspberry Pi!

What have you made with your Raspberry Pi? I’d love to get inspired by your ideas so please leave a comment below!

8 Comments

  1. suciarlak says:

    Hi,
    How do you resolved the output sound problem? I want to use it headless with an usb card but only got pulseaudio errors.

    Great project!!

  2. suciarlak says:

    It seems an ALSA problem, if i find a solution i will post it here.

    Thanks!

  3. suciarlak says:

    Found solution, now espeak works in a headless Raspberry with USB_card
    Making the usb card as the default device in ” /etc/asound.conf ”

    Just erase all and replace with this :

    pcm.!default {
    type hw
    card snd-usb-audio
    }
    ctl.!default {
    type hw
    card snd-usb-audio
    }

  4. suciarlak says:

    or this (to keeping alsamixer PCM mixer controls):
    Just erase all and replace with this :

    pcm.!default {
    type hw
    card 0
    }
    ctl.!default {
    type hw
    card 0
    }

    USB sound card must be fixed as hw 0,0 in ” /etc/modprobe.d/alsa-base.conf ” :

    options snd-usb-audio index=0

  5. suciarlak says:

    Hi Lyndon,

    How can i change the voices, speed…., are mbrola voices supported?

    Is ther any general config file?

    • Sorry about the very delayed reply!

      There’s some info on the API on their documentation site: http://pyttsx.readthedocs.org/en/v1.1/

      I should of linked to that in the post! I know you can change the speed of the voice using the setProperty() method, and there’s an option for changing the voice to but I don’t know which are supported.

      There’s an example of hearing the different voices:
      engine = pyttsx.init()
      voices = engine.getProperty('voices')
      for voice in voices:
      engine.setProperty('voice', voice.id)
      engine.say('The quick brown fox jumped over the lazy dog.')
      engine.runAndWait()

      If that helps!

      Lyndon

Leave a Reply