psychopy.org | Reference | Downloads | Github

The handle is invalid (error) OR a Fatal Python Error, mmpeg issues?, movie as stimuli

If this template helps then use it. If not then just delete and start from scratch.

OS: Win10
PsychoPy version (e.g. 1.84.x): 1.90.3
Standard Standalone? (y/n) : not standalone (not sure-it may be that anaconda was used to help create the enviornment?-I’ll ask my coworker and update this answer) then standalone
**What are you trying to achieve?: People watch a video clip, click an answer, then click another button to move onto the next trial. Once in awhile, the program goes through, but most of the time, it crashes after next is selected. At the moment, everything is recording and behaving correctly, except for the crashes.

finalroutine

What did you try to make it work?:
I had help on going through these checks:
Checked different movie clip file sizes, checked individual clips for crash (going through them sequentially), checked the amount of videos playing that can be handled 1-4, checked the rate of going through each scenario from fast to a little slower. Increased the pause routine in between trials because maybe the movie reader is having problems with closing the reader and opening another one for the next trial?

        all still crashed either after the second block or after hitting next after some trials, and the traceback messages are displayed below

changed backend default from moviepy to the other 2 options, ovencv, avbin
pardon, I forgot the error message that popped up, but they didn’t like that–> prog crashed when trying to run

Clicked on the compiler button and looked at the coder view-clicked through each of the Traceback messages.

    depth=-2.0
lib\site-packages\psychopy\visual\movie3.py
    self.loadMoviee(self.filename)
    self.mov=VideoFileClip(filename, audio=(1=self.noAudio))
lib\site-packages\moviepy\video\io\VideoFileClip.py
   fps_source=fps_source
lib\site-packages\moviepy\video\io\ffmpeg_reader.py
   fps_source
lib\site-packages\moviepy\video\io\ffmpeg_reader.py
   proc=sp.Popen(cmd, **popen_params)
lib\subprocess.py
   _cleanup()
lib\subprocess.py
   res=inst.internal_poll(_deadstate=sys.maxsize)
lib\subprocess.py
   if _WaitForSingleObject(self.handle,0) == _WAIT_OBJECT_0:
OSERROR: [WinError 6] The handle is invalid

After downloading a standalone version, the whole experiment goes through until the end. After ending, there is a

Fatal Python error: PyImport_GetModuleDict: no module dictionary!

\lib\site-packages\moviepy\video\io\VideoFileClip.py

Your insight will be most appreciated! We spent a good portion of the day just trying different things to see what is going on. The program was built on builder with code components. Since the builder items look right, I will share the compiled code. Learning at the moment as a beginner, so some code components may not be as efficient.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import absolute_import, division
from psychopy import locale_setup, sound, gui, visual, core, data, event, logging, clock
from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED,
                                STOPPED, FINISHED, PRESSED, RELEASED, FOREVER)
import numpy as np  # whole numpy lib is available, prepend 'np.'
from numpy import (sin, cos, tan, log, log10, pi, average,
                   sqrt, std, deg2rad, rad2deg, linspace, asarray)
from numpy.random import random, randint, normal, shuffle
import os  # handy system and path functions
import sys  # to get file system encoding

# Ensure that relative paths start from the same directory as this script
_thisDir = os.path.dirname(os.path.abspath(__file__)).decode(sys.getfilesystemencoding())
os.chdir(_thisDir)

# Store info about the experiment session
expName = 'blockedVideoTrialsWithBreaksWorking_videoLoop_PreFinal'  # from the Builder filename that created this script
expInfo = {'participant': ''}
dlg = gui.DlgFromDict(dictionary=expInfo, title=expName)
if dlg.OK == False:
    core.quit()  # user pressed cancel
expInfo['date'] = data.getDateStr()  # add a simple timestamp
expInfo['expName'] = expName

# Data file name stem = absolute path + name; later add .psyexp, .csv, .log, etc
filename = _thisDir + os.sep + u'data/%s_%s_%s' % (expInfo['participant'], expName, expInfo['date'])

# An ExperimentHandler isn't essential but helps with data saving
thisExp = data.ExperimentHandler(name=expName, version='',
    extraInfo=expInfo, runtimeInfo=None,
    originPath=None,
    savePickle=True, saveWideText=True,
    dataFileName=filename)
