PsychoPy Stops Running after Playing Video (MovieStim)

Hi All,

I am trying to play a video and then have participants describe what happened during the video. As of right now, the video (as a MovieStim) plays through the first time, but then won’t allow the program to move forward. If one presses the continue button while the video is playing, the program moves forward without issue. However, if the video is allowed to play through until the end, the continue button no longer works. I think there’s a flaw in my logic somewhere, and if anyone would be willing to read through my code so far I’d really appreciate it!

Thank you,

Paige

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


from __future__ import absolute_import, division
from psychopy import locale_setup, gui, visual, core, data, event, logging, sound
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 = u'WGO'  # from the Builder filename that created this script
expInfo = {'participant':'', 'session':'001'}
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=u'C:\\Users\\Paige\\Desktop\\Lab\\WGO.psyexp',
    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=(1536, 864), fullscr=True, screen=0,
allowGUI=False, allowStencil=False,
monitor='testMonitor', color=[0,0,0], colorSpace='rgb',
blendMode='avg', useFBO=True)
# 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 "Intro"
trialClock = core.Clock()
polygon = visual.Rect(
    win=win, name='polygon',
    width=(0.4, 0.4)[0], height=(0.4, 0.4)[1],
    ori=0, pos=(0, -.5),
    lineWidth=1, lineColor=[1,1,1], lineColorSpace='rgb',
    fillColor=[1,1,1], fillColorSpace='rgb',
    opacity=1, depth=-1.0, interpolate=True)
text = visual.TextStim(win=win, name='text',
    text=u' We are interested in what you think is happening in each video. There are no right or wrong answers.',
    font=u'Arial',
    pos=(0, .3), height=0.1, wrapWidth=None, ori=0, 
    color=u'white', colorSpace='rgb', opacity=1,
    depth=0.0);
continue_text = visual.TextStim(win=win, name='text',
    text=u'Continue',
    font=u'Arial',
    pos=(0, -.50), height=0.1, wrapWidth=None, ori=0, 
    color=u'black', colorSpace='rgb', opacity=1,
    depth=-3.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 "Intro"-------
t = 0
trialClock.reset()  # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
# keep track of which components have finished
trialComponents = [text, mouse, polygon]
for thisComponent in trialComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

# -------Start Routine "Intro"-------
while continueRoutine:
    # get current time
    t = trialClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame

    # *polygon* updates
    if t >= 0.0 and polygon.status == NOT_STARTED:
        # keep track of start time/frame for later
        polygon.tStart = t
        polygon.frameNStart = frameN  # exact frame index
        polygon.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)
    # *continue_text* updates
    if t >= 0.0 and continue_text.status == NOT_STARTED:
        # keep track of start time/frame for later
        continue_text.tStart = t
        continue_text.frameNStart = frameN  # exact frame index
        continue_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 trialComponents:
        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()
    
    # Move on once participant has read instructions
    if mouse.isPressedIn(polygon) :
        continueRoutine = False
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()

# -------Ending Routine "Intro"-------
for thisComponent in trialComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# the Routine "Intro" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
mouse = event.Mouse(win=win)
x, y = [None, None]
continueRoutine = True 

# ------Prepare to start Routine "Instr1"-------
t = 0
trialClock.reset()  # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
# keep track of which components have finished
trialComponents = [text, polygon, mouse, continue_text]
text.setText('There will be X trials. On each trial, you will see a short video. Please watch the video until it stops     playing. When the video stops playing, you will see a small box into which you can type. Please give a brief explanation     of what you think happened in the video.')
for thisComponent in trialComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

continueRoutine = True 
# -------Start Routine "Instr1"-------
while continueRoutine:
    # get current time
    t = trialClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    # *polygon* updates
    if t >= 0.0 and polygon.status == NOT_STARTED:
        # keep track of start time/frame for later
        polygon.tStart = t
        polygon.frameNStart = frameN  # exact frame index
        polygon.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)
