Search code examples
pythonpython-3.xraspberry-piraspbianmplayer

Using Python 3 on a Raspberry Pi, how to call MPlayer and passing a URL


(This is on a Raspberry Pi B running 2014-09-09-wheezy-raspbian, update and upgrade have been run, mplayer is installed and tested, coding using Python 3)

I only dabble in Linux and Pi so I have come to the experts for guidance.

Let me start by saying that this works:

#!/bin/bash
say() { local IFS=+;/usr/bin/mplayer -ao alsa -really-quiet -noconsolecontrols "http://translate.google.com/translate_tts?tl=en&q=$*"; }
# say() { local IFS=+;/usr/bin/mplayer -ao alsa -really-quiet -noconsolecontrols "http://translate.google.co.uk/translate_tts?tl=en&q=$*"; }

say $*

This bash script is executed like such: sudo ./speech.sh Bob's your uncle

The Pi happily goes out to Google and plays, via mplayer, the TTS. This let's me know who my uncle is.

My trouble happens in Python.

My ultimate goal is to have a small python 3 script start at start-up and every so often say some random statement. This will be mounted inside of a ceramic skull for the delight of ghosts and ghouls in the neighborhood.

Here is my python. Hopefully someone can tell me what I am doing wrong?

import urllib, os, random, urllib.request, urllib.parse, shutil, subprocess

def getGoogleSpeechURL(phrase):
    print (phrase)
    googleURL = "http://translate.google.com/translate_tts?tl=en&"
    parameters = {'q': phrase}
    data = urllib.parse.urlencode(parameters)
    googleURL = "%s%s" % (googleURL, data)
    return googleURL

def random_line(afileName):
    with open(afileName, "r") as afile:
        line = next(afile)
        for num, aline in enumerate(afile):
            if random.randrange(num + 2): continue
            line = aline
        return line

def speakSpeechFromText(phrase):
    print (phrase)
    googleSpeechURL = getGoogleSpeechURL(phrase)
    commandString = '/usr/bin/mplayer -ao alsa -really-quiet -noconsolecontrols ' + googleSpeechURL
    print (commandString)
    os.system(commandString)


filePath = "/home/pi/TalkingSkullPhrases.txt"

speakSpeechFromText (random_line(filePath))

I have tried os.system, subprocess, Popen... and nothing has worked. The system call just prints the command string and then exits out (is the code ending before mplayer? If so how do you get it to wait?). The subprocess and Popen both complain that it can't find mplayer (I've tried fully qualified paths there and no luck).

So *Nix and Python gurus, care to point out how I'm being an idiot and how I can fix it. :-)


Solution

  • One common mistake when using subprocess is that it needs the arguments to be supplied in a list, rather than a single string (unless you use some of the options like shell=True). So your mplayer call should be:

    subprocess.call(['mplayer', '-ao', 'alsa', '-really-quiet', '-noconsolecontrols', googleSpeechURL])