Note
Go to the end to download the full example code.
Video property control#
This shows how to control various properties of a video file in expyfun.
@author: drmccloy
exp_name: advanced video example
date: 2024-12-23 22_40_42.399697
file: /home/circleci/project/examples/stimuli/advanced_video.py
participant: foo
session: foo
2024-12-23 22:40:42,399 - INFO - Expyfun: Using version 2.0.0.dev0 (requested dev)
2024-12-23 22:40:42,400 - INFO - Expyfun: Setting up sound card using pyglet backend with 2 playback channels
2024-12-23 22:40:42,561 - WARNING - Expyfun: Mismatch between reported stim sample rate (24414) and device sample rate (44100.0). Experiment Controller will resample for you, but this takes a non-trivial amount of processing time and may compromise your experimental timing and/or cause artifacts.
2024-12-23 22:40:42,561 - INFO - Expyfun: Setting up screen
2024-12-23 22:40:42,590 - EXP - Expyfun: Set screen visibility True
2024-12-23 22:40:42,600 - INFO - Initialized [720 480] window on screen XlibScreen(display=<pyglet.canvas.xlib.XlibDisplay object at 0x7f3a26f69ed0>, x=0, y=0, width=1400, height=900, xinerama=0) with DPI 69.73
2024-12-23 22:40:42,601 - INFO - Expyfun: Initializing dummy triggering mode
2024-12-23 22:40:42,602 - INFO - Expyfun: Initialization complete
2024-12-23 22:40:42,602 - EXP - Expyfun: Participant: foo
2024-12-23 22:40:42,602 - EXP - Expyfun: Session: foo
2024-12-23 22:40:44,726 - INFO - Expyfun: Exiting
2024-12-23 22:40:44,731 - EXP - Expyfun: Audio stopped and reset.
import numpy as np
from expyfun import (
ExperimentController,
building_doc,
fetch_data_file,
visual,
)
from expyfun import (
analyze as ea,
)
print(__doc__)
movie_path = fetch_data_file("video/example-video.mp4")
ec_args = dict(
exp_name="advanced video example",
window_size=(720, 480),
full_screen=False,
participant="foo",
session="foo",
version="dev",
output_dir=None,
)
colors = [x for x in "rgbcmyk"]
with ExperimentController(**ec_args) as ec:
screen_period = 1.0 / ec.estimate_screen_fs()
all_presses = list()
fix = visual.FixationDot(ec)
text = text = visual.Text(ec, "Running ...", (0, -0.1), "k")
screenshot = None # don't have one yet
ec.load_video(movie_path)
ec.video.set_scale("fill")
ec.screen_prompt("press 1 during video to toggle pause.", max_wait=1.0)
ec.listen_presses() # to catch presses on first pass of while loop
t_zero = ec.video.play(auto_draw=False)
this_sec = 0.0
while not ec.video.finished:
if ec.video.playing:
ec.video.draw()
else:
ec.screen_text("paused!", color="y", font_size=32, wrap=False)
text.draw()
fix.draw()
if screenshot is None:
screenshot = ec.screenshot()
fliptime = ec.flip()
presses = ec.get_presses(live_keys=[1], relative_to=t_zero)
ec.listen_presses()
# change the background color every 1 second
if this_sec != int(ec.video.time):
this_sec = int(ec.video.time)
text = visual.Text(ec, str(colors[this_sec]), (0, -0.1), "k")
ec.set_background_color(colors[this_sec])
# shrink the video, then move it rightward
if ec.video.playing:
if 1 < ec.video.time < 3:
ec.video.set_scale(ec.video.scale * 0.99)
if 4 < ec.video.time < 5:
ec.video.set_pos(ec.video.position + np.array((0.01, 0)))
# parse button presses
if len(presses):
all_presses.extend(presses)
if len(presses) % 2: # if even number of presses, do nothing
if ec.video.playing:
ec.video.pause()
else:
ec.video.play(auto_draw=False)
if building_doc:
break
ec.delete_video()
preamble = "press times:" if len(all_presses) else "no presses"
msg = ", ".join([f"{x[1]:.3f}" for x in all_presses])
ec.flip()
ec.screen_prompt("\n".join([preamble, msg]), max_wait=1.0)
ea.plot_screen(screenshot)
Total running time of the script: (0 minutes 2.424 seconds)