예제 #1
0
class VideoRecorder():
    """
    Use ImageEncoder gym.wrappers.monitoring.video_recorder because it make really nice videos using .mp4 and ffmpeg
    """
    def start(self, output_file, observation_shape, fps=30):
        """
        :param output_file:
        :param observation_shape:
        :param fps:
        :return:
        """
        height = observation_shape[2]
        width = observation_shape[1]
        pixFmt = observation_shape[0]

        frame_shape = (height, width, pixFmt)
        self._image_encoder = ImageEncoder(output_file, frame_shape, fps, fps)

    def add_frame(self, observation):
        """
        :param observation:
        :return:
        """
        self._image_encoder.capture_frame(observation.swapaxes(0, 2))

    def close(self):
        self._image_encoder.close()

    def __del__(self):
        # Release everything if job is finished
        self.close()
예제 #2
0
def record_video(buffer, file_path, fps):
    """
    Records the given image buffer to a video file.
    :param array_like buffer: the list containing the sequential image frames to be recorded.
    :param str file_path: the path to the video file.
    :param int fps: the video frames-per-second.
    :return:
    """

    # creates video encoder and adds each frame in the buffer
    video_recorder = ImageEncoder(file_path, buffer[0].shape, fps)
    for frame in buffer:
        video_recorder.capture_frame(frame)
    video_recorder.close()
    def animate(self, act_fn, nsteps, **kwargs):
        """act_fn could be a list of functions for each agent in the environemnt that we can control"""
        if not isinstance(act_fn, list):
            act_fn = [act_fn for _ in range(len(self.agents))]
        assert len(act_fn) == len(self.agents)
        encoder = None
        vid_loc = kwargs.pop('vid', None)
        obs = self.reset()
        frame = self.render(**kwargs)
        if vid_loc:
            fps = kwargs.pop('fps', 30)
            encoder = ImageEncoder(vid_loc, frame.shape, fps)
            try:
                encoder.capture_frame(frame)
            except error.InvalidFrame as e:
                print('Invalid video frame, {}'.format(e))

        rew = np.zeros((len(self.agents)))
        traj_info_list = []
        for step in range(nsteps):
            a = list(map(lambda afn, o: afn(o), act_fn, obs))
            obs, r, done, info = self.step(a)
            rew += r
            if info:
                traj_info_list.append(info)

            frame = self.render(**kwargs)
            if vid_loc:
                try:
                    encoder.capture_frame(frame)
                except error.InvalidFrame as e:
                    print('Invalid video frame, {}'.format(e))

            if done:
                break

        traj_info = stack_dict_list(traj_info_list)
        return rew, traj_info
예제 #4
0
class EpisodeRecorder(gym.Wrapper):
    """Wrapper for recording episodes to MP4 or jpeg-frames"""
    def __init__(self, env, path, fps=60, header=None):
        """Initialize the wrapper

        Args:
            env: The env to wrap and record
            path: The location where to place recordings
            fps: The FPS to encode the MP4 at
            header: Optional prefix for the output file name
        """
        super(EpisodeRecorder, self).__init__(env)
        self.fps = fps
        self.path = path
        self.header = header
        self.encoder = None
        os.makedirs(path, exist_ok=True)

    def _get_output_name(self):
        """Gets a unique name for the output video, starting from 00000.mp4

        (Handles collisions with parallel ENVs)
        """
        base_name = self.header + "_" if self.header is not None else ""
        i = 0
        while True:
            try:
                path = os.path.join(self.path,
                                    f"{base_name}{str(i).zfill(5)}.mp4")
                pathlib.Path(path).touch(exist_ok=False)
                return path
            except FileExistsError:
                i += 1
                continue

    def _init_new(self, shape):
        self._close_last()
        self.cur_path = self._get_output_name()
        self.encoder = ImageEncoder(self.cur_path, shape, self.fps)

    def _dump_frame(self, frame):
        self.encoder.capture_frame(frame)

    def _close_last(self):
        if self.encoder is not None:
            self.encoder.close()
            self.encoder = None

    def close(self):
        self._close_last()
        self.env.close()

    def reset(self):
        obs = self.env.reset()
        # Create a new output
        self._init_new(obs.shape)

        self._dump_frame(obs)
        return obs

    def step(self, action):
        obs, reward, done, info = self.env.step(action)
        self._dump_frame(obs)

        return obs, reward, done, info