class_docstr: extract keyframes from a video and save it as jpg.
  TODO: consider to merge with `CodecProcessor`.
class_docstr_tok: ["extract","keyframes","from","a","video","and","save","it","as","jpg",".","TODO",":","consider","to","merge","with","`","CodecProcessor","`","."]
code: def __getitem__(self, idx):
      import av
  
      video_path = self.csv["video_path"].values[idx]
      output_file = self.csv["feature_path"].values[idx]
      if not (os.path.isdir(output_file)) and os.path.isfile(
          video_path
      ):
          try:
              h, w = self._get_video_dim(video_path)
          except Exception:
              print("probe failed at: {}".format(video_path))
              return {
                  "video": th.zeros(1),
                  "input": video_path,
                  "output": output_file,
              }
  
          try:
              height, width = self._get_output_dim(h, w)
  
              # new for av.
              with av.open(video_path) as container:
                  container.streams.video[0].thread_type = "AUTO"
                  container.streams.video[
                      0
                  ].codec_context.height = height
                  container.streams.video[0].codec_context.width = width
                  if self.framerate == 0:  # keyframe.
                      container.streams.video[
                          0
                      ].codec_context.skip_frame = "NONKEY"
                  frames = []
                  for frame in container.decode(video=0):
                      frames.append(frame)
                  frames = random.sample(frames, self.max_num_frames)
  
                  os.makedirs(output_file, exist_ok=True)
                  for frame in frames:
                      frame.to_image().save(
                          os.path.join(
                              output_file, "%04d.jpg" % frame.index
                          )
                      )
          except Exception:
              print("extract failed at: {}".format(video_path))
              return {
                  "video": th.zeros(1),
                  "input": video_path,
                  "output": output_file,
              }
      video = th.zeros(1)
      return {
          "video": video,
          "input": video_path,
          "output": output_file,
      }
  
imports: import torch
  import pandas
  import os
  import numpy
  import ffmpeg
  import random
  from torch.utils.data import Dataset
label_desc: Use image node_id 4 for calling the AvKeyframeVideoCompressor obj's underlying member method code with example usage: obj.__getitem__(idx) and returns: dict, dict, dict