  
  class BackgroundGenerator(threading.Thread):
      """ Run a queue in the background. From:
          https://stackoverflow.com/questions/7323664/python-generator-pre-fetch """
      def __init__(self, generator, prefetch=1): #See below why prefetch count is flawed
          threading.Thread.__init__(self)
          self.queue = Queue.Queue(prefetch)
          self.generator = generator
          self.daemon = True
          self.start()
 
</s> remove         This class is initialised in each of the argparsers for the relevant command,
        then execute script is called within their set_default function """
 </s> add         This class is initialised in each of the argparsers for the relevant
        command, then execute script is called within their set_default
        function. """ </s> remove         for filename in tqdm(self.images.input_images):
 </s> add         for filename in tqdm(self.images.input_images, file=sys.stdout): </s> remove             Note: put blocks only if put is called while queue has already reached max size
            => this makes 2 prefetched items! One in the queue, one waiting for insertion! """
 </s> add             Note: put blocks only if put is called while queue has already
            reached max size => this makes 2 prefetched items! One in the
            queue, one waiting for insertion! """ </s> remove             os.path.expanduser(values)))
 </s> add                 os.path.expanduser(values)))


class DirFullPaths(FullPaths):
    """ Class that gui uses to determine if you need to open a directory """
    pass


class FileFullPaths(FullPaths):
    """
    Class that gui uses to determine if you need to open a file.

    Filetypes added as an argparse argument must be an iterable, i.e. a
    list of lists, tuple of tuples, list of tuples etc... formatted like so:
        [("File Type", ["*.ext", "*.extension"])]
    A more realistic example:
        [("Video File", ["*.mkv", "mp4", "webm"])]

    If the file extensions are not prepended with '*.', use the
    prep_filetypes() method to format them in the arguments_list.
    """
    def __init__(self, option_strings, dest, nargs=None, filetypes=None,
                 **kwargs):
        super(FileFullPaths, self).__init__(option_strings, dest, **kwargs)
        if nargs is not None:
            raise ValueError("nargs not allowed")
        self.filetypes = filetypes

    @staticmethod
    def prep_filetypes(filetypes):
        all_files = ("All Files", "*.*")
        filetypes_l = list()
        for i in range(len(filetypes)):
            filetypes_l.append(FileFullPaths._process_filetypes(filetypes[i]))
        filetypes_l.append(all_files)
        return tuple(filetypes_l)

    @staticmethod
    def _process_filetypes(filetypes):
        """        """
        if filetypes is None:
            return None

        filetypes_name = filetypes[0]
        filetypes_l = filetypes[1]
        if (type(filetypes_l) == list or type(filetypes_l) == tuple) \
                and all("*." in i for i in filetypes_l):
            return filetypes  # assume filetypes properly formatted

        if type(filetypes_l) != list and type(filetypes_l) != tuple:
            raise ValueError("The filetypes extensions list was "
                             "neither a list nor a tuple: "
                             "{}".format(filetypes_l))

        filetypes_list = list()
        for i in range(len(filetypes_l)):
            filetype = filetypes_l[i].strip("*.")
            filetype = filetype.strip(';')
            filetypes_list.append("*." + filetype)
        return filetypes_name, filetypes_list

    def _get_kwargs(self):
        names = [
            'option_strings',
            'dest',
            'nargs',
            'const',
            'default',
            'type',
            'choices',
            'help',
            'metavar',
            'filetypes'
        ]
        return [(name, getattr(self, name)) for name in names]


class ComboFullPaths(FileFullPaths):
    """
    Class that gui uses to determine if you need to open a file or a
    directory based on which action you are choosing
    """
    def __init__(self,  option_strings, dest, nargs=None, filetypes=None,
                 actions_open_type=None, **kwargs):
        if nargs is not None:
            raise ValueError("nargs not allowed")
        super(ComboFullPaths, self).__init__(option_strings, dest,
                                             filetypes=None, **kwargs)

        self.actions_open_type = actions_open_type
        self.filetypes = filetypes

    @staticmethod
    def prep_filetypes(filetypes):
        all_files = ("All Files", "*.*")
        filetypes_d = dict()
        for k, v in filetypes.items():
            filetypes_d[k] = ()
            if v is None:
                filetypes_d[k] = None
                continue
            filetypes_l = list()
            for i in range(len(v)):
                filetypes_l.append(ComboFullPaths._process_filetypes(v[i]))
            filetypes_d[k] = (tuple(filetypes_l), all_files)
        return filetypes_d

    def _get_kwargs(self):
        names = [
            'option_strings',
            'dest',
            'nargs',
            'const',
            'default',
            'type',
            'choices',
            'help',
            'metavar',
            'filetypes',
            'actions_open_type'
        ]
        return [(name, getattr(self, name)) for name in names]

    def __init__(self, generator, prefetch=1):  # See below why prefetch count is flawed
  
  class BackgroundGenerator(threading.Thread):
      """ Run a queue in the background. From:
          https://stackoverflow.com/questions/7323664/python-generator-pre-fetch """
    def __init__(self, generator, prefetch=1):  # See below why prefetch count is flawed
          threading.Thread.__init__(self)
          self.queue = Queue.Queue(prefetch)
          self.generator = generator
          self.daemon = True
          self.start()
