Psychopy学习笔记 —— MovieStim

这几天需要用 Psychopy 写一个播放电影的方案，以前虽然用过很多次，但是 psychopy 一直在更新，同时我对以前的实现不是很满意，今天整理了一下。

使用的类主要是psychopy.visual.MovieStim，这个类有几个方法比较有用。

如何检查影片是否结束？

使用MovieStim.ifFinished方法即可，在 while 循环中检查这个值是否为 True，即可知道影片是否播放结束。结束的话，可以进行到下一个任务，没有结束就继续播放。

测试时候如何按键跳出播放界面？

我尝试了添加全局退出键，但是可能是我代码有问题，全局退出不管用，只好退而求其次。目前通过在视频播放过程中检查是否有按键，有按键的话，就停止播放。

停止播放视频可以使用mov.stop()方法。

播放视频的代码：

Copy
while not mov.isFinished:
mov.draw()
win.flip()
if len(event.getKeys())>0:
mov.stop()
break

自动调整视频的大小

我准备了两个视频，这两个视频帧的大小是不同的，为了实现自动调整，需要用到cv2这个库。

自动检测视频 frame 的大小

Copy
import cv2
def get_movie_frame_size(movie_path):
cap = cv2.VideoCapture(movie_path)
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
cap.release()
return frame_width, frame_height

这一段代码使用 chatGPT 生成的。我最开始尝试让 chatGPT 使用 psychopy 来完成，但是输出的都不对。

根据我下午阅读文档 API，psychopy 中有movie.size，文档生成可以输出 frame 的大小，但是我测试下来，输出的结果不对。chatGPDT 最开始使用 psychopy 自身来完成，也是类似的视线，但是不对。可能是 psychopy 的接口一直在更新，所以 chatGPT 没有学习到。最后使用 opencv 完成了这个任务。

最终的代码

Copy
for i in range(2): #我只有两个视频
video_used = cur_movie_path + video_names[i]
mov = visual.MovieStim(win, video_used,
flipVert=False, flipHoriz=False, loop=False)
frame_width, frame_height = \
get_movie_frame_size(cur_movie_path+video_names[i])
mov.size = (frame_width, frame_height)

while not mov.isFinished:
mov.draw()
win.flip()
if len(event.getKeys())>0:
mov.stop()
break

复制的代码，缩进不太对，使用的话需要调整代码的缩进，避免报错。