我正在尝试使用python 3在覆盆子pi上启动/停止tkinter中的视频文件。
我需要视频从头开始,每次红外传感器是低(损坏)和停止传感器再次高。理想情况下,视频应该在一个tkinter画布内,以便我可以在屏幕上同时显示其他元素(例如,加载栏)。
我设法让所有的东西都运行了,除了视频,它会在检测到传感器时立即运行,但它会冻结所有其他进程(例如加载条),并且在传感器处于高电平时不会停止。
以下是代码的简化(和未检查)版本,让您了解总体结构(实际代码要长得多):
import tkinter as TK
import RPi.GPIO as GPIO
import os
GPIO.setmode(GPIO.BCM)
GPIO.setup(14, GPIO.IN)
class App:
def __init__(self, root):
self.root = root
self.root.config(background = 'black', cursor = 'none')
self.background = TK.Canvas(root, width = 1024, height = 600, bg = 'black')
self.background.pack()
self.ext = 0
self.trial = 0
self.infrared()
def infrared(self):
if (GPIO.input(14) == False):
self.makebar()
if (self.ext == 0):
self.runvideo()
else:
os.system("killall omxplayer.bin")
self.ext = 0
self.root.after(16, self.infrared)
def runvideo(self):
os.system("omxplayer /home/pi/Desktop/testvideo.m4v")
def makebar():
self.stimulus_rect = TK.Canvas(root, width = 1024, height = 50, bg= 'white')
if self.ext < 1000
self.ext = self.ext + 10
self.stimulus_rect.create_rectangle(0, 0, self.ext, 50, fill="red")
self.stimulus_rect.place(x=0, y=0, anchor="new")
else:
self.trial = self.trial + 1
self.ext = 0
root = TK.Tk()
App(root)
root.mainloop()根据我在网上所能找到的: 1) tkinter可能会与opencv结合使用来实现这一点,但在树莓pi上安装opencv看起来并不是一个简单的操作;2)一般来说,涉及"os“的选项似乎注定无法实现我想要实现的目标。
我找不到一种干净的方法来做这件事。我的理想场景是将视频帧一个接一个地加载到画布中,并以60 at (屏幕频率)加载。然后,我将以完全相同的频率检查传感器,如果传感器没有损坏,则防止加载下一帧。在伪代码中,这将如下所示
def infrared(self):
if (GPIO.input(14) == False):
self.makebar()
if (self.ext == 0):
self.runvideo()
else:
self.video.stop
self.ext = 0
self.frame = 0
self.root.after(16, self.infrared)
def runvideo(self):
self.frame = self.frame + 1
video.run("testvideo.m4v", self.frame)关于如何在树莓派的tkinter中实现这一点有什么想法吗?
感谢蚂蚁
发布于 2019-03-25 22:29:49
经过一周的研究、试验和错误,这就是我目前如何实现我所需要的(用伪代码):
#### PSEUDOCODE ####
from subprocess import Popen # this library is used to open the video file
class App:
def __init__(self, root):
self.moviestart = False
self.movieduration = 130000
self.movie = "/home/pi/Desktop/test.mp4"
def infrared(self):
if (GPIO.input(IR) == False):
if not self.moviestart:
self.makevideo() # Call the function to start the video
self.moviestart = True # Flag that the video has started
self.moviestop = False # Flag that the video is currently playing
self.root.after(self.videoduration,
self.stopvideo) # manually call the stop video function
# to stop the video after 13 seconds (video's length).
# I could not find a more elegant way of doing this, unfortunately.
else:
self.clear_screen()
self.root.after(self.refreshIR, self.infrared)
def makevideo(self):
# popen will open the movie in a window of the size I specified,
# so that other element from tkinter can be placed on top of the movie window
omxc = Popen(['omxplayer', self.movie, '--win', "0 30 800 450"])
def stopvideo(self):
self.moviestart = False # flag that movie has been stopped
if (self.moviestop == False): # check if the movie is currently playing
try: # this is a cheap workaround other problems I had, do not try this at home
os.system('killall omxplayer.bin') # this literally kills any omxplayer instance
# currently open
self.moviestop = True # flag that the movie is not playing at the moment
except:
pass我希望这能对其他有类似问题的人有所帮助。如果我找到更好的解决方案,我会更新答案。就目前而言,这已经足够好了。
https://stackoverflow.com/questions/55118350
复制相似问题