class_docstr: Frames matches inside a set of frames.
  
  You can instantiate it passing a list of FramesMatch objects or
  using the class methods ``load`` and ``from_clip``.
  
  Parameters
  ----------
  
  lst : list
    Iterable of FramesMatch objects.
class_docstr_tok: ["Frames","matches","inside","a","set","of","frames",".","You","can","instantiate","it","passing","a","list","of","FramesMatch","objects","or","using","the","class","methods","``","load","``","and","``","from_clip","``",".","Parameters","--","--","--","--","--","lst",":","list","Iterable","of","FramesMatch","objects","."]
docstr: Select the scenes at which a video clip can be reproduced as the
  smoothest possible way, mainly oriented for the creation of GIF images.
  
  Parameters
  ----------
  
  match_threshold : float
    Maximum distance possible between frames. The smaller, the
    better-looping the GIFs are.
  
  min_time_span : float
    Minimum duration for a scene. Only matches with a duration longer
    than the value passed to this parameters will be extracted.
  
  nomatch_threshold : float, optional
    Minimum distance possible between frames. If is ``None``, then it is
    chosen equal to ``match_threshold``.
  
  time_distance : float, optional
    Minimum time offset possible between matches.
  
  Returns
  -------
  
  FramesMatches : New instance of the class with the selected scenes.
  
  Examples
  --------
  
  >>> from pprint import pprint
  >>> from moviepy.editor import *
  >>> from moviepy.video.tools.cuts import FramesMatches
  >>>
  >>> ch_clip = VideoFileClip("media/chaplin.mp4").subclip(1, 4)
  >>> clip = concatenate_videoclips([ch_clip.time_mirror(), ch_clip])
  >>>
  >>> result = FramesMatches.from_clip(clip, 10, 3).select_scenes(
  ...     1, 2, nomatch_threshold=0,
  ... )
  >>> pprint(result)
  [(1.0000, 4.0000, 0.0000, 0.0000),
   (1.1600, 3.8400, 0.0000, 0.0000),
   (1.2800, 3.7200, 0.0000, 0.0000),
   (1.4000, 3.6000, 0.0000, 0.0000)]
