OS: Windows 10
PsychoPy version 2023.2.3 Py 3.8
Do you want it to also run online? (y/n) No
What are you trying to achieve?: Playing multiple videos in the same routine.
What did you try to make it work?: In a Similarity Judgement Task, there is a Target Video presented in the center of the screen. Then, a fixation cross during 1 second. After that, two videos should display at the same time, one at left and other one at right of the screen. Participants must decide which one is more similar to the Target pressing lelft/right mouse buttons.
var Training_trials;
function Training_trialsLoopBegin(Training_trialsLoopScheduler, snapshot) {
return async function() {
TrialHandler.fromSnapshot(snapshot); // update internal variables (.thisN etc) of the loop
// set up handler to look after randomisation of conditions etc
Training_trials = new TrialHandler({
psychoJS: psychoJS,
nReps: 1, method: TrialHandler.Method.SEQUENTIAL,
extraInfo: expInfo, originPath: undefined,
trialList: 'Examples.xlsx',
seed: undefined, name: 'Training_trials'
});
psychoJS.experiment.addLoop(Training_trials); // add the loop to the experiment
currentLoop = Training_trials; // we're now the current loop
// Schedule all the trials in the trialList:
for (const thisTraining_trial of Training_trials) {
snapshot = Training_trials.getSnapshot();
Training_trialsLoopScheduler.add(importConditions(snapshot));
Training_trialsLoopScheduler.add(TrainingRoutineBegin(snapshot));
Training_trialsLoopScheduler.add(TrainingRoutineEachFrame());
Training_trialsLoopScheduler.add(TrainingRoutineEnd(snapshot));
Training_trialsLoopScheduler.add(Training_trialsLoopEndIteration(Training_trialsLoopScheduler, snapshot));
}
return Scheduler.Event.NEXT;
}
}
async function Training_trialsLoopEnd() {
// terminate loop
psychoJS.experiment.removeLoop(Training_trials);
// update the current loop from the ExperimentHandler
if (psychoJS.experiment._unfinishedLoops.length>0)
currentLoop = psychoJS.experiment._unfinishedLoops.at(-1);
else
currentLoop = psychoJS.experiment; // so we use addData from the experiment
return Scheduler.Event.NEXT;
}
function Training_trialsLoopEndIteration(scheduler, snapshot) {
// ------Prepare for next entry------
return async function () {
if (typeof snapshot !== ‘undefined’) {
// ------Check if user ended loop early------
if (snapshot.finished) {
// Check for and save orphaned data
if (psychoJS.experiment.isEntryEmpty()) {
psychoJS.experiment.nextEntry(snapshot);
}
scheduler.stop();
} else {
psychoJS.experiment.nextEntry(snapshot);
}
return Scheduler.Event.NEXT;
}
};
}
var TrainingComponents;
function TrainingRoutineBegin(snapshot) {
return async function () {
TrialHandler.fromSnapshot(snapshot); // ensure that .thisN vals are up to date
//--- Prepare to start Routine 'Training' ---
t = 0;
TrainingClock.reset(); // clock
frameN = -1;
continueRoutine = true; // until we're told otherwise
// update component parameters for each repeat
psychoJS.experiment.addData('Training.started', globalClock.getTime());
sound_1.secs=1.0;
sound_1.setVolume(1.0);
TrainingPrime.setMovie(Video_Example);
TrainingRight.setMovie(Video_Ex_Right);
TrainingLeft.setMovie(Video_Ex_Left);
// setup some python lists for storing info about the mouse_2
// current position of the mouse:
mouse_2.x = [];
mouse_2.y = [];
mouse_2.leftButton = [];
mouse_2.midButton = [];
mouse_2.rightButton = [];
mouse_2.time = [];
gotValidClick = false; // until a click is received
mouse_2.mouseClock.reset();
// keep track of which components have finished
TrainingComponents = [];
TrainingComponents.push(Cross1);
TrainingComponents.push(sound_1);
TrainingComponents.push(TrainingPrime);
TrainingComponents.push(Cross2);
TrainingComponents.push(TrainingRight);
TrainingComponents.push(TrainingLeft);
TrainingComponents.push(mouse_2);
for (const thisComponent of TrainingComponents)
if ('status' in thisComponent)
thisComponent.status = PsychoJS.Status.NOT_STARTED;
return Scheduler.Event.NEXT;
}
}
var frameRemains;
function TrainingRoutineEachFrame() {
return async function () {
//— Loop for each frame of Routine ‘Training’ —
// get current time
t = TrainingClock.getTime();
frameN = frameN + 1;// number of completed frames (so 0 is the first frame)
// update/draw components on each frame
// *Cross1* updates
if (t >= 0.0 && Cross1.status === PsychoJS.Status.NOT_STARTED) {
// keep track of start time/frame for later
Cross1.tStart = t; // (not accounting for frame time here)
Cross1.frameNStart = frameN; // exact frame index
Cross1.setAutoDraw(true);
}
frameRemains = 0.0 + 1.0 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
if (Cross1.status === PsychoJS.Status.STARTED && t >= frameRemains) {
Cross1.setAutoDraw(false);
}
// start/stop sound_1
if (t >= 0.0 && sound_1.status === PsychoJS.Status.NOT_STARTED) {
// keep track of start time/frame for later
sound_1.tStart = t; // (not accounting for frame time here)
sound_1.frameNStart = frameN; // exact frame index
psychoJS.window.callOnFlip(function(){ sound_1.play(); }); // screen flip
sound_1.status = PsychoJS.Status.STARTED;
}
frameRemains = 0.0 + 1.0 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
if (sound_1.status === PsychoJS.Status.STARTED && t >= frameRemains) {
if (t >= sound_1.tStart + 0.5) {
sound_1.stop(); // stop the sound (if longer than duration)
sound_1.status = PsychoJS.Status.FINISHED;
}
}
// *TrainingPrime* updates
if (t >= 1 && TrainingPrime.status === PsychoJS.Status.NOT_STARTED) {
// keep track of start time/frame for later
TrainingPrime.tStart = t; // (not accounting for frame time here)
TrainingPrime.frameNStart = frameN; // exact frame index
TrainingPrime.setAutoDraw(true);
TrainingPrime.play();
}
frameRemains = 1 + 5.5 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
if (TrainingPrime.status === PsychoJS.Status.STARTED && t >= frameRemains) {
TrainingPrime.setAutoDraw(false);
}
// *Cross2* updates
if (t >= 6.5 && Cross2.status === PsychoJS.Status.NOT_STARTED) {
// keep track of start time/frame for later
Cross2.tStart = t; // (not accounting for frame time here)
Cross2.frameNStart = frameN; // exact frame index
Cross2.setAutoDraw(true);
}
frameRemains = 6.5 + 1.0 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
if (Cross2.status === PsychoJS.Status.STARTED && t >= frameRemains) {
Cross2.setAutoDraw(false);
}
// *TrainingRight* updates
if (t >= 7.5 && TrainingRight.status === PsychoJS.Status.NOT_STARTED) {
// keep track of start time/frame for later
TrainingRight.tStart = t; // (not accounting for frame time here)
TrainingRight.frameNStart = frameN; // exact frame index
TrainingRight.setAutoDraw(true);
TrainingRight.play();
}
frameRemains = 7.5 + 7.5 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
if (TrainingRight.status === PsychoJS.Status.STARTED && t >= frameRemains) {
TrainingRight.setAutoDraw(false);
}
// *TrainingLeft* updates
if (t >= 7.5 && TrainingLeft.status === PsychoJS.Status.NOT_STARTED) {
// keep track of start time/frame for later
TrainingLeft.tStart = t; // (not accounting for frame time here)
TrainingLeft.frameNStart = frameN; // exact frame index
TrainingLeft.setAutoDraw(true);
TrainingLeft.play();
}
frameRemains = 7.5 + 7.5 - psychoJS.window.monitorFramePeriod * 0.75; // most of one frame period left
if (TrainingLeft.status === PsychoJS.Status.STARTED && t >= frameRemains) {
TrainingLeft.setAutoDraw(false);
}
// *mouse_2* updates
if (t >= 7.5 && mouse_2.status === PsychoJS.Status.NOT_STARTED) {
// keep track of start time/frame for later
mouse_2.tStart = t; // (not accounting for frame time here)
mouse_2.frameNStart = frameN; // exact frame index
mouse_2.status = PsychoJS.Status.STARTED;
prevButtonState = mouse_2.getPressed(); // if button is down already this ISN'T a new click
}
if (mouse_2.status === PsychoJS.Status.STARTED) { // only update if started and not finished!
_mouseButtons = mouse_2.getPressed();
if (!_mouseButtons.every( (e,i,) => (e == prevButtonState[i]) )) { // button state changed?
prevButtonState = _mouseButtons;
if (_mouseButtons.reduce( (e, acc) => (e+acc) ) > 0) { // state changed to a new click
_mouseXYs = mouse_2.getPos();
mouse_2.x.push(_mouseXYs[0]);
mouse_2.y.push(_mouseXYs[1]);
mouse_2.leftButton.push(_mouseButtons[0]);
mouse_2.midButton.push(_mouseButtons[1]);
mouse_2.rightButton.push(_mouseButtons[2]);
mouse_2.time.push(mouse_2.mouseClock.getTime());
// end routine on response
continueRoutine = false;
}
}
}
// check for quit (typically the Esc key)
if (psychoJS.experiment.experimentEnded || psychoJS.eventManager.getKeys({keyList:['escape']}).length > 0) {
return quitPsychoJS('The [Escape] key was pressed. Goodbye!', false);
}
// check if the Routine should terminate
if (!continueRoutine) { // a component has requested a forced-end of Routine
return Scheduler.Event.NEXT;
}
continueRoutine = false; // reverts to True if at least one component still running
for (const thisComponent of TrainingComponents)
if ('status' in thisComponent && thisComponent.status !== PsychoJS.Status.FINISHED) {
continueRoutine = true;
break;
}
// refresh the screen if continuing
if (continueRoutine) {
return Scheduler.Event.FLIP_REPEAT;
} else {
return Scheduler.Event.NEXT;
}
};
}
function TrainingRoutineEnd(snapshot) {
return async function () {
//— Ending Routine ‘Training’ —
for (const thisComponent of TrainingComponents) {
if (typeof thisComponent.setAutoDraw === ‘function’) {
thisComponent.setAutoDraw(false);
}
}
psychoJS.experiment.addData(‘Training.stopped’, globalClock.getTime());
sound_1.stop(); // ensure sound has stopped at end of Routine
TrainingPrime.stop(); // ensure movie has stopped at end of Routine
TrainingRight.stop(); // ensure movie has stopped at end of Routine
TrainingLeft.stop(); // ensure movie has stopped at end of Routine
// store data for psychoJS.experiment (ExperimentHandler)
if (mouse_2.x) { psychoJS.experiment.addData(‘mouse_2.x’, mouse_2.x[0])};
if (mouse_2.y) { psychoJS.experiment.addData(‘mouse_2.y’, mouse_2.y[0])};
if (mouse_2.leftButton) { psychoJS.experiment.addData(‘mouse_2.leftButton’, mouse_2.leftButton[0])};
if (mouse_2.midButton) { psychoJS.experiment.addData(‘mouse_2.midButton’, mouse_2.midButton[0])};
if (mouse_2.rightButton) { psychoJS.experiment.addData(‘mouse_2.rightButton’, mouse_2.rightButton[0])};
if (mouse_2.time) { psychoJS.experiment.addData(‘mouse_2.time’, mouse_2.time[0])};
// the Routine "Training" was not non-slip safe, so reset the non-slip timer
routineTimer.reset();
// Routines running outside a loop should always advance the datafile row
if (currentLoop === psychoJS.experiment) {
psychoJS.experiment.nextEntry(snapshot);
}
return Scheduler.Event.NEXT;
}
}
function importConditions(currentLoop) {
return async function () {
psychoJS.importAttributes(currentLoop.getCurrentTrial());
return Scheduler.Event.NEXT;
};
}
async function quitPsychoJS(message, isCompleted) {
// Check for and save orphaned data
if (psychoJS.experiment.isEntryEmpty()) {
psychoJS.experiment.nextEntry();
}
// Run ‘End Experiment’ code from code
psychoJS.window.mouseVisible = true;
psychoJS.window.close();
psychoJS.quit({message: message, isCompleted: isCompleted});
return Scheduler.Event.QUIT;
}
**What specifically went wrong when you tried that?: The experiment crashes after the fixation cross. There is no problem in the format of the videos because they display well when they are presented alone in the routine (if I temporally disability TrainingRight and TrainingLeft).
File “C:\Program Files\PsychoPy\lib\site-packages\psychopy\visual\movie3.py”, line 388, in _updateFrameTexture
self._numpyFrame = self._mov.get_frame(self._nextFrameT)
File “”, line 2, in get_frame
File “C:\Program Files\PsychoPy\lib\site-packages\moviepy\decorators.py”, line 89, in wrapper
return f(*new_a, **new_kw)
File “C:\Program Files\PsychoPy\lib\site-packages\moviepy\Clip.py”, line 93, in get_frame
return self.make_frame(t)
File “C:\Program Files\PsychoPy\lib\site-packages\moviepy\video\io\VideoFileClip.py”, line 113, in
self.make_frame = lambda t: self.reader.get_frame(t)
File “C:\Program Files\PsychoPy\lib\site-packages\moviepy\video\io\ffmpeg_reader.py”, line 184, in get_frame
result = self.read_frame()
File “C:\Program Files\PsychoPy\lib\site-packages\moviepy\video\io\ffmpeg_reader.py”, line 133, in read_frame
raise IOError(("MoviePy error: failed to read the first frame of "
OSError: MoviePy error: failed to read the first frame of video file resources/43.mp4. That might mean that the file is corrupted. That may also mean that you are using a deprecated version of FFMPEG. On Ubuntu/Debian for instance the version in the repos is deprecated. Please update to a recent version from the website.