這幾天需要用 Psychopy 寫一個播放電影的方案,以前雖然用過很多次,但是 psychopy 一直在更新,同時我對以前的實現不是很滿意,今天整理了一下。
使用的類主要是psychopy.visual.MovieStim
,這個類有幾個方法比較有用。
如何檢查影片是否結束?#
使用MovieStim.ifFinished
方法即可,在 while 循環中檢查這個值是否為 True,即可知道影片是否播放結束。結束的話,可以進行到下一個任務,沒有結束就繼續播放。
測試時候如何按鍵跳出播放界面?#
我嘗試了添加全局退出鍵,但是可能是我代碼有問題,全局退出不管用,只好退而求其次。目前通過在視頻播放過程中檢查是否有按鍵,有按鍵的話,就停止播放。
停止播放視頻可以使用mov.stop()
方法。
播放視頻的代碼:#
while not mov.isFinished:
mov.draw()
win.flip()
if len(event.getKeys())>0:
mov.stop()
break
自動調整視頻的大小#
我準備了兩個視頻,這兩個視頻幀的大小是不同的,為了實現自動調整,需要用到cv2
這個庫。
自動檢測視頻 frame 的大小#
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 完成了這個任務。
最終的代碼#
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
複製的代碼,縮進不太對,使用的話需要調整代碼的縮進,避免報錯。