class_docstr: Implementation of a video dataset.
  
  The VideoDataset allows random reads from a video file without extracting
  all frames beforehand. This is more storage efficient but is slower.
  
  Attributes:
      root:
          Root directory path.
      extensions:
          Tuple of allowed extensions.
      transform:
          Function that takes a PIL image and returns transformed version
      target_transform:
          As transform but for targets
      is_valid_file:
          Used to check corrupt files
      exception_on_non_increasing_timestamp:
          If True, a NonIncreasingTimestampError is raised when trying to load
          a frame that has a timestamp lower or equal to the timestamps of
          previous frames in the same video.
class_docstr_tok: ["Implementation","of","a","video","dataset",".","The","VideoDataset","allows","random","reads","from","a","video","file","without","extracting","all","frames","beforehand",".","This","is","more","storage","efficient","but","is","slower",".","Attributes",":","root",":","Root","directory","path",".","extensions",":","Tuple","of","allowed","extensions",".","transform",":","Function","that","takes","a","PIL","image","and","returns","transformed","version","target_transform",":","As","transform","but","for","targets","is_valid_file",":","Used","to","check","corrupt","files","exception_on_non_increasing_timestamp",":","If","True",",","a","NonIncreasingTimestampError","is","raised","when","trying","to","load","a","frame","that","has","a","timestamp","lower","or","equal","to","the","timestamps","of","previous","frames","in","the","same","video","."]
code: def __init__(
      self,
      root,
      extensions=None,
      transform=None,
      target_transform=None,
      is_valid_file=None,
      exception_on_non_increasing_timestamp=True,
      tqdm_args: Dict[str, Any] = None,
      num_workers: int = 0,
  ):
      super(VideoDataset, self).__init__(
          root, transform=transform, target_transform=target_transform
      )
  
      videos, video_timestamps, offsets, fps = _make_dataset(
          self.root,
          extensions,
          is_valid_file,
          tqdm_args=tqdm_args,
          num_workers=num_workers,
      )
  
      if len(videos) == 0:
          msg = "Found 0 videos in folder: {}\n".format(self.root)
          if extensions is not None:
              msg += "Supported extensions are: {}".format(
                  ",".join(extensions)
              )
          raise RuntimeError(msg)
  
      self.extensions = extensions
      self.backend = torchvision.get_video_backend()
      self.exception_on_non_increasing_timestamp = (
          exception_on_non_increasing_timestamp
      )
  
      self.videos = videos
      self.video_timestamps = video_timestamps
      self._length = sum((len(ts) for ts in self.video_timestamps))
      # Boolean value for every timestamp in self.video_timestamps. If True
      # the timestamp of the frame is non-increasing compared to timestamps of
      # previous frames in the video.
      self.video_timestamps_is_non_increasing = [
          _find_non_increasing_timestamps(timestamps)
          for timestamps in video_timestamps
      ]
  
      # offsets[i] indicates the index of the first frame of the i-th video.
      # e.g. for two videos of length 10 and 20, the offsets will be [0, 10].
      self.offsets = offsets
      self.fps = fps
  
      # Current VideoLoader instance and the corresponding video index. We
      # only keep track of the last accessed video as this is a good trade-off
      # between speed and memory requirements.
      # See https://github.com/lightly-ai/lightly/pull/702 for details.
      self._video_loader = None
      self._video_index = None
  
      # Keep unique reference of dataloader worker. We need this to avoid
      # accidentaly sharing VideoLoader instances between workers.
      self._worker_ref = None
  
      # Lock to prevent multiple threads creating a new VideoLoader at the
      # same time.
      self._video_loader_lock = threading.Lock()
  
imports: import os
  import threading
  import warnings
  import weakref
  from fractions import Fraction
  from typing import Any, Dict, List, Tuple
  import numpy
  import torch
  import torchvision
  from PIL import Image
  from torch.utils.data import DataLoader, Dataset
  from torchvision import datasets, io
  from tqdm import tqdm
label_desc: Use image node_id 1 to create a new VideoDataset object from inherited base classes: datasets with example: obj = VideoDataset(root, extensions, transform, target_transform, is_valid_file, exception_on_non_increasing_timestamp, tqdm_args, num_workers)