# save a log file for detail verbose info
logFile = logging.LogFile(filename+'.log', level=logging.EXP)
logging.console.setLevel(logging.WARNING)  # this outputs to the screen, not a file

endExpNow = False  # flag for 'escape' or other condition => quit the exp

# Start Code - component code to be run before the window creation

# Setup the Window
win = visual.Window(
    size=[1920, 1080], fullscr=False, screen=0,
    allowGUI=True, allowStencil=False,
    monitor='testMonitor', color=[0,0,0], colorSpace='rgb',
    blendMode='avg', useFBO=True,
    units='norm')
# store frame rate of monitor if we can measure it
expInfo['frameRate'] = win.getActualFrameRate()
if expInfo['frameRate'] != None:
    frameDur = 1.0 / round(expInfo['frameRate'])
else:
    frameDur = 1.0 / 60.0  # could not measure, so guess

# Initialize components for Routine "beginInstruct"
beginInstructClock = core.Clock()
overviewInstructions = visual.TextStim(win=win, name='overviewInstructions',
    text='INSTRUCTIONS PLACEMENT\n\nClick Next to contine.\n',
    font='Arial',
    pos=(0, 0), height=0.1, wrapWidth=None, ori=0, 
    color='white', colorSpace='rgb', opacity=1,
    depth=0.0);
mousenext = event.Mouse(win=win)
x, y = [None, None]
nextInstrucButton = visual.Rect(
    win=win, name='nextInstrucButton',
    width=(0.25, 0.15)[0], height=(0.25, 0.15)[1],
    ori=0, pos=(0, -.5),
    lineWidth=1, lineColor=[1,1,1], lineColorSpace='rgb',
    fillColor=[-1,-1,-1], fillColorSpace='rgb',
    opacity=.5, depth=-2.0, interpolate=True)
text = visual.TextStim(win=win, name='text',
    text='Next >>',
    font='Arial',
    units='norm', pos=(0, -.5), height=0.1, wrapWidth=None, ori=0, 
    color='white', colorSpace='rgb', opacity=1,
    depth=-3.0);

# Initialize components for Routine "pause"
pauseClock = core.Clock()
text_2 = visual.TextStim(win=win, name='text_2',
    text='Loading ...',
    font='Arial',
    pos=(0, 0), height=0.1, wrapWidth=None, ori=0, 
    color='white', colorSpace='rgb', opacity=1,
    depth=0.0);


# Initialize components for Routine "registersNext"
registersNextClock = core.Clock()

mouseYN_2 = event.Mouse(win=win)
x, y = [None, None]
yesButton_2 = visual.Rect(
    win=win, name='yesButton_2',
    width=(0.1, 0.1)[0], height=(0.1, 0.1)[1],
    ori=0, pos=(-0.15, -0.78),
    lineWidth=1, lineColor=[1,1,1], lineColorSpace='rgb',
    fillColor=[-.9,-.9,-.9], fillColorSpace='rgb',
    opacity=0.3, depth=-3.0, interpolate=True)
noButton_2 = visual.Rect(
    win=win, name='noButton_2',
    width=(0.1, 0.1)[0], height=(0.1, 0.1)[1],
    ori=0, pos=(0, -0.78),
    lineWidth=1, lineColor=[1,1,1], lineColorSpace='rgb',
    fillColor=[-.9,-.9,-.9], fillColorSpace='rgb',
    opacity=.3, depth=-4.0, interpolate=True)
nextImageButton_2 = visual.Rect(
    win=win, name='nextImageButton_2',
    width=(0.5, 0.1)[0], height=(0.5, 0.1)[1],
    ori=0, pos=(0.5, -0.8),
    lineWidth=1, lineColor=[.2,.2,.2], lineColorSpace='rgb',
    fillColor=[.1,.1,.1], fillColorSpace='rgb',
    opacity=.4, depth=-5.0, interpolate=True)
yesText_2 = visual.TextStim(win=win, name='yesText_2',
    text='Yes',
    font='Arial',
    pos=(-0.15, -0.78), height=0.05, wrapWidth=None, ori=0, 
    color='white', colorSpace='rgb', opacity=1,
    depth=-6.0);