keep keep keep keep replace keep keep keep keep keep
 Adding new tool effmpeg ("easy"-ffmpeg) with gui support. Extend gui functionality to support filetypes. Re-opening PR. (#373)

* Pre push commit.
Add filetypes support to gui through new classes in lib/cli.py
Add various new functions to tools/effmpeg.py

* Finish developing basic effmpeg functionality.
Ready for public alpha test.

* Add ffmpy to requirements.
Fix gen-vid to allow specifying a new file in GUI.
Fix extract throwing an error when supplied with a valid directory.

Add two new gui user pop interactions: save (allows you to create new
files/directories) and nothing (disables the prompt button when it's not
needed).
Improve logic and argument processing in effmpeg.

* Fix post merge bugs.
Reformat tools.py to match the new style of faceswap.py
Fix some whitespace issues.

* Fix matplotlib.use() being called after pyplot was imported.

* Fix various effmpeg bugs and add ability do terminate nested subprocess
to GUI.

effmpeg changes:
Fix get-fps not printing to terminal.
Fix mux-audio not working.
Add verbosity option. If verbose is not specified than ffmpeg output is
reduced with the -hide_banner flag.

scripts/gui.py changes:
Add ability to terminate nested subprocesses, i.e. the following type of
process tree should now be terminated safely:
gui -> command -> command-subprocess
               -> command-subprocess -> command-sub-subprocess

* Add functionality to tools/effmpeg.py, fix some docstring and print statement issues in some files.

tools/effmpeg.py:
Transpose choices now display detailed name in GUI, while in cli they can
still be entered as a number or the full command name.
Add quiet option to effmpeg that only shows critical ffmpeg errors.
Improve user input handling.

lib/cli.py; scripts/convert.py; scripts/extract.py; scripts/train.py:
Fix some line length issues and typos in docstrings, help text and print statements.
Fix some whitespace issues.

lib/cli.py:
Add filetypes to '--alignments' argument.
Change argument action to DirFullPaths where appropriate.

* Bug fixes and improvements to tools/effmpeg.py

Fix bug where duration would not be used even when end time was not set.
Add option to specify output filetype for extraction.
Enchance gen-vid to be able to generate a video from images that were zero padded to any arbitrary number, and not just 5.
Enchance gen-vid to be able to use any of the image formats that a video can be extracted into.
Improve gen-vid output video quality.
Minor code quality improvements and ffmpeg argument formatting improvements.

* Remove dependency on psutil in scripts/gui.py and various small improvements.

lib/utils.py:
Add _image_extensions and _video_extensions as global variables to make them easily portable across all of faceswap.
Fix lack of new lines between function and class declarions to conform to PEP8.
Fix some typos and line length issues in doctsrings and comments.

scripts/convert.py:
Make tqdm print to stdout.

scripts/extract.py:
Make tqdm print to stdout.
Apply workaround for occasional TqdmSynchronisationWarning being thrown.
Fix some typos and line length issues in doctsrings and comments.

scripts/fsmedia.py:
Did TODO in scripts/fsmedia.py in Faces.load_extractor(): TODO Pass extractor_name as argument
Fix lack of new lines between function and class declarions to conform to PEP8.
Fix some typos and line length issues in doctsrings and comments.
Change 2 print statements to use format() for string formatting instead of the old '%'.

scripts/gui.py:
Refactor subprocess generation and termination to remove dependency on psutil.
Fix some typos and line length issues in comments.

tools/effmpeg.py
Refactor DataItem class to use new lib/utils.py global media file extensions.
Improve ffmpeg subprocess termination handling. 
lib/utils.py