How to open and close omxplayer (Python/Raspberry Pi) while playing video?

给你一囗甜甜゛ 提交于 2020-01-10 06:10:07

问题


Using a Raspberry Pi and some push buttons I want to control video playback. When someone presses a button the corresponding video plays. The buttons work great. When you press a button the video plays, but when you press a different button or the same button it opens the video without closing the video that was currently playing. I've been searching a while to fix this. I'm pretty new to Python so please keep it as simple as possible. In the code below I'm trying to accomplish it using multithreading. I wasn't able to close the thread though when another thread starts. I am able to close the video after it plays for 10 seconds, but I can't move the quit command anywhere else to close other videos: playSippycup.stdin.write('q')

Here's are the errors I'm currently receiving:

Unhandled exception in thread started by <function shoppingcart at 0xb6c566f0>Playing Sippycup

Unhandled exception in thread started by <function dodgeballs at 0xb6c56670>
Traceback (most recent call last):
    File "./labmural2.py", line 53, in dodgeballs
    playDodgeballs.stdin.write('q')
NameError: global name 'playDodgeballs' is not defined
Traceback (most recent call last):
  File "./labmural2.py", line 71, in shoppingcart
    playShoppingcart.stdin.write('q')
NameError: global name 'playShoppingcart' is not defined

Thanks so much for any help you guys can offer!

#!/usr/bin/env python

import RPi.GPIO as GPIO
import subprocess
import time
import thread

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

GPIO.setup(9, GPIO.IN)
GPIO.setup(10, GPIO.IN)
GPIO.setup(11, GPIO.IN)

GPIO.setup(17, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)
GPIO.setup(27, GPIO.OUT)