noText_2 = visual.TextStim(win=win, name='noText_2',
    text='No',
    font='Arial',
    pos=(0, -0.78), height=0.05, wrapWidth=None, ori=0, 
    color='white', colorSpace='rgb', opacity=1,
    depth=-7.0);
nextIma_2 = visual.TextStim(win=win, name='nextIma_2',
    text='Next Image >>',
    font='Arial',
    pos=(0.5, -0.8), height=0.05, wrapWidth=None, ori=0, 
    color='white', colorSpace='rgb', opacity=1,
    depth=-8.0);

# Initialize components for Routine "interBreak"
interBreakClock = core.Clock()

breakMouse = event.Mouse(win=win)
x, y = [None, None]
breakInBetween = visual.TextStim(win=win, name='breakInBetween',
    text='Please use this time to take a brief break.\nFeel free to use the bathroom or rest your eyes for a minute.\n\nWhen you are ready to go to the next block of trials, click next.',
    font='Arial',
    pos=(0, 0), height=0.1, wrapWidth=None, ori=0, 
    color='white', colorSpace='rgb', opacity=1,
    depth=-2.0);
finishBreak = visual.Rect(
    win=win, name='finishBreak',
    width=(0.2, 0.1)[0], height=(0.2, 0.1)[1],
    ori=0, pos=(0, -.7),
    lineWidth=1, lineColor=[-1,-1,-1], lineColorSpace='rgb',
    fillColor=[-1,-1,-1], fillColorSpace='rgb',
    opacity=.5, depth=-3.0, interpolate=True)
nextPastBreak = visual.TextStim(win=win, name='nextPastBreak',
    text='Next >>',
    font='Arial',
    pos=(0, -.7), height=0.1, wrapWidth=None, ori=0, 
    color='white', colorSpace='rgb', opacity=1,
    depth=-4.0);
numblocks = visual.TextStim(win=win, name='numblocks',
    text='default text',
    font='Arial',
    pos=(0, -.8), height=0.1, wrapWidth=None, ori=0, 
    color='white', colorSpace='rgb', opacity=1,
    depth=-5.0);

# Initialize components for Routine "thanks"
thanksClock = core.Clock()
text_3 = visual.TextStim(win=win, name='text_3',
    text='Thanks!\n\nYou are finished.\n\nClick anywhere to close out the program.\n\nNote to self:\n-Two of the images are at different wxh based on pixels \n-set width and height to be a square at norm of 1 to 1\n-displayed image with w and h same as saved format\n',
    font='Arial',
    pos=(0, 0), height=0.1, wrapWidth=None, ori=0, 
    color='white', colorSpace='rgb', opacity=1,
    depth=0.0);
mouse = event.Mouse(win=win)
x, y = [None, None]

# Create some handy timers
globalClock = core.Clock()  # to track the time since experiment started
routineTimer = core.CountdownTimer()  # to track time remaining of each (non-slip) routine 

# ------Prepare to start Routine "beginInstruct"-------
t = 0
beginInstructClock.reset()  # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
# setup some python lists for storing info about the mousenext
mousenext.clicked_name = []
gotValidClick = False  # until a click is received
# keep track of which components have finished
beginInstructComponents = [overviewInstructions, mousenext, nextInstrucButton, text]
for thisComponent in beginInstructComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

