class_docstr: EncodedVideoPyAV is an abstraction for accessing clips from an encoded video using
  PyAV as the decoding backend. It supports selective decoding when header information
  is available.
class_docstr_tok: ["EncodedVideoPyAV","is","an","abstraction","for","accessing","clips","from","an","encoded","video","using","PyAV","as","the","decoding","backend",".","It","supports","selective","decoding","when","header","information","is","available","."]
docstr: Args:
      file (BinaryIO): a file-like object (e.g. io.BytesIO or io.StringIO) that
          contains the encoded video.
      perform_seek:
          Whether or not to seek time to the underlying video container.
  
          NOTE: seeks may be slow on larger files, e.g. on a networked filesystem
docstr_tok: ["Args",":","file","(","BinaryIO",")",":","a","file-like","object","(","e.g",".","io.BytesIO","or","io.StringIO",")","that","contains","the","encoded","video",".","perform_seek",":","Whether","or","not","to","seek","time","to","the","underlying","video","container",".","NOTE",":","seeks","may","be","slow","on","larger","files",",","e.g",".","on","a","networked","filesystem"]
code: def __init__(
      self,
      file: BinaryIO,
      video_name: Optional[str] = None,
      decode_video: bool = True,
      decode_audio: bool = True,
      perform_seek: bool = True,
  ) -> None:
      """
      Args:
          file (BinaryIO): a file-like object (e.g. io.BytesIO or io.StringIO) that
              contains the encoded video.
          perform_seek:
              Whether or not to seek time to the underlying video container.
  
              NOTE: seeks may be slow on larger files, e.g. on a networked filesystem
      """
      self.perform_seek = perform_seek
      self._video_name = video_name
      self._decode_video = decode_video
      self._decode_audio = decode_audio
  
      try:
          self._container = av.open(file)
      except Exception as e:
          raise RuntimeError(f"Failed to open video {video_name}. {e}")
  
      if (
          self._container is None
          or len(self._container.streams.video) == 0
      ):
          raise RuntimeError(f"Video stream not found {video_name}")
  
      # Retrieve video header information if available.
      video_stream = self._container.streams.video[0]
      self._video_time_base = video_stream.time_base
      self._video_start_pts = video_stream.start_time
      if self._video_start_pts is None:
          self._video_start_pts = 0.0
  
      video_duration = video_stream.duration
  
      # Retrieve audio header information if available.
      audio_duration = None
      self._has_audio = None
      if self._decode_audio:
          self._has_audio = self._container.streams.audio
          if self._has_audio:
              self._audio_time_base = self._container.streams.audio[
                  0
              ].time_base
              self._audio_start_pts = self._container.streams.audio[
                  0
              ].start_time
              if self._audio_start_pts is None:
                  self._audio_start_pts = 0.0
  
              audio_duration = self._container.streams.audio[0].duration
  
      # If duration isn't found in header the whole video is decoded to
      # determine the duration.
      self._video, self._audio, self._selective_decoding = (
          None,
          None,
          True,
      )
      if audio_duration is None and video_duration is None:
          self._selective_decoding = False
          self._video, self._audio = self._pyav_decode_video()
          if self._video is None:
              raise RuntimeError("Unable to decode video stream")
  
          video_duration = self._video[-1][1]
          if self._audio is not None:
              audio_duration = self._audio[-1][1]
  
      # Take the largest duration of either video or duration stream.
      if audio_duration is not None and video_duration is not None:
          self._duration = max(
              pts_to_secs(
                  video_duration,
                  self._video_time_base,
                  self._video_start_pts,
              ),
              pts_to_secs(
                  audio_duration,
                  self._audio_time_base,
                  self._audio_start_pts,
              ),
          )
      elif video_duration is not None:
          self._duration = pts_to_secs(
              video_duration,
              self._video_time_base,
              self._video_start_pts,
          )
  
      elif audio_duration is not None:
          self._duration = pts_to_secs(
              audio_duration,
              self._audio_time_base,
              self._audio_start_pts,
          )
  
imports: import logging
  import math
  from fractions import Fraction
  from typing import BinaryIO, Dict, List, Optional, Tuple, Union
  import av
  import numpy
  import torch
  from pytorchvideo.data.encoded_video import EncodedVideo
  from .utils import pts_to_secs, secs_to_pts, thwc_to_cthw
label_desc: Use image node_id 1 to create a new EncodedVideoPyAV object from inherited base classes: EncodedVideo with example: obj = EncodedVideoPyAV(file, video_name, decode_video, decode_audio, perform_seek)