Unexpected delay due to MovieStim in looped routine (PsychoPy)

OS: Windows 11 Home
PsychoPy version: v2024.2.4
Standalone installation: Yes
Online experiment (Pavlovia): No

Goal:
I want to loop through a routine with the following sequence:
Fixation cross: 1s
Instruction (text): 0.8s
Video: 2s
Blank screen: 0.2s

Both the instruction and the video change on each loop iteration.

What works:
The routine runs fine when outside of a loop.
If I replace the video with an image, the timing is accurate (including the 0.2s blank).

Problem:
When using videos inside a loop, the last component (blank screen) consistently lasts about 500ms longer than expected — except on the final loop repetition, where it’s accurate.

Hypothesis:
I suspect the delay is caused by the video loading at the start of each trial, possibly happening during the blank screen time.

What I tried:
I isolated the routine from the full experiment.
I replaced the video with an image (the timing is then correct).
I use a code component in the “Each Frame” tab to control the timing, here is a simplified version:

t = Timer.getTime()

if t >= 0.0 and t < 1.0:
    cross.setAutoDraw(True)
else:
    cross.setAutoDraw(False)

if t >= 1.0 and t < 1.8:
    instruction.setAutoDraw(True)
else:
    instruction.setAutoDraw(False)

if t >= 1.8 and t < 3.8:
    if video.status == NOT_STARTED:
        clock_rt.reset()
    video.setAutoDraw(True)
    keys = event.getKeys(keyList=["s", "l", "escape"], timeStamped=clock_rt)
    if keys:
        ...
else:
    video.setAutoDraw(False)

if t >= 3.8 and t < 4.0:
    blank.setAutoDraw(True)
else:
    blank.setAutoDraw(False)

Question:
Is there a way to force PsychoPy to preload videos before the next trial starts, so that the blank screen timing stays accurate?
Or is there a recommended workaround to avoid this delay?

Thanks in advance!

I wouldn’t recommend setting AutoDraw every frame.

I usually use opacity or location to show/hide visual stimuli.

Big videos do take time to load. Does the video need to start from it’s beginning at 1.8 seconds or could it already be running (but invisible)?

Hello wakecarter,

The video start at 1.8. The duration of the video itself is 2s and I show the video during 2s.
What do you mean by don’t use AutoDraw every frame? Do you mean I can use AutoDraw one time and then chose to hide or show them when I want?

Thank you for your answer.

What is the code for? I think most of it should be deleted and you should just use the start times and durations of the builder components.

The first reason I use this code is that the CSI (instruction duration) and the blank duration aren’t always the same. I calculate the blank duration based on the CSI.

The second reason is that when I first started using Psychopy, I tried it with Builder and noticed issues with overlapping and timing out in my routine (for exemple the cross and the instruction overlap).

This solved my timing and overlap issues for all components except the last one, the one just before the loop returns (here the blank) to which 500ms was added for no reason.

I mean, I ask the user what CSI he wants (T), then I calculate the blank duration (V).
So I have something like this:
Fixation cross: 1s
Instruction (text): T s
Video: 2s
Blank screen: V s