【问题标题】:Two videos - Sync one with Flashing LED; all on GPIO button push两个视频 - 一个与闪烁的 LED 同步;全部按 GPIO 按钮
【发布时间】:2018-12-18 06:42:14
【问题描述】:

我是 Python 的新手,我正在做一个项目,我希望人们按下按钮来播放视频事件。 Video#1 将是默认的普通视频,而 video#2 将播放并闪烁来自 GPIO 13 (BCM) 的 LED。

这是我的两难选择:按钮 1、按钮 2 和按钮 3。如果我按 1 然后按按钮 3 中断它,通常我可以继续运行程序。但是,当我按下按钮 2 时,按钮 3 不会停止视频,但会终止工作,并且闪烁的 LED 不会在 GPIO 中清除。它通常处于 "ON" 状态。我已经为此奋斗了一两个星期,希望能得到一些帮助。如有必要,欢迎您重写;盯着屏幕看这么久,我头疼不已。该代码来自本网站上的各种其他代码,其他代码与我自己的一些修改合并。请问你能帮忙吗?

#!/usr/bin/env python3

import RPi.GPIO as GPIO
from omxplayer.player import OMXPlayer
from pathlib import Path
import time

GPIO.setmode(GPIO.BCM)

GPIO.setup(13, GPIO.OUT)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)

VIDEO_PATH1 = Path("/home/pi/Videos/ship.mp4")
VIDEO_PATH2 = Path("/home/pi/Videos/twist.mp4")

def blink():
    for j in range(0,5):
        GPIO.output(13, GPIO.HIGH)  # led on
        time.sleep(0.8)
        GPIO.output(13, GPIO.LOW) # led off
        time.sleep(0.8)

last_state1 = True
last_state2 = True

input_state1 = True
input_state2 = True
quit_video = True

playit = False

playit2 = False

while True:
    #Read states of inputs
    input_state1 = GPIO.input(17)
    input_state2 = GPIO.input(18)
    quit_video = GPIO.input(24)


    #If GPIO(17) is shorted to Ground
    if input_state1 == last_state1:
        if (playit and not input_state1):
            player.quit()
            player = OMXPlayer(VIDEO_PATH1)
            playit = True
        elif not input_state1:
            player = OMXPlayer(VIDEO_PATH1)
            playit = True

    #If GPIO(18) is shorted to Ground
    if input_state2 == last_state2:
        if (playit2 and not input_state2):
            player.quit()
            player = OMXPlayer(VIDEO_PATH2)
            blink()
            playit2 = True
        elif not input_state2:
            player = OMXPlayer(VIDEO_PATH2)
            blink()
            playit2 = True

    #If omxplayer is running and GIOP(17) and GPIO(18) are not
        elif (playit and playit2 and input_state1 and input_state2):
            player.quit()
            playit = False
            playit2 = False

    #GPIO(24) to close omxplayer manually - used during debug
    if quit_video == False:
        player.quit()
        GPIO.output(13,GPIO.LOW)   # led off
        GPIO.cleanup()             # Release resource
        playit = False
        playit2 = False


    #Set last_input states
    last_state1 = input_state1
    last_state2 = input_state2'

更新:

    '#!/usr/bin/env python3

    import RPi.GPIO as GPIO
    import time
    from omxplayer.player import OMXPlayer
    from pathlib import Path
    from time import sleep

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

    GPIO.setup(13,GPIO.OUT)
    GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)


    VIDEO_PATH1 = Path("/home/pi/Videos/ship.mp4")
    VIDEO_PATH2 = Path("/home/pi/Videos/twist.mp4")

    last_state1 = True
    last_state2 = True
    last_state3 = True

    input_state1 = True
    input_state2 = True
    quit_video = True

    playit = False
    playit2 = False

    def blink():
        while player.is_playing():
            GPIO.output(13,GPIO.HIGH)
            time.sleep(0.8)
            print("LED is ON!")
            GPIO.output(13,GPIO.LOW)
            time.sleep(0.8)
            print("LED is OFF!!")

    while True:
        #Read states of inputs
        input_state1 = GPIO.input(17)
        input_state2 = GPIO.input(18)
        quit_video = GPIO.input(24)

        #If GPIO(17) is shorted to Ground
        if input_state1 == last_state1:
            if (playit and not input_state1):
                player.quit()
                player = OMXPlayer(VIDEO_PATH1)
                playit = True
            elif not input_state1:
                player = OMXPlayer(VIDEO_PATH1)
                playit = True

        #If GPIO(18) is shorted to Ground
        if input_state2 == last_state2:
            if (playit2 and not input_state2):
                player.quit()
                player = OMXPlayer(VIDEO_PATH2)
                blink()
                playit2 = True

            elif not input_state2:
                player = OMXPlayer(VIDEO_PATH2)
                print("program is running")
                blink()
                playit2 = True


        #If omxplayer is running and GIOP(17) and GPIO(18) are not shorted to Ground
        elif (playit and playit2 and input_state1 and input_state2):
            player.quit()
            playit = False
            playit2 = False

        #GPIO(24) to close omxplayer manually - used during debug
        if quit_video == False:
            player.quit()
            playit = False
            playit2 = False
            GPIO.output(13, GPIO.LOW)   # led off

        #Set last_input states
        last_state1 = input_state1
        last_state2 = input_state2

