          self._threaded_redirector("load")
          self._run_extraction()
          for thread in self._threads:
              thread.join()
          self._alignments.save()
          finalize(self._images.process_count + self._existing_count,
                   self._alignments.faces_count,
                   self._verify_output)
  
      def _threaded_redirector(self, task: str, io_args: Optional[tuple] = None) -> None:
          """ Redirect image input/output tasks to relevant queues in background thread
  
          Parameters
 
</s> remove         self._run_extraction()
 </s> add     def reload(self, detected_faces: Dict[str, ExtractMedia]) -> None:
        """ Reload images for multiple pipeline passes """
        self._threaded_redirector("reload", (detected_faces, ))

    def check_thread_error(self) -> None:
        """ Check if any errors have occurred in the running threads and raise their errors """
        for thread in self._threads:
            thread.check_and_raise_error()

    def join(self) -> None:
        """ Join all open loader threads """ </s> remove     def save(self, filename: str, image: bytes, sub_folder: Optional[str] = None) -> None:
 </s> add     def save(self,
             filename: str,
             image: Union[bytes, np.ndarray],
             sub_folder: Optional[str] = None) -> None: </s> remove             logger.error("Failed to save image '%s'. Original Error: %s", filename, err)
 </s> add             logger.error("Failed to save image '%s'. Original Error: %s", filename, str(err)) </s> remove         Should only be called from  :class:`lib.cli.launcher.ScriptExecutor`
 </s> add         if len(item.detected_faces) > 1 and is_filter:
            logger.warning("%s faces detected for filter in '%s'. These identies will not be used",
                           len(item.detected_faces), os.path.basename(item.filename))
            filelist.pop(idx)
            embeddings.pop(idx)
            return

        if len(item.detected_faces) > 1 and not is_filter:
            logger.warning("%s faces detected for nfilter in '%s'. All of these identies will be "
                           "used", len(item.detected_faces), os.path.basename(item.filename))
            embeddings[idx] = identities
            return

    def _identity_from_extractor(self, file_list: List[str], aligned: List[str]) -> None:
        """ Obtain the identity embeddings from the extraction pipeline

        Parameters
        ----------
        filesile_list: list
            List of full path to images to run through the extraction pipeline
        aligned: list
            List of full path to images that exist in attr:`filelist` that are faceswap aligned
            images </s> remove     def _check_thread_error(self) -> None:
        """ Check if any errors have occurred in the running threads and their errors """
        for thread in self._threads:
            thread.check_and_raise_error()

 </s> add 
          self._threaded_redirector("load")
          self._run_extraction()
          for thread in self._threads:
              thread.join()




  
      def _threaded_redirector(self, task: str, io_args: Optional[tuple] = None) -> None:
          """ Redirect image input/output tasks to relevant queues in background thread
  
          Parameters
keep keep keep keep replace replace replace replace keep 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 
scripts/extract.py