docstr_tok: ["Select","the","scenes","at","which","a","video","clip","can","be","reproduced","as","the","smoothest","possible","way",",","mainly","oriented","for","the","creation","of","GIF","images",".","Parameters","--","--","--","--","--","match_threshold",":","float","Maximum","distance","possible","between","frames",".","The","smaller",",","the","better-looping","the","GIFs","are",".","min_time_span",":","float","Minimum","duration","for","a","scene",".","Only","matches","with","a","duration","longer","than","the","value","passed","to","this","parameters","will","be","extracted",".","nomatch_threshold",":","float",",","optional","Minimum","distance","possible","between","frames",".","If","is","``","None","``",",","then","it","is","chosen","equal","to","``","match_threshold","``",".","time_distance",":","float",",","optional","Minimum","time","offset","possible","between","matches",".","Returns","--","--","--","-","FramesMatches",":","New","instance","of","the","class","with","the","selected","scenes",".","Examples","--","--","--","--",">",">",">","from","pprint","import","pprint",">",">",">","from","moviepy.editor","import","*",">",">",">","from","moviepy.video.tools.cuts","import","FramesMatches",">",">",">",">",">",">","ch_clip","=","VideoFileClip","(","``","media\/chaplin.mp4","''",")",".subclip","(","1",",","4",")",">",">",">","clip","=","concatenate_videoclips","(","[","ch_clip.time_mirror","(",")",",","ch_clip","]",")",">",">",">",">",">",">","result","=","FramesMatches.from_clip","(","clip",",","10",",","3",")",".select_scenes","(","...","1",",","2",",","nomatch_threshold=0",",","...",")",">",">",">","pprint","(","result",")","[","(","1.0000",",","4.0000",",","0.0000",",","0.0000",")",",","(","1.1600",",","3.8400",",","0.0000",",","0.0000",")",",","(","1.2800",",","3.7200",",","0.0000",",","0.0000",")",",","(","1.4000",",","3.6000",",","0.0000",",","0.0000",")","]"]
code: def select_scenes(
      self,
      match_threshold,
      min_time_span,
      nomatch_threshold=None,
      time_distance=0,
  ):
      """Select the scenes at which a video clip can be reproduced as the
      smoothest possible way, mainly oriented for the creation of GIF images.
  
      Parameters
      ----------
  
      match_threshold : float
        Maximum distance possible between frames. The smaller, the
        better-looping the GIFs are.
  
      min_time_span : float
        Minimum duration for a scene. Only matches with a duration longer
        than the value passed to this parameters will be extracted.
  
      nomatch_threshold : float, optional
        Minimum distance possible between frames. If is ``None``, then it is
        chosen equal to ``match_threshold``.
  
      time_distance : float, optional
        Minimum time offset possible between matches.
  
      Returns
      -------
  
      FramesMatches : New instance of the class with the selected scenes.
  
      Examples
      --------
  
      >>> from pprint import pprint
      >>> from moviepy.editor import *
      >>> from moviepy.video.tools.cuts import FramesMatches
      >>>
      >>> ch_clip = VideoFileClip("media/chaplin.mp4").subclip(1, 4)
      >>> clip = concatenate_videoclips([ch_clip.time_mirror(), ch_clip])
      >>>
      >>> result = FramesMatches.from_clip(clip, 10, 3).select_scenes(
      ...     1, 2, nomatch_threshold=0,
      ... )
      >>> pprint(result)
      [(1.0000, 4.0000, 0.0000, 0.0000),
       (1.1600, 3.8400, 0.0000, 0.0000),
       (1.2800, 3.7200, 0.0000, 0.0000),
       (1.4000, 3.6000, 0.0000, 0.0000)]
      """
      if nomatch_threshold is None:
          nomatch_threshold = match_threshold
  
      dict_starts = defaultdict(lambda: [])
      for start, end, min_distance, max_distance in self:
          dict_starts[start].append([end, min_distance, max_distance])
  
      starts_ends = sorted(dict_starts.items(), key=lambda k: k[0])
  
      result = []
      min_start = 0
      for start, ends_distances in starts_ends:
          if start < min_start:
              continue
  
          ends = [
              end
              for (end, min_distance, max_distance) in ends_distances
          ]
          great_matches = [
              (end, min_distance, max_distance)
              for (end, min_distance, max_distance) in ends_distances
              if max_distance < match_threshold
          ]
  
          great_long_matches = [
              (end, min_distance, max_distance)
              for (end, min_distance, max_distance) in great_matches
              if (end - start) > min_time_span
          ]
  
          if not great_long_matches:
              continue  # No GIF can be made starting at this time
  
          poor_matches = {
              end
              for (end, min_distance, max_distance) in ends_distances
              if min_distance > nomatch_threshold
          }
          short_matches = {end for end in ends if (end - start) <= 0.6}
  
          if not poor_matches.intersection(short_matches):
              continue
  
          end = max(
              end
              for (
                  end,
                  min_distance,
                  max_distance,
              ) in great_long_matches
          )
          end, min_distance, max_distance = next(
              e for e in great_long_matches if e[0] == end
          )
  
          result.append(
              FramesMatch(start, end, min_distance, max_distance)
          )
          min_start = start + time_distance
  
      return FramesMatches(result)
  
imports: from collections import defaultdict
  import numpy
  from moviepy.decorators import convert_parameter_to_seconds, use_clip_fps_by_default
label_desc: Use image node_id 7 for calling the FramesMatches obj's underlying member method code with example usage: obj.select_scenes(match_threshold, min_time_span, nomatch_threshold, time_distance) and returns: FramesMatches