【问题讨论】:

  • 我又做了一些工作,发现 blink() 正在阻止按钮 #2 上第二个视频的终止。它可以在没有该代码的情况下工作,但我需要 LED 每 0.8 秒闪烁一次。任何帮助将不胜感激。
  • 我修复了 LED 闪光灯/视频问题,但是视频不会在按下按钮 #3 (GPIO 24) 时停止并返回:Traceback(最近一次通话最后一次):文件“/home/ pi/Desktop/Master.print.py",第 69 行,在 blink() 文件中 "/home/pi/Desktop/Master.print.py",第 33 行,在 player.is_playing() 中闪烁:文件“”,第 2 行,在 is_playing 文件中“/home/pi/.local/lib/python3.5/site-packages/omxplayer/player.py”,第 50 行,在包装中引发 OMXPlayerDeadError( '进程不再存在,无法运行命令')

标签: video gpio led omxplayer


【解决方案1】:

我会使用一个紧密的循环来检查按钮并根据时间增量切换 LED。类似于以下内容:

#!/usr/bin/env python3

import RPi.GPIO as GPIO
import time,datetime,signal,sys
from omxplayer.player import OMXPlayer

def playerExit(code):
    print('exit',code)
    GPIO.output(ledGPIO,GPIO.LOW)
    global videoPlaying
    videoPlaying=False

def playVideo(video):
    global player,videoPlaying
    if player==None:
        player=OMXPlayer(video)
        player.exitEvent += lambda _, exit_code: playerExit(exit_code)
    else:
        player.load(video)
    videoPlaying=True

def signalHandler(sig,frame):
    print('Ctrl+C pressed')
    quitting()
    sys.exit(0)

def quitPlayerLED():
    GPIO.output(ledGPIO,GPIO.LOW)
    if player!=None:
        player.quit()

# gpio,video/quit,blink T/F
buttonVideos = [[17,"/home/pi/Videos/ship.mp4",False],
                [18,"/home/pi/Videos/twist.mp4",True],
                [24,"quit",False]]
ledGPIO = 13

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

GPIO.setup(ledGPIO,GPIO.OUT)
GPIO.output(ledGPIO,GPIO.LOW)
for buttonVideo in buttonVideos:
    GPIO.setup(buttonVideo[0], GPIO.IN, pull_up_down=GPIO.PUD_UP)

signal.signal(signal.SIGINT,signalHandler)

player = None
videoPlaying = False
blink = False
ledOn = False
toggle=datetime.datetime.now()

while True:
    # check buttons
    for buttonVideo in buttonVideos:
        if GPIO.input(buttonVideo[0]) == GPIO.LOW:
            print(buttonVideo[0],'pressed')
            if buttonVideo[1] == "quit":
                quitPlayerLED()
            else:
                playVideo(buttonVideo[1])
            blink = buttonVideo[2]
            if blink:
                ledOn = True
                toggle=datetime.datetime.now()+datetime.timedelta(seconds=0.8)
            else:
                GPIO.output(ledGPIO,GPIO.LOW)
            break

    # blink led        
    if blink and videoPlaying:
        if datetime.datetime.now() > toggle:
            print(ledOn)
            GPIO.output(ledGPIO,ledOn)
            ledOn = not ledOn
            toggle = datetime.datetime.now()+datetime.timedelta(seconds=0.8)

    time.sleep(0.1)

【讨论】:

  • 我会试试这个。我发现如果出现异常错误,视频将不会停止,并且会在没有错误的情况下停止。我找到了一种无需等待视频结束即可暂停视频的简单方法:除了 KeyboardInterrupt: command1 = "sudo killall -s 9 omxplayer.bin" os.system(command1)。还有 deadall()。
  • 我个人不喜欢仅仅杀死进程。
  • 我同意,但在测试时我需要快速杀死或等待 2 分钟。
  • 你的版本很好用。如何将其设置为有 1 个主视频 (normal.mp4) 循环,直到按下按钮,然后当 ship.mp4 或 twist.mp4 结束时,除非按下按钮 3(24),否则主视频将再次启动?
  • 如果您觉得这个答案是正确的,最好将其标记为这样。然后针对您的新要求提出另一个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
相关资源
最近更新 更多