Hello everyone,
I am trying to write a code where participants can adjust the speed of a video by pressing the keys. For example, for a small decrease in the speed (let’s say 0.1 unit), they should press ‘y’, or for a large increment (0.3), they should press ‘a’. After each key press, I want the newly adjusted video to be seen on the screen so that participants can decide if it is proper or if they want to change the speed again and again. After they are sure, they should press the right arrow to move to the next video. The trick is that I want to use the same video, but each time, they will see it with a different playback speed/rate. So, each time when the next video is shown on the screen, it should be the same one with a different playback rate. Then, I need to save the initial playback rate and the final one only. I want to keep the playback rate between 0.1 and 5.0. So far, I have not been able to refresh the video with the key press.
Here is some part of my code
…
— Initialize components for Routine “exp_trial” —
movie_files = visual.MovieStim(
win, name='movie_files',
filename=None, movieLib='ffpyplayer',
loop=True, volume=1.0, noAudio=False,
pos=(0, 0), size=(43.46, 24.45), units='deg',
ori=0.0, anchor='center',opacity=None, contrast=1.0,
depth=0
)
trial_key_resp = keyboard.Keyboard(deviceName='trial_key_resp')
trial_inst_text = visual.TextStim(win=win, name='trial_inst_text',
text='Press A or S for large decrement or increment. \nPress Y or X for a small decrement or increment.',
font='Arial',
pos=(0, 0.40), height=0.03, wrapWidth=None, ori=0.0,
color='white', colorSpace='rgb', opacity=None,
languageStyle='LTR',
depth=-2.0);
answer_key_resp = keyboard.Keyboard(deviceName='answer_key_resp')
…
set up handler to look after randomisation of conditions etc
trial_loop = data.TrialHandler(nReps=1.0, method='random',
extraInfo=expInfo, originPath=-1,
trialList=data.importConditions('trialExp.xlsx'),
seed=None, name='trial_loop')
thisExp.addLoop(trial_loop) # add the loop to the experiment
thisTrial_loop = trial_loop.trialList[0] # so we can initialise stimuli with some values
# abbreviate parameter names if possible (e.g. rgb = thisTrial_loop.rgb)
if thisTrial_loop != None:
for paramName in thisTrial_loop:
globals()[paramName] = thisTrial_loop[paramName]
for thisTrial_loop in trial_loop:
currentLoop = trial_loop
thisExp.timestampOnFlip(win, 'thisRow.t', format=globalClock.format)
# pause experiment here if requested
if thisExp.status == PAUSED:
pauseExperiment(
thisExp=thisExp,
win=win,
timers=[routineTimer],
playbackComponents=[]
)
# abbreviate parameter names if possible (e.g. rgb = thisTrial_loop.rgb)
if thisTrial_loop != None:
for paramName in thisTrial_loop:
globals()[paramName] = thisTrial_loop[paramName]
# Initialize playback speed
speeds = np.arange(0.1,5.1,0.1)
video_file = trial_videos # Assuming trial_videos is a single video file path string
large_step = 3
small_step = 1
# --- Prepare to start Routine "exp_trial" ---
continueRoutine = True
# update component parameters for each repeat
thisExp.addData('exp_trial.started', globalClock.getTime(format='float'))
# Load the movie file and set playback rate
playback_speed = np.random.choice(speeds)
movie_files.setMovie(video_file)
movie_files.rate = playback_speed
movie_files.play()
trial_key_resp.keys = []
trial_key_resp.rt = []
_trial_key_resp_allKeys = []
answer_key_resp.keys = []
answer_key_resp.rt = []
_answer_key_resp_allKeys = []
# keep track of which components have finished
exp_trialComponents = [movie_files, trial_key_resp, trial_inst_text, answer_key_resp]
for thisComponent in exp_trialComponents:
thisComponent.tStart = None
thisComponent.tStop = None
thisComponent.tStartRefresh = None
thisComponent.tStopRefresh = None
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED
# reset timers
t = 0
_timeToFirstFrame = win.getFutureFlipTime(clock="now")
frameN = -1
# --- Run Routine "exp_trial" ---
routineForceEnded = not continueRoutine
while continueRoutine:
# get current time
t = routineTimer.getTime()
tThisFlip = win.getFutureFlipTime(clock=routineTimer)
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)
# update/draw components on each frame
# *movie_files* updates
# if movie_files is starting this frame...
if movie_files.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
movie_files.frameNStart = frameN # exact frame index
movie_files.tStart = t # local t and not account for scr refresh
movie_files.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(movie_files, 'tStartRefresh') # time at next scr refresh
# add timestamp to datafile
thisExp.timestampOnFlip(win, 'movie_files.started')
# update status
movie_files.status = STARTED
movie_files.setAutoDraw(True)
movie_files.play()
# *trial_key_resp* updates
waitOnFlip = False
# if trial_key_resp is starting this frame...
if trial_key_resp.status == NOT_STARTED and tThisFlip >= 2.0-frameTolerance:
# keep track of start time/frame for later
trial_key_resp.frameNStart = frameN # exact frame index
trial_key_resp.tStart = t # local t and not account for scr refresh
trial_key_resp.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(trial_key_resp, 'tStartRefresh') # time at next scr refresh
# update status
trial_key_resp.status = STARTED
# keyboard checking is just starting
waitOnFlip = True
win.callOnFlip(trial_key_resp.clock.reset) # t=0 on next screen flip
win.callOnFlip(trial_key_resp.clearEvents, eventType='keyboard') # clear events on next screen flip
if trial_key_resp.status == STARTED and not waitOnFlip:
theseKeys = trial_key_resp.getKeys(keyList=['right'], ignoreKeys=["escape"], waitRelease=False)
_trial_key_resp_allKeys.extend(theseKeys)
if len(_trial_key_resp_allKeys):
trial_key_resp.keys = _trial_key_resp_allKeys[-1].name # just the last key pressed
trial_key_resp.rt = _trial_key_resp_allKeys[-1].rt
trial_key_resp.duration = _trial_key_resp_allKeys[-1].duration
# a response ends the routine
continueRoutine = False
# *trial_inst_text* updates
# if trial_inst_text is starting this frame...
if trial_inst_text.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
# keep track of start time/frame for later
trial_inst_text.frameNStart = frameN # exact frame index
trial_inst_text.tStart = t # local t and not account for scr refresh
trial_inst_text.tStartRefresh = tThisFlipGlobal # on global time
win.timeOnFlip(trial_inst_text, 'tStartRefresh') # time at next scr refresh
# add timestamp to datafile
thisExp.timestampOnFlip(win, 'trial_inst_text.started')
# update status
trial_inst_text.status = STARTED
trial_inst_text.setAutoDraw(True)
# if trial_inst_text is active this frame...
if trial_inst_text.status == STARTED:
# update params
pass
# *answer_key_resp* updates
waitOnFlip = False
# if answer_key_resp is starting this frame...
if answer_key_resp.status == NOT_STARTED and tThisFlip >= 0.0 - frameTolerance:
answer_key_resp.frameNStart = frameN
answer_key_resp.tStart = t
answer_key_resp.tStartRefresh = tThisFlipGlobal
win.timeOnFlip(answer_key_resp, 'tStartRefresh')
thisExp.timestampOnFlip(win, 'answer_key_resp.started')
answer_key_resp.status = STARTED
waitOnFlip = True
win.callOnFlip(answer_key_resp.clock.reset)
win.callOnFlip(answer_key_resp.clearEvents, eventType='keyboard')
if trial_key_resp.status == STARTED and not waitOnFlip:
keys = event.getKeys(['a', 's', 'y', 'x', 'right'])
if keys:
key = keys[0] # just the first key pressed
if key == 'a': # large decrement
playback_speed = max(0, playback_speed - large_step)
elif key == 's': # large increment
playback_speed = min(5.1, playback_speed + large_step)
elif key == 'y': # small decrement
playback_speed = max(0, playback_speed - small_step)
elif key == 'x': # small increment
playback_speed = min(5.1, playback_speed + small_step)
elif key == 'right': # Proceed to next video
continueRoutine = False
# Update the playback speed immediately
playback_rate = playback_speed
# Start playing the video
movie_files.setMovie(video_file)
movie_files.rate = playback_rate
movie_files.play()
# Refresh the screen
win.flip()
# check for quit (typically the Esc key)
if defaultKeyboard.getKeys(keyList=["escape"]):
thisExp.status = FINISHED
if thisExp.status == FINISHED or endExpNow:
endExperiment(thisExp, win=win)
return
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
routineForceEnded = True
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in exp_trialComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
# --- Ending Routine "exp_trial" ---
for thisComponent in exp_trialComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
thisExp.addData('exp_trial.stopped', globalClock.getTime(format='float'))
movie_files.stop() # ensure movie has stopped at end of Routine
# check responses
if trial_key_resp.keys in ['', [], None]: # No response was made
trial_key_resp.keys = None
trial_loop.addData('trial_key_resp.keys',trial_key_resp.keys)
if trial_key_resp.keys != None: # we had a response
trial_loop.addData('trial_key_resp.rt', trial_key_resp.rt)
trial_loop.addData('trial_key_resp.duration', trial_key_resp.duration)
if answer_key_resp.keys in ['', [], None]: # No response was made
answer_key_resp.keys = None
trial_loop.addData('answer_key_resp.keys',answer_key_resp.keys)
trial_loop.addData('updated_speed', playback_speed)
if answer_key_resp.keys != None: # we had a response
trial_loop.addData('answer_key_resp.rt', answer_key_resp.rt)
trial_loop.addData('answer_key_resp.duration', answer_key_resp.duration)
# the Routine "exp_trial" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()