def sippycup( name ):

        global playSippycup

        while True:
                if GPIO.input(11) == True:
                        print name
                        time.sleep(1)
                        playSippycup=subprocess.Popen(['omxplayer','Desktop/videos/sippycup.mp4'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, close_fds=True)
                        time.sleep(10)
                        playSippycup.stdin.write('q')

                if GPIO.input(9) == True:
                        playSippycup.stdin.write('q')

                if GPIO.input(10) == True:
                        playSippycup.stdin.write('q')

def dodgeballs( name ):

        global playDodgeballs

        while True:
                if GPIO.input(9) == True:
                        print name
                        time.sleep(1)
                        playDodgeballs=subprocess.Popen(['omxplayer','Desktop/videos/dodgeballs.mp4'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, close_fds=True)
                        time.sleep(10)
                        playDodgeballs.stdin.write('q')

                if GPIO.input(10) == True:
                        playDodgeballs.stdin.write('q')

                if GPIO.input(11) == True:
                        playDodgeballs.stdin.write('q')

def dodgeballs( name ):

        global playDodgeballs

        while True:
                if GPIO.input(9) == True:
                        print name
                        time.sleep(1)
                        playDodgeballs=subprocess.Popen(['omxplayer','Desktop/videos/dodgeballs.mp4'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, close_fds=True)
                        time.sleep(10)
                        playDodgeballs.stdin.write('q')

                if GPIO.input(10) == True:
                        playDodgeballs.stdin.write('q')

                if GPIO.input(11) == True:
                        playDodgeballs.stdin.write('q')

def shoppingcart( name ):

        global playShoppingcart

         while True:
                if GPIO.input(10) == True:
                        print name
                        time.sleep(1)
                        playShoppingcart=subprocess.Popen(['omxplayer','Desktop/videos/shoppingcart.mp4'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, close_fds=True)
                        time.sleep(10)
                        playShoppingcart.stdin.write('q')

            if GPIO.input(9) == True:
                        playShoppingcart.stdin.write('q')

            if GPIO.input(11) == True:
                        playShoppingcart.stdin.write('q')

thread.start_new_thread( sippycup, ("Playing Sippycup",) )
thread.start_new_thread( dodgeballs, ("Playing Dodgeballs",) )
thread.start_new_thread( shoppingcart, ("Playing Shoppingcart",) )

while True:
            pass

GPIO.cleanup()

NEW EDIT:

#!/usr/bin/python

from time import sleep
import RPi.GPIO as GPIO
import subprocess
import time
import thread

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

GPIO.setup(9, GPIO.IN)
GPIO.setup(10, GPIO.IN)
GPIO.setup(11, GPIO.IN)

GPIO.setup(17, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)
GPIO.setup(27, GPIO.OUT)

def welcome_loop():
    while True:
            global playProcess
            x = 1
            print "LOOPING"
            time.sleep(.5)
            playProcess=subprocess.Popen(['omxplayer','-b','Desktop/videos/loop/loop.mp4'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, close_fds=True)
            time.sleep(10)
            playProcess.stdin.write('q')
            x += 1

def videos():
    while True:
            if GPIO.input(9):
                    print "STOP LOOP"
                    time.sleep(.5)
                    playProcess.stdin.write('q')
                    time.sleep(.5)
                    print "Play Sippycup"
                    sippycup_video=subprocess.Popen(['omxplayer','-b','Desktop/videos/sippycup.mp4'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, close_fds=True)
                    time.sleep(10)
                    sippycup_video.stdin.write('q')
                    time.sleep(.5)
                    welcome_loop()

            if GPIO.input(10):
                    print "STOP LOOP"
                    time.sleep(.5)
                    playProcess.stdin.write('q')
                    time.sleep(.5)
                    print "Play Dodgeballs"
                    dodgeballs_video=subprocess.Popen(['omxplayer','-b','Desktop/videos/dodgeballs.mp4'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, close_fds=True)
                    time.sleep(10)
                    dodgeballs_video.stdin.write('q')
                    time.sleep(.5)
                    welcome_loop()

            if GPIO.input(11):
                    print "STOP LOOP"
                    time.sleep(.5)
                    playProcess.stdin.write('q')
                    time.sleep(.5)
                    print "Play Shoppingcart"
                    shoppingcart_video=subprocess.Popen(['omxplayer','-b','Desktop/videos/shoppingcart.mp4'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, close_fds=True)
                    time.sleep(10)
                    shoppingcart_video.stdin.write('q')
                    time.sleep(.5)
                    welcome_loop()

thread.start_new_thread( videos, () )
thread.start_new_thread( welcome_loop, () )

while True:
    pass

GPIO.cleanup()

ERROR:

Unhandled exception in thread started by Traceback (most recent call last): File "./labmural2.py", line 28, in welcome_loop playProcess.stdin.write('q') IOError: [Errno 32] Broken pipe


回答1:


NameError: global name 'playDodgeballs' is not defined means that you are trying to use playDodgeballs before it is defined playDodgeballs = ...

I would simplify your code by removing all globals and threads. subprocess.Popen runs a separate process; it doesn't block your main thread:

names = 'sippycup', 'dodgeballs', 'shoppingcart'
movies = ['Desktop/videos/{name}.mp4'.format(name=name) for name in names]
players = [Player(movie=movie) for movie in movies]
player = players[0]

setup_io() # GPIO setup
while True:
    for key in get_key_events(): # get GPIO input
        if key == '0':
           player = players[0]
        elif key == 'space':
           player.toggle() # pause/unpause
        elif key == 'enter':
           player.start()
        ...

where Player is a simple wrapper around omxplayer subprocess:

import logging
from subprocess import Popen, PIPE, DEVNULL

logger = logging.getLogger(__name__)

class Player:
    def __init__(self, movie):
       self.movie = movie
       self.process = None

    def start(self):
        self.stop()
        self.process = Popen(['omxplayer', self.movie], stdin=PIPE,
                             stdout=DEVNULL, close_fds=True, bufsize=0)
        self.process.stdin.write(start_command) # start playing

    def stop(self):
        p = self.process
        if p is not None:
           try:
               p.stdin.write(quit_command) # send quit command
               p.terminate()
               p.wait() # -> move into background thread if necessary
           except EnvironmentError as e:
               logger.error("can't stop %s: %s", self.movie, e)
           else:
               self.process = None

    def toggle(self):
        p = self.process
        if p is not None:
           try:
               p.stdin.write(toggle_command) # pause/unpause
           except EnvironmentError as e:
               logger.warning("can't toggle %s: %s", self.movie, e)

Specify appropriate start_command, quit_command, toggle_command. You could define different methods depending on what commands omxplayer understands and what commands you need.



来源:https://stackoverflow.com/questions/26389648/how-to-open-and-close-omxplayer-python-raspberry-pi-while-playing-video

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!