[英]Python Multithreading Help! Video Display/Capture
我正在尝试同时:
我曾尝试使用多线程来处理这个问题,但遇到了一个问题,即 Thread1 (func1) 立即将视频广播到屏幕上,而 Thread 2 (func2) 可能需要 10-20 秒(由于某种原因而有所不同)才能开始捕获视频。 (a sleep() function 由于不可预测性而无济于事)。 认为我需要暂停/恢复第一个线程以等待第二个线程开始捕获视频。 或者,让第二个线程触发第一个线程。
import pyglet
import numpy as np
import cv2
import time
from threading import Thread
from screeninfo import get_monitors
for monitor in get_monitors():
width = monitor.width
height = monitor.height
def func1():
vid_path='path/to/video'
window= pyglet.window.Window(width, height, fullscreen=True)
player = pyglet.media.Player()
source = pyglet.media.StreamingSource()
MediaLoad = pyglet.media.load(vid_path)
player.queue(MediaLoad)
player.play()
@window.event
def on_draw():
if player.source and player.source.video_format:
player.get_texture().blit(0,0)
pyglet.app.run()
def func2():
capture_duration = 60 #This portion of code
cap = cv2.VideoCapture(0) #takes about 10 seconds to
fourcc = cv2.VideoWriter_fourcc(*'XVID') #execute causing a time dif
out = cv2.VideoWriter('output.avi',fourcc, 30.0, (640,480)) #btw video play and
start_time = time.time() #capture
while( int(time.time() - start_time) < capture_duration ):
ret, frame = cap.read()
if ret==True:
out.write(frame)
else:
break
# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
Thread(target = func1).start()
Thread(target = func2).start()
只需使用threading.Event
来同步两个线程。
threading.Event
实例.wait()
,在另一侧调用.set()
。例子:
import threading
import time
def takes_long(event: threading.Event):
time.sleep(5)
print("[Long ] Started!")
event.set()
def takes_short(event: threading.Event):
print("[Short] Waiting for other thread!")
event.wait()
print("[Short] Started!")
event_ = threading.Event()
threading.Thread(target=takes_long, args=[event_]).start()
threading.Thread(target=takes_short, args=[event_]).start()
[Short] Waiting for other thread!
[Long ] Started!
[Short] Started!
应用代码:
import time
import threading
import pyglet
import cv2
# hard-coding for simplification
WIDTH, HEIGHT = 2560, 1440
DURATION = 10
# source / output path
SOURCE_PATH = "./sample.mp4"
OUTPUT_PATH = "X:/Temp/output.avi"
def func1(started_event: threading.Event):
"""Waits for func2 then plays the video for fixed duration"""
window = pyglet.window.Window(WIDTH, HEIGHT, fullscreen=True)
player = pyglet.media.Player()
media = pyglet.media.load(SOURCE_PATH)
player.queue(media)
# wait for event then play
started_event.wait()
player.play()
@window.event
def on_draw():
if player.source and player.source.video_format:
player.get_texture().blit(0, 0)
pyglet.app.run()
def func2(started_event: threading.Event):
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter(OUTPUT_PATH, fourcc, 30.0, (640, 480))
# now all required steps are done, fire event so video playback can start
started_event.set()
# now start capturing
start_time = time.time()
while (time.time() - start_time) < DURATION:
ret, frame = cap.read()
if ret:
out.write(frame)
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
pyglet.app.exit()
if __name__ == '__main__':
event = threading.Event()
threading.Thread(target=func1, args=(event,)).start()
threading.Thread(target=func2, args=(event,)).start()
这应该等到它准备好,并在捕获后退出 pyglet。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.