ラジ録2で録った「らじる★らじる」flvファイルをまとめてmp3に変換する その2

ラジ録2で録った「らじる★らじる」flvファイルをまとめてmp3に変換する - 別館 子子子子子子(ねこのここねこ)
というのを3年ほど前に書きましたが、そのまま放置していました。
ふと、サーバに入っているflvファイルをまとめて変換してしまおう、と思い立ったので、書いてみました。

require 'pathname'
require 'fileutils'
require 'shellwords'

radiorec_filepath = ARGV[0]
radiorec_pathname = Pathname.new(radiorec_filepath)

if radiorec_pathname.directory?
  is_directory = true
  radiorec_dir = radiorec_pathname
  flvs = radiorec_pathname.children.select { |file| file.extname == ".flv" }
  flvs_uniq = flvs.map{ |flv| flv.basename.to_path[/([^-]+)(?:-\d{3})?\.flv/, 1] }.uniq
  count = flvs_uniq.size
else
  is_directory = false
  radiorec_dir = radiorec_pathname.dirname
  target_name = radiorec_pathname.basename.to_path[/(.+_\d{4}_\d\d_\d\d)(?:-\d{3})?\.flv/, 1]
  flvs_uniq = [target_name]
  count = 1
end
puts "対象ファイルは"
puts flvs_uniq
puts "以上の#{count}ファイルです。"

flvs_uniq.each.with_index(1) do |flv, i|
  puts "作業#{i}/#{count}#{flv}"
  if is_directory
    target_flvs = flvs.select { |f| f.basename.to_path[/#{flv}/] }
  else
    target_flvs = radiorec_dir.children.select { |file| file.to_path[/#{target_name}[^.]*\.flv/] }
    puts target_flvs
  end
  src = radiorec_dir + "src_mp3"
  src.mkdir
  trash = radiorec_dir + "trash_flv"
  trash.mkdir unless trash.exist?
  target_flvs.each do |f|
    f_mp3_path = src + (f.basename.to_path[/(.+)\.flv/, 1] + ".mp3")
    ffmpeg_conv_command = "ffmpeg -i #{f} -ab 128k #{f_mp3_path} 2>/dev/null"
#    puts ffmpeg_conv_command
    `#{ffmpeg_conv_command}`
  end
  if src.children.size == 0
    puts "#{flv}」はファイルサイズが0のため、mp3が生成されませんでした。"
    puts
    src.rmtree
    next
  end
  ffmpeg_input = "concat:" + src.children.sort.join("|")
  ffmpeg_output = radiorec_dir + (flv + (target_flvs.size > 1 ? "#{target_flvs.size - 1}Gap】" : "") + ".mp3")
  if ffmpeg_output.exist?
    puts "既に「#{ffmpeg_output}」ファイルが存在します。別名で保存します。"
    ffmpeg_output_name = ffmpeg_output.to_path
    ffmpeg_output_name[-4, 0] = "exist"
    ffmpeg_output = Pathname.new(ffmpeg_output_name)
  end
  ffmpeg_command = %[cpulimit -l 300 -- ffmpeg -i "#{ffmpeg_input}" #{Shellwords.escape(ffmpeg_output.to_s)} 2>&1]
#  puts ffmpeg_command
#  `#{ffmpeg_command}`
  IO.popen(ffmpeg_command) do |pipe|
    pipe.each("r").inject("") do |buffer, each_line|
      buffer << each_line
      buffer = buffer.split("\n").last
      if buffer[/\r/]
        print "\r" + buffer.split("\r").first.sub(/q=\d+\.\d /, "").sub(/dup=\d+ drop=\d+ /, "").rstrip
      end
      buffer.split("\r").last
    end
  end
  
  latest_file_pathname = target_flvs.last
  ffmpeg_output.utime(latest_file_pathname.atime, latest_file_pathname.mtime)
  
  puts
  FileUtils.move(target_flvs.map(&:to_path), trash.to_path)
  src.rmtree
end

これを radiorec2flv2mp3.rb という名称で保存しました。
使い方はflvファイルが入っているディレクトリ名を指定する

$ ruby radiorec2flv2mp3.rb [path]

もしくは対象にしたいflvファイルを指定する

$ ruby radiorec2flv2mp3.rb [path.flv]

と変換してくれます。元の flv ファイルは trash_flv ディレクトリに移されていますので、まとめて削除してください。

おまけ

なお 上記リンクのコメント欄 に「flv ファイルが大量発生するのはラジ録の rtmpdump のせいではないか」というコメントをくださった方がいらっしゃり、私もそれに従って以下のように作業しました(コメント欄をそのまま引用)。

「rtmpdumpを入れ替え」とのことでしたので、ラジ録2の

/Applications/RadioRec2.app/Contents/MacOS/cores_macosx

フォルダにある rtmpdump 実行ファイル(バージョン2.4)をリネームしておき、 Homebrew でインストールした rtmpdump

https://github.com/Homebrew/homebrew/blob/master/Library/Formula/rtmpdump.rb (バージョンは2.4+20150115)

をコピーして上記フォルダへペーストしました。
rtmpdump 実行ファイルのサイズが全く違う(ラジ録2付属は1.3MBなのに Homebrew 版は33KB!)のですが、問題なく動作しているようです。ギャップが生じるかどうか、今後確認していきます。

その後も何度か flv ファイルが発生してしまっていますが、頻度は格段に減りましたので、この対策は有効だと思います。