ffprobeでchannelの情報を読み出して解析し、その結果を反映してffmpegでmp4にエンコードします。副音声がある場合は、異なるbit rateのaudio channelを複数含むようです。ここでは120 kbs以上のchannelはエンコードするようにしています。
以下はrubyで書いた例です。コードは綺麗ではないです。無保証ですので、このコードを実行して何か不具合が生じても責任は取りません。 ffmpegとffprobeはパスを通しておきます。
ffprobeの情報はstderrのようなので、”open3″を使っています。
#!/usr/bin/ruby require "open3" require 'nkf' def get_ch(info) ch_video = ""; ch_audio = [] info.each_line{|line| if /Stream\s+\#(\d+:\d+).+Video.*,\s+(\d+x1080)/i =~ line ch_video = $1 elsif /stream\s+\#(\d+:\d+).+audio.*,\s+(\d+)\s+kb\/s/i =~ line if $2.to_i > 120 ch_audio << $1 end end } return ch_video, ch_audio.uniq end ARGV.each{|ts| if /\.ts/ =~ ts then stdout, stderr, status = Open3.capture3("ffprobe #{ts}") info = NKF.nkf("-w", stderr) v,a = get_ch(info) map_v = " -map #{v}" map_a = "" a.each{|aa| map_a += " -map #{aa}" } outfile = ts.gsub(/\.ts/, '.mp4') command = "ffmpeg -y -i #{ts} -threads 0 -f mp4" command += " -vcodec libx264 -b:v 2000k -vpre libx264 -r 30000/1001 -aspect 16:9 -s 1024x758" command += " -bufsize 20000k -maxrate 25000k -vsync 1 -async 1000 -crf 23.0 -level 30 -qmin 10" command += " -acodec libfaac -b:a 128k -ac 2 -ar 48000 #{map_v} #{map_a} #{outfile}" puts command system(command) end }
2017年1月29日修正: Videoの判定を1440×1080から\d+x1080に変更しました。1920×1080の場合もありますから。