class_docstr: FrameVideo is an abstractions for accessing clips based on their start and end
  time for a video where each frame is stored as an image. PathManager is used for
  frame image reading, allowing non-local uri's to be used.
docstr: Retrieves frames from the stored video at the specified start and end times
  in seconds (the video always starts at 0 seconds). Returned frames will be
  in [start_sec, end_sec). Given that PathManager may
  be fetching the frames from network storage, to handle transient errors, frame
  reading is retried N times.  Note that as end_sec is exclusive, so you may need
  to use `get_clip(start_sec, duration + EPS)` to get the last frame.
  
  Args:
      start_sec (float): the clip start time in seconds
      end_sec (float): the clip end time in seconds
      frame_filter (Optional[Callable[List[int], List[int]]]):
          function to subsample frames in a clip before loading.
          If None, no subsampling is peformed.
  Returns:
      clip_frames: A tensor of the clip's RGB frames with shape:
          (channel, time, height, width). The frames are of type torch.float32 and
          in the range [0 - 255]. Raises an exception if unable to load images.
  
      clip_data:
          "video": A tensor of the clip's RGB frames with shape:
          (channel, time, height, width). The frames are of type torch.float32 and
          in the range [0 - 255]. Raises an exception if unable to load images.
  
          "frame_indices": A list of indices for each frame relative to all frames in the
          video.
  
      Returns None if no frames are found.
docstr_tok: ["Retrieves","frames","from","the","stored","video","at","the","specified","start","and","end","times","in","seconds","(","the","video","always","starts","at","0","seconds",")",".","Returned","frames","will","be","in","[","start_sec",",","end_sec",")",".","Given","that","PathManager","may","be","fetching","the","frames","from","network","storage",",","to","handle","transient","errors",",","frame","reading","is","retried","N","times",".","Note","that","as","end_sec","is","exclusive",",","so","you","may","need","to","use","`","get_clip","(","start_sec",",","duration","+","EPS",")","`","to","get","the","last","frame",".","Args",":","start_sec","(","float",")",":","the","clip","start","time","in","seconds","end_sec","(","float",")",":","the","clip","end","time","in","seconds","frame_filter","(","Optional","[","Callable","[","List","[","int","]",",","List","[","int","]","]","]",")",":","function","to","subsample","frames","in","a","clip","before","loading",".","If","None",",","no","subsampling","is","peformed",".","Returns",":","clip_frames",":","A","tensor","of","the","clip","'s","RGB","frames","with","shape",":","(","channel",",","time",",","height",",","width",")",".","The","frames","are","of","type","torch.float32","and","in","the","range","[","0","-","255","]",".","Raises","an","exception","if","unable","to","load","images",".","clip_data",":","``","video","''",":","A","tensor","of","the","clip","'s","RGB","frames","with","shape",":","(","channel",",","time",",","height",",","width",")",".","The","frames","are","of","type","torch.float32","and","in","the","range","[","0","-","255","]",".","Raises","an","exception","if","unable","to","load","images",".","``","frame_indices","''",":","A","list","of","indices","for","each","frame","relative","to","all","frames","in","the","video",".","Returns","None","if","no","frames","are","found","."]
code: def get_clip(
      self,
      start_sec: float,
      end_sec: float,
      frame_filter: Optional[Callable[[List[int]], List[int]]] = None,
  ) -> Dict[str, Optional[torch.Tensor]]:
      """
      Retrieves frames from the stored video at the specified start and end times
      in seconds (the video always starts at 0 seconds). Returned frames will be
      in [start_sec, end_sec). Given that PathManager may
      be fetching the frames from network storage, to handle transient errors, frame
      reading is retried N times.  Note that as end_sec is exclusive, so you may need
      to use `get_clip(start_sec, duration + EPS)` to get the last frame.
  
      Args:
          start_sec (float): the clip start time in seconds
          end_sec (float): the clip end time in seconds
          frame_filter (Optional[Callable[List[int], List[int]]]):
              function to subsample frames in a clip before loading.
              If None, no subsampling is peformed.
      Returns:
          clip_frames: A tensor of the clip's RGB frames with shape:
              (channel, time, height, width). The frames are of type torch.float32 and
              in the range [0 - 255]. Raises an exception if unable to load images.
  
          clip_data:
              "video": A tensor of the clip's RGB frames with shape:
              (channel, time, height, width). The frames are of type torch.float32 and
              in the range [0 - 255]. Raises an exception if unable to load images.
  
              "frame_indices": A list of indices for each frame relative to all frames in the
              video.
  
          Returns None if no frames are found.
      """
      if start_sec < 0 or start_sec > self._duration:
          logger.warning(
              f"No frames found within {start_sec} and {end_sec} seconds. Video starts"
              f"at time 0 and ends at {self._duration}."
          )
          return None
  
      end_sec = min(end_sec, self._duration)
  
      start_frame_index = self._get_frame_index_for_time(start_sec)
      end_frame_index = min(
          self._get_frame_index_for_time(end_sec),
          len(self._video_frame_paths),
      )
      frame_indices = list(range(start_frame_index, end_frame_index))
      # Frame filter function to allow for subsampling before loading
      if frame_filter:
          frame_indices = frame_filter(frame_indices)
  
      clip_paths = [self._video_frame_to_path(i) for i in frame_indices]
      clip_frames = _load_images_with_retries(
          clip_paths, multithreaded=self._multithreaded_io
      )
      clip_frames = thwc_to_cthw(clip_frames).to(torch.float32)
      return {
          "video": clip_frames,
          "frame_indices": frame_indices,
          "audio": None,
      }
  
imports: from __future__ import annotations
  import logging
  import math
  import os
  import re
  import time
  from typing import Callable, Dict, List, Optional
  import numpy
  import torch
  import torch.utils.data
  from iopath.common.file_io import g_pathmgr
  from pytorchvideo.data.utils import optional_threaded_foreach
  from .utils import thwc_to_cthw
  from .video import Video
label_desc: Use image node_id 7 for calling the FrameVideo obj's underlying member method code with example usage: obj.get_clip(start_sec, end_sec, frame_filter) and returns: dict, None