code: def make_frames_dataset(
      sample_collection,
      sample_frames=False,
      fps=None,
      max_fps=None,
      size=None,
      min_size=None,
      max_size=None,
      sparse=False,
      output_dir=None,
      rel_dir=None,
      frames_patt=None,
      force_sample=False,
      skip_failures=True,
      verbose=False,
      name=None,
  ):
      """Creates a dataset that contains one sample per frame in the video
      collection.
  
      The returned dataset will contain all frame-level fields and the ``tags``
      of each video as sample-level fields, as well as a ``sample_id`` field that
      records the IDs of the parent sample for each frame.
  
      By default, ``sample_frames`` is False and this method assumes that the
      frames of the input collection have ``filepath`` fields populated pointing
      to each frame image. Any frames without a ``filepath`` populated will be
      omitted from the frames dataset.
  
      When ``sample_frames`` is True, this method samples each video in the
      collection into a directory of per-frame images and stores the filepaths in
      the ``filepath`` frame field of the source dataset. By default, each folder
      of images is written using the same basename as the input video. For
      example, if ``frames_patt = "%%06d.jpg"``, then videos with the following
      paths::
  
          /path/to/video1.mp4
          /path/to/video2.mp4
          ...
  
      would be sampled as follows::
  
          /path/to/video1/
              000001.jpg
              000002.jpg
              ...
          /path/to/video2/
              000001.jpg
              000002.jpg
              ...
  
      However, you can use the optional ``output_dir`` and ``rel_dir`` parameters
      to customize the location and shape of the sampled frame folders. For
      example, if ``output_dir = "/tmp"`` and ``rel_dir = "/path/to"``, then
      videos with the following paths::
  
          /path/to/folderA/video1.mp4
          /path/to/folderA/video2.mp4
          /path/to/folderB/video3.mp4
          ...
  
      would be sampled as follows::
  
          /tmp/folderA/
              video1/
                  000001.jpg
                  000002.jpg
                  ...
              video2/
                  000001.jpg
                  000002.jpg
                  ...
          /tmp/folderB/
              video3/
                  000001.jpg
                  000002.jpg
                  ...
  
      By default, samples will be generated for every video frame at full
      resolution, but this method provides a variety of parameters that can be
      used to customize the sampling behavior.
  
      .. note::
  
          If this method is run multiple times with ``sample_frames`` set to
          True, existing frames will not be resampled unless you set
          ``force_sample`` to True.
  
      .. note::
  
          The returned dataset is independent from the source collection;
          modifying it will not affect the source collection.
  
      Args:
          sample_collection: a
              :class:`fiftyone.core.collections.SampleCollection`
          sample_frames (False): whether to assume that the frame images have
              already been sampled at locations stored in the ``filepath`` field
              of each frame (False), or whether to sample the video frames now
              according to the specified parameters (True)
          fps (None): an optional frame rate at which to sample each video's
              frames
          max_fps (None): an optional maximum frame rate at which to sample.
              Videos with frame rate exceeding this value are downsampled
          size (None): an optional ``(width, height)`` at which to sample frames.
              A dimension can be -1, in which case the aspect ratio is preserved.
              Only applicable when ``sample_frames=True``
          min_size (None): an optional minimum ``(width, height)`` for each
              frame. A dimension can be -1 if no constraint should be applied.
              The frames are resized (aspect-preserving) if necessary to meet
              this constraint. Only applicable when ``sample_frames=True``
          max_size (None): an optional maximum ``(width, height)`` for each
              frame. A dimension can be -1 if no constraint should be applied.
              The frames are resized (aspect-preserving) if necessary to meet
              this constraint. Only applicable when ``sample_frames=True``
          sparse (False): whether to only sample frame images for frame numbers
              for which :class:`fiftyone.core.frame.Frame` instances exist in the
              input collection. This parameter has no effect when
              ``sample_frames==False`` since frames must always exist in order to
              have ``filepath`` information used
          output_dir (None): an optional output directory in which to write the
              sampled frames. By default, the frames are written in folders with
              the same basename of each video
          rel_dir (None): a relative directory to remove from the filepath of
              each video, if possible. The path is converted to an absolute path
              (if necessary) via :func:`fiftyone.core.storage.normalize_path`.
              This argument can be used in conjunction with ``output_dir`` to
              cause the sampled frames to be written in a nested directory
              structure within ``output_dir`` matching the shape of the input
              video's folder structure
          frames_patt (None): a pattern specifying the filename/format to use to
              write or check or existing sampled frames, e.g., ``"%%06d.jpg"``.
              The default value is
              ``fiftyone.config.default_sequence_idx + fiftyone.config.default_image_ext``
          force_sample (False): whether to resample videos whose sampled frames
              already exist. Only applicable when ``sample_frames=True``
          skip_failures (True): whether to gracefully continue without raising
              an error if a video cannot be sampled
          verbose (False): whether to log information about the frames that will
              be sampled, if any
          name (None): a name for the dataset
  
      Returns:
          a :class:`fiftyone.core.dataset.Dataset`
      """
      fova.validate_video_collection(sample_collection)
  
      if sample_frames != True:
          l = locals()
          for var in ("size", "min_size", "max_size"):
              if l[var]:
                  logger.warning(
                      "Ignoring '%s' when sample_frames=%s",
                      var,
                      sample_frames,
                  )
  
      if frames_patt is None:
          frames_patt = (
              fo.config.default_sequence_idx
              + fo.config.default_image_ext
          )
  
      #
      # Create dataset with proper schema
      #
  
      dataset = fod.Dataset(name=name, _frames=True)
      dataset.media_type = fom.IMAGE
      dataset.add_sample_field("sample_id", fof.ObjectIdField)
  
      frame_schema = sample_collection.get_frame_field_schema()
      dataset._sample_doc_cls.merge_field_schema(frame_schema)
  
      dataset.create_index("sample_id")
  
      # This index will be used when populating the collection now as well as
      # later when syncing the source collection
      dataset.create_index(
          [("sample_id", 1), ("frame_number", 1)], unique=True
      )
  
      _make_pretty_summary(dataset)
  
      # Initialize frames dataset
      sample_view, frames_to_sample = _init_frames(
          dataset,
          sample_collection,
          sample_frames,
          output_dir,
          rel_dir,
          frames_patt,
          fps,
          max_fps,
          sparse,
          force_sample,
          verbose,
      )
  
      # Sample frames, if necessary
      if sample_view is not None:
          logger.info("Sampling video frames...")
          fouv.sample_videos(
              sample_view,
              output_dir=output_dir,
              rel_dir=rel_dir,
              frames_patt=frames_patt,
              frames=frames_to_sample,
              size=size,
              min_size=min_size,
              max_size=max_size,
              original_frame_numbers=True,
              force_sample=True,
              save_filepaths=True,
              skip_failures=skip_failures,
          )
  
      #
      # Merge frame data
      #
  
      pipeline = []
  
      if sample_frames == "dynamic":
          pipeline.append({"$project": {"filepath": False}})
  
      pipeline.extend(
          [
              {"$addFields": {"_dataset_id": dataset._doc.id}},
              {
                  "$merge": {
                      "into": dataset._sample_collection_name,
                      "on": ["_sample_id", "frame_number"],
                      "whenMatched": "merge",
                      "whenNotMatched": "discard",
                  }
              },
          ]
      )
  
      sample_collection._aggregate(
          frames_only=True, post_pipeline=pipeline
      )
  
      if sample_frames == False and not dataset:
          logger.warning(
              "Your frames view is empty. Note that you must either "
              "pre-populate the `filepath` field on the frames of your video "
              "collection or pass `sample_frames=True` to this method to "
              "perform the sampling. See "
              "https://docs.voxel51.com/user_guide/using_views.html#frame-views "
              "for more information."
          )
  
      return dataset
  
imports: from collections import defaultdict
  from copy import deepcopy
  import logging
  import os
  from bson import ObjectId
  from pymongo import UpdateOne
  import eta.core.utils
  import fiftyone
  import fiftyone.core.dataset
  import fiftyone.core.fields
  import fiftyone.core.media
  import fiftyone.core.sample
  import fiftyone.core.odm
  import fiftyone.core.odm.sample
  import fiftyone.core.utils
  import fiftyone.core.validation
  import fiftyone.core.view
label_desc: Use image node_id 1 for calling a global function with example usage: make_frames_dataset(sample_collection, sample_frames, fps, max_fps, size, min_size, max_size, sparse, output_dir, rel_dir, frames_patt, force_sample, skip_failures, verbose, name) and returns: dataset