# -------Start Routine "beginInstruct"-------
while continueRoutine:
    # get current time
    t = beginInstructClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    
    # *overviewInstructions* updates
    if t >= 0.0 and overviewInstructions.status == NOT_STARTED:
        # keep track of start time/frame for later
        overviewInstructions.tStart = t
        overviewInstructions.frameNStart = frameN  # exact frame index
        overviewInstructions.setAutoDraw(True)
    # *mousenext* updates
    if t >= 0.0 and mousenext.status == NOT_STARTED:
        # keep track of start time/frame for later
        mousenext.tStart = t
        mousenext.frameNStart = frameN  # exact frame index
        mousenext.status = STARTED
        prevButtonState = mousenext.getPressed()  # if button is down already this ISN'T a new click
    if mousenext.status == STARTED:  # only update if started and not stopped!
        buttons = mousenext.getPressed()
        if buttons != prevButtonState:  # button state changed?
            prevButtonState = buttons
            if sum(buttons) > 0:  # state changed to a new click
                # check if the mouse was inside our 'clickable' objects
                for obj in [nextInstrucButton]:
                    if obj.contains(mousenext):
                        gotValidClick = True
                        mousenext.clicked_name.append(obj.name)
                if gotValidClick:  # abort routine on response
                    continueRoutine = False
    
    # *nextInstrucButton* updates
    if t >= 0.0 and nextInstrucButton.status == NOT_STARTED:
        # keep track of start time/frame for later
        nextInstrucButton.tStart = t
        nextInstrucButton.frameNStart = frameN  # exact frame index
        nextInstrucButton.setAutoDraw(True)
    
    # *text* updates
    if t >= 0.0 and text.status == NOT_STARTED:
        # keep track of start time/frame for later
        text.tStart = t
        text.frameNStart = frameN  # exact frame index
        text.setAutoDraw(True)
    
    # check if all components have finished
    if not continueRoutine:  # a component has requested a forced-end of Routine
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in beginInstructComponents:
        if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
            continueRoutine = True
            break  # at least one component has not yet finished
    
    # check for quit (the Esc key)
    if endExpNow or event.getKeys(keyList=["escape"]):
        core.quit()
    
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()

# -------Ending Routine "beginInstruct"-------
for thisComponent in beginInstructComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# store data for thisExp (ExperimentHandler)
thisExp.nextEntry()
# the Routine "beginInstruct" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()

# set up handler to look after randomisation of conditions etc
blocks = data.TrialHandler(nReps=1, method='random', 
    extraInfo=expInfo, originPath=-1,
    trialList=data.importConditions('blockOrder.xlsx'),
    seed=None, name='blocks')
thisExp.addLoop(blocks)  # add the loop to the experiment
thisBlock = blocks.trialList[0]  # so we can initialise stimuli with some values
# abbreviate parameter names if possible (e.g. rgb = thisBlock.rgb)
if thisBlock != None:
    for paramName in thisBlock:
        exec('{} = thisBlock[paramName]'.format(paramName))

