      def __init__(self, output_folder, total_count, frame_ranges, source_video, **kwargs):
          super().__init__(output_folder, **kwargs)
          logger.debug("total_count: %s, frame_ranges: %s, source_video: '%s'",
                       total_count, frame_ranges, source_video)
          self.source_video = source_video
          self.frame_ranges = frame_ranges
          self.frame_order = self.set_frame_order(total_count)
          self.output_dimensions = None  # Fix dims of 1st frame in case of different sized images
          self.writer = None  # Need to know dimensions of first frame, so set writer then
  
      @property
      def video_file(self):
          """ Return full path to video output """
          filename = os.path.basename(self.source_video)
          filename = os.path.splitext(filename)[0]
          filename = "{}_converted.{}".format(filename, self.config["container"])
          retval = os.path.join(self.output_folder, filename)
          logger.debug(retval)
          return retval
  
      @property
      def video_tmp_file(self):
          """ Temporary video file, prior to muxing final audio """
          path, filename = os.path.split(self.video_file)
 
</s> remove     """ Video output writer using imageio """
    def __init__(self, output_folder, total_count, frame_ranges, source_video, **kwargs):
 </s> add     """ Video output writer using imageio-ffmpeg.

    Parameters
    ----------
    output_folder: str
        The folder to save the output video to
    total_count: int
        The total number of frames to be converted
    frame_ranges: list or ``None``
        List of integers for any explicit frame ranges to be converted or ``None`` if all frames
        are to be converted
    source_video: str
        The full path to the source video for obtaining fps and audio
    kwargs: dict
        Any additional standard :class:`plugins.convert.writer._base.Output` key word arguments.
    """
    def __init__(self,
                 output_folder: str,
                 total_count: int,
                 frame_ranges: Optional[List[int]],
                 source_video: str,
                 **kwargs) -> None: </s> remove     def video_tmp_file(self):
        """ Temporary video file, prior to muxing final audio """
        path, filename = os.path.split(self.video_file)
        retval = os.path.join(path, "__tmp_{}".format(filename))
 </s> add     def _video_tmp_file(self) -> str:
        """ str: Full path to the temporary video file that is generated prior to muxing final
        audio. """
        path, filename = os.path.split(self._output_filename)
        retval = os.path.join(path, f"__tmp_{filename}") </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: </s> remove     def video_fps(self):
        """ Return the fps of source video """
        reader = imageio.get_reader(self.source_video, "ffmpeg")
 </s> add     def _video_fps(self) -> float:
        """ float: The fps of the source video. """
        reader = imageio.get_reader(self._source_video, "ffmpeg") </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.
        """
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
      def __init__(self, output_folder, total_count, frame_ranges, source_video, **kwargs):
          super().__init__(output_folder, **kwargs)
          logger.debug("total_count: %s, frame_ranges: %s, source_video: '%s'",
                       total_count, frame_ranges, source_video)
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
        self._source_video: str = source_video
        self._output_filename: str = self._get_output_filename()
        self._frame_ranges: Optional[List[int]] = frame_ranges
        self._frame_order: List[int] = self._set_frame_order(total_count)
        self._output_dimensions: Optional[str] = None  # Fix dims on 1st received frame
        # Need to know dimensions of first frame, so set writer then
        self._writer: Optional[imageio.plugins.ffmpeg.FfmpegFormat.Writer] = None
  
      @property
      def video_tmp_file(self):
          """ Temporary video file, prior to muxing final audio """
          path, filename = os.path.split(self.video_file)
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 ffmpeg writer: Create new filename if output pre-exists 
plugins/convert/writer/ffmpeg.py