pythonmultithreadingraspberry-pigpioomxplayer

Killing or stopping an active thread


I've come a long way and I'm almost there. I've converted from using Thread to Threading and can now switch videos mid-play, but I still am having trouble killing or stopping the first video. Basically, I'm making a video player controlled by buttons on a Raspberry Pi using OMXplayer. At the moment, I have to wait for one video to finish playing before pressing another button or else it will crash because multiple videos are playing at the same time.

Thanks so much for any help you guys can offer.

#!/usr/bin/python

import RPi.GPIO as GPIO
import subprocess
import threading
import time

GPIO.setmode (GPIO.BCM)
GPIO.setwarnings (False)

GPIO.setup(9, GPIO.IN)  # Button 1
GPIO.setup(10, GPIO.IN) # Button 2

def shoppingcart():
        global current_video
        while True:
                if GPIO.input(9):
                        #current_video.terminate()
                        #current_video.kill()
                        print "Play Shoppingcart"
                        time.sleep(1)
                        current_video=subprocess.Popen(['omxplayer','-b','Desktop/videos/shoppingcart.mp4'],
                                        stdin=subprocess.PIPE,stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE,close_fds=True)

def dodgeballs():
        global current_video
        while True:
                if GPIO.input(10):
                        #current_video.terminate()
                        #current_video.kill()
                        print "Play Dodgeballs"
                        time.sleep(1)
                        current_video=subprocess.Popen(['omxplayer','-b','Desktop/videos/dodgeballs.mp4'],
                                        stdin=subprocess.PIPE,stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE,close_fds=True)

v1 = threading.Thread( name='shoppingcart', target=shoppingcart ) # Videos thread
v2 = threading.Thread( name='dodgeballs', target=dodgeballs )   # Videos thread

v1.start()
v2.start()

while True:
        pass

GPIO.cleanup() #Reset GPIOs

Solution

  • You need to implement your own threads:

    class RaspberryThread(threading.Thread):
        def __init__(self, function):
            self.running = False
            self.function = function
            super(RaspberryThread, self).__init__()
    
        def start(self):
            self.running = True
            super(RaspberryThread, self).start()
    
        def run(self):
            while self.running:
                self.function()
    
        def stop(self):
            self.running = False
    

    Then remove the while loops from your functions so you can pass them to the threads.

    v1 = RaspberryThread(function = shoppingcart)
    v2 = RaspberryThread(function = dodgeballs)
    
    v1.start()
    v2.start()
    

    Then you can stop the threads at any time

    v1.stop()
    v2.stop()