Filter::ffmpeg - ffmpeg でエンコード処理

Pragger 用のプラグインです。
enclosure.url のファイルを ffmpegエンコードします。


未完成品です、一応動作は確認していますけれどね。
お試し版感覚で使ってください。


profile は外部ファイル化して、適宜読み込んで使いたいかも。

require 'kconv'

module FFmpeg
  class Helper
    def initialize(file)
      @profile = {
        :ipod_touch => {
          :f        => 'mp4',
          :bufsize  => '2000k',
          :maxrate  => '768k',
          :s        => '320x240',
          :b        => '512k',
          :bt       => '512k',
          :vcodec   => 'libx264',
          :acodec   => 'libfaac',
          :ac       => '2',
          :ab       => '128k',
        },
        :audio => {
          :ac      => '2',
          :ab      => '128k',
          :ar      => '44100',
        },
      }

      @file            = file
      @option          = {}
      @extended_option = ''
    end

    def set_profile(name)
      if @profile.key?(name)
        @option.merge!(@profile[name])
      else
        $stderr.puts "not found profile; #{name}"
      end
    end

    def set_option(opt)
      @option.merge!(opt)
    end

    def extended_option(s)
      @extended_option = s
    end

    def execute(infile, outfile)
      argument = []

      argument << %Q{#{@file} -y -i "#{infile}" }

      @option.each {|k, v|
        argument << "-#{k} #{v} "
      }

      argument << %Q{ #{@extended_option} "#{outfile}" 2>&1}

      command = argument.join('')

      puts "#{command}"

      io = IO.popen("#{command}", "r");
      io.each("\r") {|line|
        puts line
      }
      io.close

      return $?
    end
  end
end

# TODO: 
@ffmpeg_profile = <<EOD
ipod_touch:
  f:       'mp4'
  bufsize: '2000k'
  maxrate: '768k'
  s:       '320x240'
  b:       '512k'
  bt:      '512k'
  vcodec:  'libx264'
  acodec:  'libfaac'
  ac:      '2'
  ab:      '128k'
EOD

def ffmpeg(config, data)
  return data  unless config.key?('dir') && config.key?('encoding')

  profile = YAML.load(@ffmpeg_profile)

  time = %Q{"#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}"}

  ffmpeg = FFmpeg::Helper.new(config['command'] || "ffmpeg")

  ffmpeg.set_option(profile[config['profile']]) if profile.key?(config['profile'])
  ffmpeg.set_option(:timestamp => time)
  ffmpeg.set_option(:f => config['format'])  if config.key?('format')
  ffmpeg.extended_option(config['extra_options'])  if config.key?('extra_options')

  data.each {|item|
    # TODO:
    filename = item.title + '.mpg'
    if config.key?('filename')
      filename = config['filename'].gsub(/%(.+?)%/) {|s|
        item.send($1) rescue s
      }
    end

    ffmpeg.set_option(:title => %Q{"#{item.title.send('to' + config['encoding'])}"})
#   $stderr.puts "filename: #{filename}"

    dest = File.expand_path(config['dir'] + '/' + filename)
    src  = item.enclosure.url.send('to' + config['encoding'])

    ffmpeg.execute(src, dest.send('to' + config['encoding']))

    item.enclosure.url = dest.toutf8
  }

  data
end