Example #1
0
    def _get_frames(
        self, video_reader: decord.VideoReader, offset: int,
    ) -> List[np.ndarray]:
        """ Get frames at sample length.

        Args:
            video_reader: the decord tool for parsing videos
            offset: where to start the reader from

        Returns
            Frames at sample length in a List
        """
        clip = list()

        # decord.seek() seems to have a bug. use seek_accurate().
        video_reader.seek_accurate(offset)

        # first frame
        clip.append(video_reader.next().asnumpy())

        # remaining frames
        try:
            for i in range(self.sample_length - 1):
                step = (
                    randint(self.sample_step + 1)
                    if self.temporal_jitter
                    else self.sample_step
                )

                if step == 0 and self.temporal_jitter:
                    clip.append(clip[-1].copy())
                else:
                    if step > 1:
                        video_reader.skip_frames(step - 1)
                    cur_frame = video_reader.next().asnumpy()
                    clip.append(cur_frame)

        except StopIteration:
            # pass when video has ended
            pass

        # if clip needs more frames, simply duplicate the last frame in the clip.
        while len(clip) < self.sample_length:
            clip.append(clip[-1].copy())

        return clip
    shuffle=1)
ex = vl.next()
vr = VideoReader(path, ctx=cpu(0))
# a file like object works as well, for in-memory decoding
with open(path, 'rb') as f:
    vr = VideoReader(f, ctx=cpu(0))
print('video frames:', len(vr))
# 1. the simplest way is to directly access frames
for i in range(len(vr)):
    # the video reader will handle seeking and skipping in the most efficient manner
    frame = vr[i]
    print(frame.shape)

# To get multiple frames at once, use get_batch
# this is the efficient way to obtain a long list of frames
frames = vr.get_batch([1, 3, 5, 7, 9])
print(frames.shape)
# (5, 240, 320, 3)
# duplicate frame indices will be accepted and handled internally to avoid duplicate decoding
frames2 = vr.get_batch([1, 2, 3, 2, 3, 4, 3, 4, 5])
print(frames2.shape)
# (9, 240, 320, 3)

# 2. you can do cv2 style reading as well
# skip 100 frames
vr.skip_frames(100)
# seek to start
vr.seek(0)
batch = vr.next()
print('frame shape:', batch.shape)