使用gym.vector.SyncVectorEnv时render未实现,如何录制视频?
问题分析与解决方案
核心原因
gym.vector.SyncVectorEnv 默认没有实现 render() 方法,所以直接给它套 RecordVideo 时,wrapper 调用 env.render() 会触发 NotImplemented 错误。而你能调用 single_env.render() 是因为单个环境本身具备渲染能力,但直接把 RecordVideo 套在 single_env 外会崩溃,是因为后续用 vector env 输出的动作/观测带批量维度(比如 (1, ...)),和单个环境的接口要求不匹配。
可行解决方案
方案一:手动控制录制流程
既然你用的是单环境的 SyncVectorEnv,本质还是在操作底层的 single_env,可以直接用 VideoRecorder 单独绑定 single_env,同时保留 vector env 的批量接口逻辑:
from gym.wrappers.monitoring.video_recorder import VideoRecorder def make_env(): env = gym.make('CarRacing-v2', render_mode='rgb_array') env = normalize_obs(env) env = BoundAction(env, low=0, high=1) return env single_env = make_env() env = gym.vector.SyncVectorEnv([lambda: single_env]) # 初始化视频录制器,绑定单个环境 video_recorder = VideoRecorder(single_env, path="./recording/episode_0.mp4") # 运行/训练循环 obs = env.reset() done = False while not done: action = ... # 你的动作选择逻辑(输出需符合vector env的批量维度) obs, reward, done, info = env.step(action) # 每次step后获取单个环境的渲染帧并写入视频 frame = single_env.render() video_recorder.capture_frame(frame) # 结束录制并关闭环境 video_recorder.close() env.close()
方案二:给SyncVectorEnv添加render支持
自定义一个wrapper,让 SyncVectorEnv 的 render() 方法转发到底层单个环境,这样就能正常使用 RecordVideo:
import gym from gym.vector import SyncVectorEnv from gym.wrappers import RecordVideo class VectorRenderWrapper(gym.Wrapper): def __init__(self, env): super().__init__(env) # 针对单环境的SyncVectorEnv,直接取第一个底层环境 self.single_env = env.envs[0] def render(self, **kwargs): return self.single_env.render(**kwargs) # 创建环境 single_env = make_env() env = SyncVectorEnv([lambda: single_env]) # 先套自定义render wrapper,再套RecordVideo env = VectorRenderWrapper(env) env = RecordVideo(env, "./recording") # 正常运行循环 obs = env.reset() done = False while not done: action = ... # 符合vector env批量维度的动作 obs, reward, done, info = env.step(action) # RecordVideo会自动调用env.render(),由wrapper转发到single_env if done: env.close()
内容的提问来源于stack exchange,提问作者brownie
相关产品推荐
相关产品推荐