for thisBlock in blocks:
    currentLoop = blocks
    # abbreviate parameter names if possible (e.g. rgb = thisBlock.rgb)
    if thisBlock != None:
        for paramName in thisBlock:
            exec('{} = thisBlock[paramName]'.format(paramName))
    
    # set up handler to look after randomisation of conditions etc
    trials = data.TrialHandler(nReps=1, method='random', 
        extraInfo=expInfo, originPath=-1,
        trialList=data.importConditions(orderBlocks),
        seed=None, name='trials')
    thisExp.addLoop(trials)  # add the loop to the experiment
    thisTrial = trials.trialList[0]  # so we can initialise stimuli with some values
    # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
    if thisTrial != None:
        for paramName in thisTrial:
            exec('{} = thisTrial[paramName]'.format(paramName))
    
    for thisTrial in trials:
        currentLoop = trials
        # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
        if thisTrial != None:
            for paramName in thisTrial:
                exec('{} = thisTrial[paramName]'.format(paramName))
        
        # ------Prepare to start Routine "pause"-------
        t = 0
        pauseClock.reset()  # clock
        frameN = -1
        continueRoutine = True
        routineTimer.add(1.200000)
        # update component parameters for each repeat
        #gives a 0.2 second pause before the next trial appears
        #there is a noticeable different in user test taking satisfaction
        #pierce (creator of psychopy) mentions that users feel that the exp is 
        #running too fast if the stimuli appears exactly one right after another
        # keep track of which components have finished
        pauseComponents = [text_2]
        for thisComponent in pauseComponents:
            if hasattr(thisComponent, 'status'):
                thisComponent.status = NOT_STARTED
        
        # -------Start Routine "pause"-------
        while continueRoutine and routineTimer.getTime() > 0:
            # get current time
            t = pauseClock.getTime()
            frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
            # update/draw components on each frame
            
            # *text_2* updates
            if t >= 0.2 and text_2.status == NOT_STARTED:
                # keep track of start time/frame for later
                text_2.tStart = t
                text_2.frameNStart = frameN  # exact frame index
                text_2.setAutoDraw(True)
            frameRemains = 0.2 + 1- win.monitorFramePeriod * 0.75  # most of one frame period left
            if text_2.status == STARTED and t >= frameRemains:
                text_2.setAutoDraw(False)
            
            
            # check if all components have finished
            if not continueRoutine:  # a component has requested a forced-end of Routine
                break
            continueRoutine = False  # will revert to True if at least one component still running
            for thisComponent in pauseComponents:
                if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
                    continueRoutine = True
                    break  # at least one component has not yet finished
            
            # check for quit (the Esc key)
            if endExpNow or event.getKeys(keyList=["escape"]):
                core.quit()
            
            # refresh the screen
            if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
                win.flip()
        
        # -------Ending Routine "pause"-------
        for thisComponent in pauseComponents:
            if hasattr(thisComponent, "setAutoDraw"):
                thisComponent.setAutoDraw(False)
        
        
        # ------Prepare to start Routine "registersNext"-------
        t = 0
        registersNextClock.reset()  # clock
        frameN = -1
        continueRoutine = True
        # update component parameters for each repeat
        #WOOOOOOOOOOOOOWEEEEEEEEEEEEEEEEEE
        # setup some python lists for storing info about the mouseYN_2
        mouseYN_2.clicked_name = []
        mouseYN_2.clicked_pos = []
        mouseYN_2.clicked_time = []
        gotValidClick = False  # until a click is received
        movie_2 = visual.MovieStim3(
            win=win, name='movie_2',
            noAudio = True,
            filename=videoClips,
            ori=0, pos=(0, 0), opacity=1,
            depth=-2.0,
            )
        # keep track of which components have finished
        registersNextComponents = [mouseYN_2, movie_2, yesButton_2, noButton_2, nextImageButton_2, yesText_2, noText_2, nextIma_2]
        for thisComponent in registersNextComponents:
            if hasattr(thisComponent, 'status'):
                thisComponent.status = NOT_STARTED
        
        # -------Start Routine "registersNext"-------
        while continueRoutine:
            # get current time
            t = registersNextClock.getTime()
            frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
            # update/draw components on each frame
            
            #checks each frame to see if the mouse overs over butt obj
            #provide user feedback when they hover mouse over y/n button
            #color of button looks darker (changed opacity since couldn't get setColor to come out correctly
            
            if yesButton_2.contains(mouseYN_2):
                #YesButton.color = ([-1,-1,-1], colorSpace='rgb')
                yesButton_2.opacity=(.5)
            
            else:
                #YesButton.color = ([1,1,1], colorSpace='rgb')
                yesButton_2.opacity= (.3)
            
            if noButton_2.contains(mouseYN_2):
                #NoButton.color = ([-1,-1,-1], colorSpace='rgb')
                noButton_2.opacity=(.5)
            
            else:
                #NoButton.color= ([1,1,1], colorSpace='rgb')
                noButton_2.opacity= (.3)
            
            #gives user visible feedback when Yes or No buttons are pressed
            # these lines does not mean that these lines save the answer
            #gives buttons a bounce effect
            
            if mouseYN_2.isPressedIn(yesButton_2, buttons=[0]): #left-click only on yesbutt
                yesButton_2.opacity=(.9)
            #    yesButton_2.setColor=((-1,-1,-1),'rgb255')
                noButton_2.opacity=(.3) 
            
            elif mouseYN_2.isPressedIn(noButton_2, buttons=[0]):
            #    noButton_2.color=((-1,-1,-1),'rgb255')
                yesButton_2.opacity=(.3)
                noButton_2.opacity=(.9)
            
            else:
                pass #do nothing. also read that can leave this out
            
            
            #if people end up changing their answer, then allow prog to save the answer before moving on
            #saves the button name, time clicked, and position to a list
            if mouseYN_2.isPressedIn(yesButton_2, buttons=[0]):
            
                stimX,stimY = mouseYN_2.getPos() #in case you want to later save the x and y coordinates in end routine
                mouseYN_2.clicked_name.append(yesButton_2.name)
                mouseYN_2.clicked_pos.append(yesButton_2.pos)
                mouseYN_2.clicked_time.append(registersNextClock.getTime())
            
            elif mouseYN_2.isPressedIn(noButton_2, buttons=[0]):
            
                stimX,stimY = mouseYN_2.getPos()#in case you want to later save the x and y coordinates in end routine
                mouseYN_2.clicked_name.append(noButton_2.name)
                mouseYN_2.clicked_pos.append(noButton_2.pos)
                mouseYN_2.clicked_time.append(registersNextClock.getTime())
            
            
            #check to make sure Y/N clicked before moving on
            if mouseYN_2.isPressedIn(nextImageButton_2, buttons=[0]):
            
                if yesButton_2.name in mouseYN_2.clicked_name: #if name of object in mouse object list
            #        movieClipLooping.finished=True #looping ends (can actually take out movieClipLooping but kept it there in case need to loop stuff in future
                    continueRoutine = False #stops current routine and starts new one or the next trial
            
                elif noButton_2.name in mouseYN_2.clicked_name:
            #        movieClipLooping.finished=True (added in case in future, need to loop this routine)
                    continueRoutine = False
            
                else:
            #        print("Please click yes or no before clicking Next Image") #need to format this
                    continueRoutine = True 
            else:
                movie_2.loop=True #if don't click on Next, keep looping the movie
            
            
            
            
            
            # *movie_2* updates
            if t >= 0.0 and movie_2.status == NOT_STARTED:
                # keep track of start time/frame for later
                movie_2.tStart = t
                movie_2.frameNStart = frameN  # exact frame index
                movie_2.setAutoDraw(True)
            
            # *yesButton_2* updates
            if t >= 0 and yesButton_2.status == NOT_STARTED:
                # keep track of start time/frame for later
                yesButton_2.tStart = t
                yesButton_2.frameNStart = frameN  # exact frame index
                yesButton_2.setAutoDraw(True)
            
            # *noButton_2* updates
            if t >= 0.0 and noButton_2.status == NOT_STARTED:
                # keep track of start time/frame for later
                noButton_2.tStart = t
                noButton_2.frameNStart = frameN  # exact frame index
                noButton_2.setAutoDraw(True)
            
            # *nextImageButton_2* updates
            if t >= 0.0 and nextImageButton_2.status == NOT_STARTED:
                # keep track of start time/frame for later
                nextImageButton_2.tStart = t
                nextImageButton_2.frameNStart = frameN  # exact frame index
                nextImageButton_2.setAutoDraw(True)
            
            # *yesText_2* updates
            if t >= 0.0 and yesText_2.status == NOT_STARTED:
                # keep track of start time/frame for later
                yesText_2.tStart = t
                yesText_2.frameNStart = frameN  # exact frame index
                yesText_2.setAutoDraw(True)
            
            # *noText_2* updates
            if t >= 0.0 and noText_2.status == NOT_STARTED:
                # keep track of start time/frame for later
                noText_2.tStart = t
                noText_2.frameNStart = frameN  # exact frame index
                noText_2.setAutoDraw(True)
            
            # *nextIma_2* updates
            if t >= 0.0 and nextIma_2.status == NOT_STARTED:
                # keep track of start time/frame for later
                nextIma_2.tStart = t
                nextIma_2.frameNStart = frameN  # exact frame index
                nextIma_2.setAutoDraw(True)
            
            # check if all components have finished
            if not continueRoutine:  # a component has requested a forced-end of Routine
                break
            continueRoutine = False  # will revert to True if at least one component still running
            for thisComponent in registersNextComponents:
                if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
                    continueRoutine = True
                    break  # at least one component has not yet finished
            
            # check for quit (the Esc key)
            if endExpNow or event.getKeys(keyList=["escape"]):
                core.quit()
            
            # refresh the screen
            if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
                win.flip()
        
        # -------Ending Routine "registersNext"-------
        for thisComponent in registersNextComponents:
            if hasattr(thisComponent, "setAutoDraw"):
                thisComponent.setAutoDraw(False)
        if len(mouseYN_2.clicked_name):  #if there is a something in length of list (versus nothing in list)
            trials.addData('Answer',mouseYN_2.clicked_name[-1]) #saves last answer in list of clicked Y and N
            trials.addData('Button position', mouseYN_2.clicked_pos[-1]) #saves the last ans's x, y mouse position @ valid obj's center coordinates
            trials.addData('Reaction Time', mouseYN_2.clicked_time[-1]) #reaction time of last clicked answer
        
        # store data for trials (TrialHandler)
        # the Routine "registersNext" was not non-slip safe, so reset the non-slip timer
        routineTimer.reset()
        thisExp.nextEntry()
        
    # completed 1 repeats of 'trials'
    
    
    # ------Prepare to start Routine "interBreak"-------
    t = 0
    interBreakClock.reset()  # clock
    frameN = -1
    continueRoutine = True
    # update component parameters for each repeat
    if blocks.thisN == 1: #if at 2nd block (final block)
        continueRoutine = False #don't continue the routine, showing recommendation for break
    #tried to say if blocks.thisN == -1: but this doesn't stop running in last block listed in array
    
    # setup some python lists for storing info about the breakMouse
    breakMouse.clicked_name = []
    gotValidClick = False  # until a click is received
    numblocks.setText(#gives user feedback on current block out of total
#find the current block number out of all and turns them into strings to be printed out
'Block: ' + str(trials.thisRepN) + ' out of ' + str(trials.nReps + 1))
    # keep track of which components have finished
    interBreakComponents = [breakMouse, breakInBetween, finishBreak, nextPastBreak, numblocks]
    for thisComponent in interBreakComponents:
        if hasattr(thisComponent, 'status'):
            thisComponent.status = NOT_STARTED
    
    # -------Start Routine "interBreak"-------
    while continueRoutine:
        # get current time
        t = interBreakClock.getTime()
        frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
        # update/draw components on each frame
        
        # *breakMouse* updates
        if t >= 0.0 and breakMouse.status == NOT_STARTED:
            # keep track of start time/frame for later
            breakMouse.tStart = t
            breakMouse.frameNStart = frameN  # exact frame index
            breakMouse.status = STARTED
            prevButtonState = breakMouse.getPressed()  # if button is down already this ISN'T a new click
        if breakMouse.status == STARTED:  # only update if started and not stopped!
            buttons = breakMouse.getPressed()
            if buttons != prevButtonState:  # button state changed?
                prevButtonState = buttons
                if sum(buttons) > 0:  # state changed to a new click
                    # check if the mouse was inside our 'clickable' objects
                    for obj in [finishBreak]:
                        if obj.contains(breakMouse):
                            gotValidClick = True
                            breakMouse.clicked_name.append(obj.name)
                    if gotValidClick:  # abort routine on response
                        continueRoutine = False
        
        # *breakInBetween* updates
        if t >= 0.0 and breakInBetween.status == NOT_STARTED:
            # keep track of start time/frame for later
            breakInBetween.tStart = t
            breakInBetween.frameNStart = frameN  # exact frame index
            breakInBetween.setAutoDraw(True)
        
        # *finishBreak* updates
        if t >= 0.0 and finishBreak.status == NOT_STARTED:
            # keep track of start time/frame for later
            finishBreak.tStart = t
            finishBreak.frameNStart = frameN  # exact frame index
            finishBreak.setAutoDraw(True)
        
        # *nextPastBreak* updates
        if t >= 0.0 and nextPastBreak.status == NOT_STARTED:
            # keep track of start time/frame for later
            nextPastBreak.tStart = t
            nextPastBreak.frameNStart = frameN  # exact frame index
            nextPastBreak.setAutoDraw(True)
        
        # *numblocks* updates
        if t >= 0.0 and numblocks.status == NOT_STARTED:
            # keep track of start time/frame for later
            numblocks.tStart = t
            numblocks.frameNStart = frameN  # exact frame index
            numblocks.setAutoDraw(True)
        
        # check if all components have finished
        if not continueRoutine:  # a component has requested a forced-end of Routine
            break
        continueRoutine = False  # will revert to True if at least one component still running
        for thisComponent in interBreakComponents:
            if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
                continueRoutine = True
                break  # at least one component has not yet finished
        
        # check for quit (the Esc key)
        if endExpNow or event.getKeys(keyList=["escape"]):
            core.quit()
        
        # refresh the screen
        if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
            win.flip()
    
    # -------Ending Routine "interBreak"-------
    for thisComponent in interBreakComponents:
        if hasattr(thisComponent, "setAutoDraw"):
            thisComponent.setAutoDraw(False)
    
    # store data for blocks (TrialHandler)
    # the Routine "interBreak" was not non-slip safe, so reset the non-slip timer
    routineTimer.reset()
