Anaconda环境下OpenAI Gymnasium视频捕获失败求助
Gymnasium录屏在Anaconda中出现帧率NoneType错误的解决方法
问题背景
同样的Gymnasium录屏代码在Google Colab中可正常运行(但会生成两个视频),但在Anaconda 2.1.4中执行时,程序尝试写入视频后抛出TypeError: must be real number, not NoneType错误,错误指向'-r', '%.02f' % fps,代码行,说明视频帧率fps未被正确赋值为有效数值。尝试修改环境metadata中的帧率参数(如video.frames_per_second、render_fps)均无效。
Colab可运行的原始代码
安装依赖
!pip install gymnasium !pip install moviepy
录屏代码
import gymnasium as gym env = gym.make("CartPole-v1", render_mode='rgb_array') env = gym.wrappers.RecordVideo(env, 'vidcap') observation, info = env.reset(seed=42) for step in range(100): action = env.action_space.sample() observation, reward, terminated, truncated, info = env.step(action) if terminated or truncated: observation, info = env.reset() env.close() env.reset
已尝试的无效帧率设置方式
#env.metadata["video.frames_per_second"] = 4 #仅Colab有效 #env.metadata["render_fps"] = 4 #仅Colab有效 #env.metadata['video.fps'] = 4 #env.metadata.get("render_fps", 4) #env.metadata['video.frames_per_second']
可行解决方法
1. 修改原始环境的render_fps
直接修改未包装的原始环境的metadata,确保帧率参数被正确传递到录屏包装器:
import gymnasium as gym env = gym.make("CartPole-v1", render_mode='rgb_array') # 修改原始环境的渲染帧率 env.unwrapped.metadata["render_fps"] = 30 env = gym.wrappers.RecordVideo(env, 'vidcap') # 后续执行逻辑不变 observation, info = env.reset(seed=42) for step in range(100): action = env.action_space.sample() observation, reward, terminated, truncated, info = env.step(action) if terminated or truncated: observation, info = env.reset() env.close()
2. 显式给RecordVideo传入fps参数(Gymnasium 0.26+适用)
若你的Gymnasium版本≥0.26,可在初始化录屏包装器时直接指定帧率:
env = gym.wrappers.RecordVideo(env, 'vidcap', fps=30)
3. 检查并修复依赖环境
Anaconda环境中可能存在ffmpeg缺失或依赖版本不兼容问题:
- 安装ffmpeg:在终端执行
conda install -c conda-forge ffmpeg - 更新依赖包到最新版本:
pip install --upgrade gymnasium moviepy
4. 控制录屏触发逻辑(同时解决多视频问题)
原代码中每次环境重置都会触发新的录屏任务,既会生成多个视频,也可能导致帧率参数异常。可通过自定义触发函数限制仅录制指定回合:
import gymnasium as gym from gymnasium.wrappers import RecordVideo env = gym.make("CartPole-v1", render_mode='rgb_array') env.unwrapped.metadata["render_fps"] = 30 # 仅录制第1个回合 def episode_trigger(episode_id): return episode_id == 0 env = RecordVideo(env, 'vidcap', episode_trigger=episode_trigger) observation, info = env.reset(seed=42) for step in range(100): action = env.action_space.sample() observation, reward, terminated, truncated, info = env.step(action) if terminated or truncated: observation, info = env.reset() env.close()
内容的提问来源于stack exchange,提问作者Marc Unger
相关产品推荐
相关产品推荐

