I am trying to simultaneously:
I have tried to handle this with multithreading, but am running into an issue where Thread1 (func1) instantly broadcasts video to the screen, while Thread 2 (func2) can take 10-20 seconds (varies for some reason) to start capturing video. (a sleep() function wont help due to unpredictability). Think I need to Pause/Resume the first thread to wait for the second one to start capturing video. Or, have the second thread trigger the first.
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()
Simply use threading.Event
to synchronize both thread.
threading.Event
instance.wait()
on waiting side, .set()
on other side.Example:
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!
Applied code:
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()
This should wait until it's prepared, and exit pyglet after capture.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.