# completed 1 repeats of 'blocks'


# ------Prepare to start Routine "thanks"-------
t = 0
thanksClock.reset()  # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
# setup some python lists for storing info about the mouse
gotValidClick = False  # until a click is received
# keep track of which components have finished
thanksComponents = [text_3, mouse]
for thisComponent in thanksComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

# -------Start Routine "thanks"-------
while continueRoutine:
    # get current time
    t = thanksClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    
    # *text_3* updates
    if t >= 0.0 and text_3.status == NOT_STARTED:
        # keep track of start time/frame for later
        text_3.tStart = t
        text_3.frameNStart = frameN  # exact frame index
        text_3.setAutoDraw(True)
    # *mouse* updates
    if t >= 0.0 and mouse.status == NOT_STARTED:
        # keep track of start time/frame for later
        mouse.tStart = t
        mouse.frameNStart = frameN  # exact frame index
        mouse.status = STARTED
        prevButtonState = mouse.getPressed()  # if button is down already this ISN'T a new click
    if mouse.status == STARTED:  # only update if started and not stopped!
        buttons = mouse.getPressed()
        if buttons != prevButtonState:  # button state changed?
            prevButtonState = buttons
            if sum(buttons) > 0:  # state changed to a new click
                # abort routine on response
                continueRoutine = False
    
    # check if all components have finished
    if not continueRoutine:  # a component has requested a forced-end of Routine
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in thanksComponents:
        if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
            continueRoutine = True
            break  # at least one component has not yet finished
    
    # check for quit (the Esc key)
    if endExpNow or event.getKeys(keyList=["escape"]):
        core.quit()
    
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()

