Search code examples
pythonpython-3.xraspberry-pimplayer

Stopping subprocess executing in a class


I'm trying to play a series of Audio files through MPlayer which is classed as a subprocess in Python.

Then when the .stop() command is called. I want the subprocess to..... well.. stop executing.

The important thing I want to keep occurring is the main thread. I don't want Python to terminate altogether.

Below is the code I have tried out so far.

class Alarm:

    urllib.request.urlretrieve(Settings.news_url, 'news.mp3')

    tts1 = gTTS(text='Good morning' + Settings.name + 'It is ' + str(date.today()), lang='en')
    tts2 = gTTS(text='Here is the latest news from the BBC world service', lang='en')
    tts3 = gTTS(text='The weather for today is ' + Settings.weather_rss.entries[0]['title'].split(' ', 1)[1], lang='en')
    tts4 = gTTS(text='That is all for now. Have a great day!', lang='en')

    tts1.save(Settings.greeting)
    tts2.save(Settings.news_intro)
    tts3.save(Settings.weather_forecast)
    tts4.save(Settings.outtro)


    def play(self):     
        alarmpi = subprocess.call(['mplayer', Settings.greeting, Settings.news_intro, 'news.mp3', Settings.weather_forecast, Settings.outtro]);

    def stop(self):
        alarmpi.kill()

alarm = Alarm()

on = Thread(target=alarm.play)
stop = Thread(target=alarm.stop)
on.start()
time.sleep(5)
stop.start()

However when I run this, I get an error saying alarmpi is not defined.

Is there a different way to tackle this issue?

Thanks in advance.


Solution

  • just define alarmpi as a member of the class using self object to store it so you can recall it in the stop method (define it first in the class constructor so you can call stop without calling play first)

    def __init__(self):
        self.alarmpi = None
    
    def play(self):     
        self.alarmpi = subprocess.call(['mplayer', Settings.greeting, Settings.news_intro, 'news.mp3', Settings.weather_forecast, Settings.outtro]);
    
    def stop(self):
        if self.alarmpi:
            self.alarmpi.kill()
            self.alarmpi = None