.preview()
blocks code and it can't run code which checks event
.
But if it would run it then other problem could be that event
checks mouse click only inside pygame window but preview
uses OpenCV
to display own window (probably created with PyQt
)
You may use directly OpenCV
to read video frame-by-frame, resize it, convert to PyGame's surface, and display it in PyGame's window - and then you can use event
to stop/close it.
I keep some some code in comments because it can be useful to create more complex video - ie. you can display some elements directly on video.
import pygame
import cv2
video = cv2.VideoCapture("BigBuckBunny.mp4")
#w = video.get(cv2.CAP_PROP_FRAME_WIDTH)
#h = video.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = video.get(cv2.CAP_PROP_FPS) # video's speed (Frames Per Second)
pygame.init()
screen = pygame.display.set_mode((800,600))
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
running = False
# read single frame from video (as `numpy.array`)
ret, frame = video.read()
if ret: # check `return status` because it may have problem to read frame
#print(frame.shape)
# cv2 keeps image as `BGR` and it needs to convert to `RGB`
#frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# it gives first `height`, next `width`
#h, w = frame.shape[:2]
# it needs first `width`, next `height`
#image = pygame.image.frombuffer(frame, (w, h), "RGB")
# resize to pygame's window
frame = cv2.resize(frame, (800, 600))
# convert frame to PyGame surface
# cv2 keeps image as `BGR` and it needs to convert to `RGB`
image = pygame.image.frombuffer(frame, (800, 600), "BGR")
# display it in PyGame's window
screen.blit(image, (0,0))
# slow down to correct speed
clock.tick(fps)
pygame.display.flip()
# --- end ---
pygame.quit()
#exit()
Tested with video Big Buck Bunny