You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: ugoira.rb
    path of file: ./repos/danbooru/app/logical/media_file
    
    the code of the file until where you have to start completion: # frozen_string_literal: true

# A MediaFile for a Pixiv ugoira file.
#
# A Pixiv ugoira is an animation format that consists of a zip file containing
# JPEG or PNG images, one per frame, plus a JSON object containing the
# inter-frame delay timings. Each frame can have a different delay, therefore
# ugoiras can have a variable framerate. The frame data isn't stored inside the
# zip file, so it must be passed around separately.
class MediaFile::Ugoira < MediaFile
  class Error < StandardError; end
  attr_accessor :frame_delays

  def initialize(file, frame_delays: [], **options)
    super(file, **options)
    @frame_delays = frame_delays
  end

  def close
    super
    @preview_frame&.close
    # XXX should clean up `convert` too
  end

  def metadata
    super.merge("Ugoira:FrameDelays" => frame_delays)
  end

  def dimensions
    preview_frame.dimensions
  en
    
  def convert
    raise NotImplementedError, "can't convert ugoira to webm: ffmpeg or mkvmerge not installed" unless self.class.videos_enabled?
    raise RuntimeError, "can't convert ugoira to webm: no ugoira frame data was provided" unless frame_delays.present?

    Danbooru::Archive.extract!(file) do |tmpdir, filenames|
      output_file = Danbooru::Tempfile.new(["danbooru-ugoira-conversion-#{md5}-", ".webm"], binmode: true)

      # Duplicate last frame to avoid it being displayed only for a very short amount of time.
      last_file_name = File.basename(filenames.last)
      last_index, file_ext = last_file_name.split(".")
      new_last_filename = "#{"%06d" % (last_index.to_i + 1)}.#{file_ext}"
      path_from = File.join(tmpdir, last_file_name)
      path_to = File.join(tmpdir, new_last_filename)
      FileUtils.cp(path_from, path_to)

      delay_sum = 0
      timecodes_path = File.join(tmpdir, "timecodes.tc")
      File.open(timecodes_path, "w+") do |f|
        f.write("# timecode format v2\n")
        frame_delays.each do |delay|
          f.write("#{delay_sum}\n")
          delay_sum += delay
        end
        f.write("#{delay_sum}\n")
        f.write("#{delay_sum}\n")
      end

      ffmpeg_out, status = Open3.capture2e("ffmpeg -i #{tmpdir}/%06d.#{file_ext} -codec:v libvpx-vp9 -crf 12 -b:v 0 -an -threads 8 -tile-columns 2 -tile-rows 1 -row-mt 1 -pass 1 -passlogfile #{tmpdir}/ffmpeg2pass -f null /dev/null")
      raise Error, "ffmpeg failed: #{ffmpeg_out}" unless status.success?

      ffmpeg_out, status = Open3.capture2e("ffmpeg -i #{tmpdir}/%06d.#{file_ext} -codec:v libvpx-vp9 -crf 12 -b:v 0 -an -threads 8 -tile-columns 2 -tile-rows 1 -row-mt 1 -pass 2 -passlogfile #{tmpdir}/ffmpeg2pass #{tmpdir}/tmp.webm")
      raise Error, "ffmpeg failed: #{ffmpeg_out}" unless status.success?

      mkvmerge_out, status = Open3.capture2e("mkvmerge -o #{output_file.path} --webm --timecodes 0:#{tmpdir}/timecodes.tc #{tmpdir}/tmp.webm")
      raise Error, "mkvmerge failed: #{mkvmerge_out}" unless status.success?

      MediaFile.open(output_file)
    end
  end