I am trying to write a small script to play video from files using opencv and pygame. The videos should play whenever a key is being pressed and keep playing until the end. When the key is released, the background color changes and I record the time between the keypress and the keyrelease.
So far so good, it seems to be working as expected. My only issue is with the fact that I cannot set the frame rate as I want to. All the videos have the same length (exactly 2500 ms, 20 fps) and when I run the script the videos are way too fast. I tried multiple things (video.set(cv2.cv.CV_CAP_PROP_FPS, ), ...) but it didn't work. The closest I get is by adding a self.sleep(50) somewhere in the loop. It seems to adjust the frame rate but it doens't seem to be very reliable as the length of each video is not consistent. Any advice would be greatly appreciated ! Thanks a lot !
import cv2
import numpy
import pygame
red = (255,0,0)
background_color = (0,0,0,)
#check whether the correct backend is being used (for OpenSesame)
if self.get('canvas_backend') == 'legacy':
surface = exp.surface
elif self.get('canvas_backend') == 'xpyriment':
surface = exp.window
else:
raise Exception('This script requires legacy or xpyriment (no opengl)')
# Full path to the video file
path = pool[self.get('video')]
# Open the video and determine the video dimensions
video = cv2.VideoCapture(path)
#initiate the video with a keypress and start the clock
key = None
while key == None:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
start_time = self.time()
key = event.key
go = True
while go:
# Get a frame and break the loop if we failed, usually because the video
# ended.
success, frame = video.read()
if not success:
break
#for some reasons the frames appeared inverted
frame = numpy.fliplr(frame)
frame = numpy.rot90(frame)
# The video uses BGR colors and PyGame needs RGB
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# Create a PyGame surface
surf = pygame.surfarray.make_surface(frame)
#set the frame rate to 20 fps ?? To be verified.
self.sleep(50)
# Fill the background color of the PyGame surface whenever a key is released
for event in pygame.event.get():
if event.type == pygame.KEYUP:
background_color = red
surface.fill(background_color)
pygame.display.update
end_time = self.time()
# Show the PyGame surface!
surface.blit(surf, ((surface.get_rect().centerx-150),(surface.get_rect().centery-100)))
pygame.display.flip()
#define the experimental variable
rt = end_time- start_time
exp.set('keyreleaseRT', rt)
print '%s was released after %d ms' % (key, rt)