# -------Ending Routine "thanks"-------
for thisComponent in thanksComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# store data for thisExp (ExperimentHandler)
thisExp.nextEntry()
# the Routine "thanks" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()



# these shouldn't be strictly necessary (should auto-save)
thisExp.saveAsWideText(filename+'.csv')
thisExp.saveAsPickle(filename)
logging.flush()
# make sure everything is closed down
thisExp.abort()  # or data files will save again on exit
win.close()
core.quit()

had to break it up because of post limits
credits and how to site is still in my prog :slight_smile: but I took that out to try to fit the code in 1-2 chunks in this post

Hi @Miss_Egg, it is possible the error may originate in this line of code.

1 = self.Audio should throw a syntax error because you cant assign values to integers like that. This error does not appear in my current working version of PsychoPy or other versions of 1.90 on Github. You could correct this error by replacing the relevant code in movie3.py with:

audio=(1-self.noAudio)

If that does not work please let us know.

@Miss_Egg, (your coworker here)

I think I found the problem with the
> OSError: [WinError 6] The handle is invalid
issue. This error is also posted in SO
Getting “OSError: [WinError 6] The handle is invalid” in VideoFileClip function

8
down vote
I solved the issue by running the following commands after reading the video.

video_clip.reader.close()
video_clip.audio.reader.close_proc()
See https://github.com/Zulko/moviepy/issues/73 and https://github.com/Zulko/moviepy/issues/164.

The problem is that MovieStim3 is not properly closing the video in MovieStim3._unload(). All I did was add a .close() in the _unload function in movie3.py

    def _unload(self):
        try:
            # remove textures from graphics card to prevent crash
            self.clearTextures()
        except Exception:
            pass
        self._mov.close()
        self._mov = None
        self._numpyFrame = None
        self._audioStream = None
        self.status = FINISHED

@dvbridges Thank you for your feedback. I went back after looking at the standalone version downloaded, and I do not see that code with the syntax error from the traceback messages anymore. I am still getting the Fatal Python Error though. It seems to not be affecting the datalogging or experience with the program. Ideally, it would be nice to figure out what is going on, but is there a way to hide any traceback messages from popping up?

@tjwilli58 I remember seeing that post on github, but I definitely did not implement the close correctly. I can’t believe that this add was all that was needed to a different file. Thank you for writing about the fix very clearly :open_mouth:!!

I opened an issue (#1915) on GitHub on this.