          self.cache = dict()  # Cache for when frames must be written in correct order
          logger.debug("Initialized %s", self.__class__.__name__)
  
      @property
      def is_stream(self):
          """ Return whether the writer is a stream or images
              Writers that write to a stream have a frame_order paramater to dictate
              the order in which frames should be written out (eg. gif/ffmpeg) """
          retval = hasattr(self, "frame_order")
          return retval
  
      def output_filename(self, filename):
          """ Return the output filename with the correct folder and extension
 
</s> remove         self.re_search = re.compile(r"(\d+)(?=\.\w+$)")  # Identify frame numbers
        self.cache = dict()  # Cache for when frames must be written in correct order
 </s> add         self.re_search: re.Pattern = re.compile(r"(\d+)(?=\.\w+$)")  # Identify frame numbers
        self.cache: dict = {}  # Cache for when frames must be written in correct order </s> remove     def output_filename(self, filename):
        """ Return the output filename with the correct folder and extension
            NB: The plugin must have a config item 'format' that contains the
                file extension to use this method """
 </s> add     def output_filename(self, filename: str) -> str:
        """ Obtain the full path for the output file, including the correct extension, for the
        given input filename.

        NB: The plugin must have a config item 'format' that contains the file extension to use
        this method.

        Parameters
        ----------
        filename: str
            The input frame filename to generate the output file name for

        Returns
        -------
        str
            The full path for the output converted frame to be saved to.
        """ </s> remove         out_filename = "{}.{}".format(filename, self.config["format"])
 </s> add         out_filename = f"{filename}.{self.config['format']}" </s> remove         self.output_folder = output_folder
        self.output_dimensions = None
 </s> add         self.output_folder: str = output_folder </s> remove     def set_frame_order(self, total_count):
        """ Return the full list of frames to be converted in order """
        if self.frame_ranges is None:
 </s> add     def _get_output_filename(self) -> str:
        """ Return full path to video output file.

        The filename is the same as the input video with `"_converted"` appended to the end. The
        file extension is as selected in the plugin settings. If a file already exists with the
        given filename, then `"_1"` is appended to the end of the filename. This number iterates
        until a valid filename that does not exist is found.

        Returns
        -------
        str
            The full path to the output video filename
        """
        filename = os.path.basename(self._source_video)
        filename = os.path.splitext(filename)[0]
        ext = self.config["container"]
        idx = 0
        while True:
            out_file = f"{filename}_converted{'' if idx == 0 else f'_{idx}'}.{ext}"
            retval = os.path.join(self.output_folder, out_file)
            if not os.path.exists(retval):
                break
            idx += 1
        logger.info("Outputting to: '%s'", retval)
        return retval

    def _set_frame_order(self, total_count: int) -> List[int]:
        """ Obtain the full list of frames to be converted in order.

        Parameters
        ----------
        total_count: int
            The total number of frames to be converted

        Returns
        -------
        list
            Full list of all frame indices to be converted
        """
        if self._frame_ranges is None:
    def is_stream(self) -> bool:
        """ bool: Whether the writer outputs a stream or a series images.

        Writers that write to a stream have a frame_order paramater to dictate
        the order in which frames should be written out (eg. gif/ffmpeg) """
          self.cache = dict()  # Cache for when frames must be written in correct order
          logger.debug("Initialized %s", self.__class__.__name__)
  
      @property
    def is_stream(self) -> bool:
        """ bool: Whether the writer outputs a stream or a series images.

        Writers that write to a stream have a frame_order paramater to dictate
        the order in which frames should be written out (eg. gif/ffmpeg) """
    def is_stream(self) -> bool:
        """ bool: Whether the writer outputs a stream or a series images.

        Writers that write to a stream have a frame_order paramater to dictate
        the order in which frames should be written out (eg. gif/ffmpeg) """
    def is_stream(self) -> bool:
        """ bool: Whether the writer outputs a stream or a series images.

        Writers that write to a stream have a frame_order paramater to dictate
        the order in which frames should be written out (eg. gif/ffmpeg) """
    def is_stream(self) -> bool:
        """ bool: Whether the writer outputs a stream or a series images.

        Writers that write to a stream have a frame_order paramater to dictate
        the order in which frames should be written out (eg. gif/ffmpeg) """
          retval = hasattr(self, "frame_order")
          return retval
  
      def output_filename(self, filename):
          """ Return the output filename with the correct folder and extension
keep keep keep keep replace replace replace replace keep keep keep keep keep
 ffmpeg writer: Create new filename if output pre-exists 
plugins/convert/writer/_base.py