          retval = self._phase_index == len(self._phases) - 1
          logger.trace(retval)  # type: ignore
          return retval
  
      def reset_phase_index(self) -> None:
          """ Reset the current phase index back to 0. Used for when batch processing is used in
          extract. """
          self._phase_index = 0
 
</s> remove     def _skip_num(self) -> int:
        """ int: Number of frames to skip if extract_every_n has been provided """
        return self._args.extract_every_n if hasattr(self._args, "extract_every_n") else 1
 </s> add     def embeddings(self) -> np.ndarray:
        """ :class:`numpy.ndarray`: The filter embeddings"""
        if self._embeddings and all(np.any(e) for e in self._embeddings):
            retval = np.concatenate(self._embeddings, axis=0)
        else:
            retval = np.array([])
        return retval </s> remove     def _set_skip_list(self) -> None:
        """ Add the skip list to the image loader
 </s> add     @property
    def n_embeddings(self) -> np.ndarray:
        """ :class:`numpy.ndarray`: The n-filter embeddings"""
        if self._nembeddings and all(np.any(e) for e in self._nembeddings):
            retval = np.concatenate(self._nembeddings, axis=0)
        else:
            retval = np.array([])
        return retval </s> remove         skip_list = []
        for idx, filename in enumerate(self._images.file_list):
            if idx % self._skip_num != 0:
                logger.trace("Adding image '%s' to skip list due to "  # type: ignore
                             "extract_every_n = %s", filename, self._skip_num)
                skip_list.append(idx)
            # Items may be in the alignments file if skip-existing[-faces] is selected
            elif os.path.basename(filename) in self._alignments.data:
                self._existing_count += 1
                logger.trace("Removing image: '%s' due to previously existing",  # type: ignore
                             filename)
                skip_list.append(idx)
        if self._existing_count != 0:
            logger.info("Skipping %s frames due to skip_existing/skip_existing_faces.",
                        self._existing_count)
        logger.debug("Adding skip list: %s", skip_list)
        self._images.add_skip_list(skip_list)
 </s> add  </s> remove         retval = np.frombuffer(png_write_meta(retval.tobytes(), metadata), dtype="uint8")
 </s> add         retval = png_write_meta(retval.tobytes(), metadata) </s> remove     def process(self):
 </s> add     def process(self) -> None:
    @property
    def aligner(self) -> "Aligner":
        """ The currently selected aligner plugin """
        assert self._align is not None
        return self._align

    @property
    def recognition(self) -> "Identity":
        """ The currently selected recognition plugin """
        assert self._recognition is not None
        return self._recognition

          retval = self._phase_index == len(self._phases) - 1
          logger.trace(retval)  # type: ignore
          return retval
  
    @property
    def aligner(self) -> "Aligner":
        """ The currently selected aligner plugin """
        assert self._align is not None
        return self._align

    @property
    def recognition(self) -> "Identity":
        """ The currently selected recognition plugin """
        assert self._recognition is not None
        return self._recognition

      def reset_phase_index(self) -> None:
          """ Reset the current phase index back to 0. Used for when batch processing is used in
          extract. """
          self._phase_index = 0
keep keep keep add keep keep keep keep
 Update Face Filter
  - Remove old face filter
  - plugins.extract.pipeline: Expose plugins directly
  - Change `is_aligned` from plugin level to ExtractMedia level
  - Allow extract pipeline to take faceswap aligned images
  - Add ability for recognition plugins to accept aligned faces as input
  - Add face filter to recognition plugin
  - Move extractor pipeline IO ops to own class 
plugins/extract/pipeline.py