code: def test_to_clip_frames():
      dataset = foz.load_zoo_dataset("quickstart-video").clone()
      dataset.compute_metadata()
  
      dataset.tag_samples("test")
  
      clips = dataset.filter_labels(
          "frames.detections", F("label") == "person"
      ).to_clips("frames.detections")
  
      frames = clips.to_frames(sample_frames=True, fps=1)
  
      print("\nClips view")
      for filepath, support in zip(
          *clips.values(["filepath", "support"])
      ):
          print("%s: %s" % (filepath, support))
  
      print("\nFrames view")
      for filepath, fn in zip(
          *frames.values(["filepath", "frame_number"])
      ):
          print("%s: %s" % (filepath, fn))
  
      # Frames inherit sample tags
      print(dataset.count_sample_tags())
      print(frames.count_sample_tags())
  
      frames.tag_samples("clips")
  
      # Tagging frames has no effect on the source dataset
      print(frames.count_sample_tags())
      print(dataset.count_sample_tags())
  
      frames.untag_samples("clips")
  
      # Untagging clips has no effect on the source dataset
      print(frames.count_sample_tags())
      print(dataset.count_sample_tags())
  
      frames.tag_labels("test")
  
      # Tagging labels applies to the source dataset
      print(frames.count_label_tags())
      print(dataset.count_label_tags())
      print(dataset.count_values("frames.detections.detections.tags"))
  
      frames.untag_labels("test")
  
      # Untagging labels applies to the source dataset
      print(frames.count_label_tags())
      print(dataset.count_label_tags())
      print(dataset.count_values("frames.detections.detections.tags"))
  
      view = frames.limit(10).set_field(
          "detections.detections.label", F("label").upper()
      )
  
      # Views can be created, but don't affect source dataset until saved
      print(frames.count("detections.detections"))
      print(view.count("detections.detections"))
      print(dataset.count("frames.detections.detections"))
      print(frames.count_values("detections.detections.label"))
      print(view.count_values("detections.detections.label"))
      print(dataset.count_values("frames.detections.detections.label"))
  
      view.save()
  
      # Changes and deletions are synced with source dataset
      print(frames.count("detections.detections"))
      print(view.count("detections.detections"))
      print(dataset.count("frames.detections.detections"))
      print(frames.count_values("detections.detections.label"))
      print(view.count_values("detections.detections.label"))
      print(dataset.count_values("frames.detections.detections.label"))
  
      # Ensure that data is correctly formed
      print(frames.first().id)
      print(dataset.first().frames.first().id)
  
      sample = frames.first()
  
      sample["hello"] = "world"
      sample.save()
  
      # Fields can be added by direct sample modification, and are saved
      print(frames)
      print(dataset)
      print(frames.count_values("hello"))
      print(dataset.count_values("frames.hello"))
  
      sample = frames.exclude_fields("detections").first()
      sample["hello2"] = "world2"
      sample.save()
  
      # Excluded fields are not removed when saving clip samples
      print(frames)
      print(dataset)
      print(frames.count_values("detections.detections.label"))
      print(frames.count_values("hello2"))
      print(dataset.count_values("frames.detections.detections.label"))
      print(dataset.count_values("frames.hello2"))
  
      dataset.untag_samples("test")
      frames.reload()
  
      # Reloading a view syncs it with the source dataset
      print(dataset.count_sample_tags())
      print(frames.count_sample_tags())
  
file_path: fiftyone/tests/intensive/video_tests.py
imports: import random
  import unittest
  import fiftyone
  import fiftyone.zoo
  from fiftyone import ViewField
  import fiftyone.utils.video
label_desc: Use image node_id 3 for calling a global function with example usage: test_to_clip_frames() without return types