# *continue_text* updates
if t >= 0.0 and continue_text.status == NOT_STARTED:
    # keep track of start time/frame for later
    continue_text.tStart = t
    continue_text.frameNStart = frameN  # exact frame index
    continue_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 trialComponents:
    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()
# Move on once participant has read instructions
if mouse.isPressedIn(polygon) :
    continueRoutine = False
# refresh the screen
if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
    win.flip()

# -------Ending Routine "Instr1"-------
for thisComponent in trialComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# the Routine "Intro" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
mouse = event.Mouse(win=win)
x, y = [None, None]
continueRoutine = True 


#------Prepare to start Routine "Instr2"-------
t = 0
trialClock.reset()  # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
# keep track of which components have finished
trialComponents = [text, polygon, mouse, continue_text]
text.setText('Remember, there are no right or wrong answers. Please press continue when you are ready to begin     watching the first video.')
for thisComponent in trialComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

# -------Start Routine "Instr2"-------
while continueRoutine:
    # get current time
    t = trialClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    # *polygon* updates
    if t >= 0.0 and polygon.status == NOT_STARTED:
        # keep track of start time/frame for later
        polygon.tStart = t
        polygon.frameNStart = frameN  # exact frame index
        polygon.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)
    # *continue_text* updates
    if t >= 0.0 and continue_text.status == NOT_STARTED:
        # keep track of start time/frame for later
        continue_text.tStart = t
        continue_text.frameNStart = frameN  # exact frame index
            continue_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 trialComponents:
        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()
    # Move on once participant has read instructions
    if mouse.isPressedIn(polygon) :
        continueRoutine = False
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()

# -------Ending Routine "Instr2"-------
for thisComponent in trialComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# the Routine "Intro" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
mouse = event.Mouse(win=win)
x, y = [None, None]
continueRoutine = True 


# Initialize components for Routine "Trial1"

mov = visual.MovieStim(win, 'A.mp4', pos=(0.0, 150), flipVert=False)
mov.size= (960, 540)


#------Prepare to start Routine "Trial1"-------
t = 0
trialClock.reset()  # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
# keep track of which components have finished
trialComponents = [text, polygon, mov, mouse, continue_text]
text.setText('Trial 1 text')
for thisComponent in trialComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED


# -------Start Routine "Trial1"-------
while continueRoutine:
    # get current time
    t = trialClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    # *polygon* updates
    if t >= 0.0 and polygon.status == NOT_STARTED:
        # keep track of start time/frame for later
        polygon.tStart = t
        polygon.frameNStart = frameN  # exact frame index
        polygon.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)
    # *continue_text* updates
    if t >= 0.0 and continue_text.status == NOT_STARTED:
        # keep track of start time/frame for later
        continue_text.tStart = t
        continue_text.frameNStart = frameN  # exact frame index
        continue_text.setAutoDraw(True)
    # *mov* updates
    if t >= 0.0 and mov.status == NOT_STARTED:
        # keep track of start time/frame for later
        text.tStart = t
        text.frameNStart = frameN  # exact frame index
        mov.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  I think the problem may be here
    for thisComponent in trialComponents:
        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()
    # Move on once participant has read instructions
     if mouse.isPressedIn(polygon) :
         print"was pressed" 
         continueRoutine = False
   # refresh the screen
     if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
         win.flip()

print"line 365"

# -------Ending Routine "Trial1"-------
for thisComponent in trialComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# the Routine "Trial1" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
mouse = event.Mouse(win=win)
x, y = [None, None]
continueRoutine = True 

print"line 377"



# Initialize components for Routine "Trial2"

mov = visual.MovieStim(win, 'B.mp4', pos=(0.0, 150), flipVert=False)
mov.size= (960, 540)


#------Prepare to start Routine "Trial2"-------
t = 0
trialClock.reset()  # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
# keep track of which components have finished
trialComponents = [text, polygon, mov, mouse, continue_text]
text.setText('Trial 2 text')
for thisComponent in trialComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED


# -------Start Routine "Trial2"-------
while continueRoutine:
    # get current time
    t = trialClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    # *polygon* updates
    if t >= 0.0 and polygon.status == NOT_STARTED:
        # keep track of start time/frame for later
        polygon.tStart = t
        polygon.frameNStart = frameN  # exact frame index
        polygon.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)
    # *continue_text* updates
    if t >= 0.0 and continue_text.status == NOT_STARTED:
        # keep track of start time/frame for later
        continue_text.tStart = t
        continue_text.frameNStart = frameN  # exact frame index
        continue_text.setAutoDraw(True)
    # *mov* updates
    if t >= 0.0 and mov.status == NOT_STARTED:
        # keep track of start time/frame for later
        text.tStart = t
        text.frameNStart = frameN  # exact frame index
        mov.setAutoDraw(True)
    if mouse.isPressedIn(mov):
        mov.play()
    # check if all components have finished new to see if movie is registering as unfinished. did not change anything. 
    if mov.status == FINISHED:
        break
    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 trialComponents:
        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()
    # Move on once participant has read instructions
    if mouse.isPressedIn(polygon) :
        print"was pressed" 
        continueRoutine = False
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()

print"line 365"

# -------Ending Routine "Trial2"-------
for thisComponent in trialComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# the Routine "Trial1" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
mouse = event.Mouse(win=win)
x, y = [None, None]
continueRoutine = True 






# 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()

Hi Paige,

I’m not sure, but there might have been a bit of copy/paste fatigue going on here:

# *mov* updates
    if t >= 0.0 and mov.status == NOT_STARTED:
        # keep track of start time/frame for later
        text.tStart = t
        text.frameNStart = frameN  # exact frame index
        mov.setAutoDraw(True)

i.e. you are setting the tStart and frameNStart attributes of the text stimulus again, rather than the movie stimulus. I don’t really know how Builder-style code works in determining whether a stimulus has finished, but maybe those attributes are used for that?

Cheers,

Michael

PS rather than having to wade through an entire experiment of code (particularly the verbose style that Builder generates), it is useful to just post the relevant sections.

Hi Michael,

Thank you for the suggestions! I fixed the ‘mov updates’ section, but unfortunately the problem remains. My hunch is that mov.status never equals FINISHED or visual.FINISHED. Because of this, the loop continues forever and the program cannot move forward. Based on the code I found here I assumed that mov.status will update to finished once the video is done playing. However, that doesn’t seem to happen. Does the status need to be manually changed?

Again, any suggestions or relevant website/examples would be appreciated.

Thank you!

Paige

#------Prepare to start Routine "Trial1"-------
t = 0
trialClock.reset()  # clock
frameN = -1
continueRoutine = True
trialComponents = [text, polygon, mov, mouse, continue_text]
text.setText('Trial 1 text')
for thisComponent in trialComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED


# -------Start Routine "Trial1"-------
while continueRoutine:
    t = trialClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    # *polygon*  updates
    if t >= 0.0 and polygon.status == NOT_STARTED:
        # keep track of start time/frame for later
        polygon.tStart = t
        polygon.frameNStart = frameN  
        polygon.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  
        text.setAutoDraw(True)
    # *continue_text*  updates
    if t >= 0.0 and continue_text.status == NOT_STARTED:
        # keep track of start time/frame for later
        continue_text.tStart = t
        continue_text.frameNStart = frameN  
        continue_text.setAutoDraw(True)
    # *mov*  updates
    if t >= 0.0 and mov.status == NOT_STARTED:
        # keep track of start time/frame for later, happens
        mov.tStart = t
        mov.frameNStart = frameN  
        mov.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
    if mov.status == visual.FINISHED:
        continueRoutine = False
        print('mov.status equals vis.fin') # never prints, so the movie never finishes?
    for thisComponent in trialComponents:
        if hasattr(thisComponent, "status") and thisComponent.status != FINISHED or thisComponent.status!=visual.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()
# Move on once participant has read instructions
if mouse.isPressedIn(polygon) :
    continueRoutine = False
if continueRoutine: 
    win.flip()