動画の大きさ(縦横サイズ)を調べる
ffmpeg などで動画の大きさを変更してエンコードするときに、元の動画の大きさやそこからわかるアスペクト比などを得たいことがあります。上下や左右に黒帯が付加され、コンテンツ自体のサイズと異なる場合もあります。
そこで ffmpeg や mplayer が出力した内容を使って大きさを取得してみます。(ちゃんとした仕様やソースをあたっていません。予想に依るところがあります。)
ffmpeg が出力する情報
$ ffmpeg -i input.mp4 (略) Stream #0.0(und): Video: h264 (High), yuv420p, 960x720 [PAR 479:480 DAR 479:360], 768 kb/s, 29.97 fps, 30 tbr, 90k tbn, 180k tbc (略)
ffmpeg で入力ファイルのみを指定して実行すると変換自体は行うことはできませんが、そのとき出力されるエラーの中に入力ファイルの情報が出力されます。
このときの 960x720 は縦横のドット数であり、そのあとの PAR はピクセルアスペクト比、 DAR はディスプレイアスペクト比を意味するものだと思われます。特にピクセルアスペクト比(1ドットの縦横比)が 1:1 のときはドット数がすなわち動画サイズとなりますが、それ以外のときは縦ないし横に引き伸ばした結果が動画の大きさとなるため、その値を計算する必要がでてきます。
mplayer が出力する情報
動画プレイヤーのひとつである mplayer で映像音声ともに出力をなしにした状態で 1 フレームのみ再生し、出力する情報を利用することもできます。
$ mplayer -vo null -ao null -frames 1 input.mp4 2>/dev/null (略) Movie-Aspect is 1.33:1 - prescaling to correct movie aspect. VO: [null] 960x720 => 960x722 Planar YV12 (略)
このような VO: [null] からはじまる行があり左の値がドット数、右の値がピクセルアスペクト比を加味して変換された大きさになると思われます。
変換すべき否か
ただし、今回の例で用いたファイルは、ピクセルアスペクト比 479:480 で 960x720 を 960x722 に変換しています。この場合はアスペクト比情報の方が間違って指定されており、変換しない方が映像として好ましいものだと思われます。一方で、ピクセルアスペクト比を適用した方が意図通りになるものもあります。
スクリプト
最後に個人的に使用しているスクリプトを簡単に。
#!/usr/local/bin/ruby # usage: # ./video_size.rb VIDEO_FILE [VIDEO_FILE ...] # example: # ./video_size.rb *.mp4 videos = [] ARGV.each do |arg| Dir.glob(arg) do |path| videos << path end end videos.uniq.sort.each do |path| open("| mplayer -ao null -vo null -frames 1 #{path} 2>/dev/null") do |io| w = h = nil io.each do |line| if line.strip =~ /^VO: \[null\] \d+x\d+ => (\d+)x(\d+).*$/ w = $1 h = $2 end end end unless w.nil? || h.nil? puts "%sx%s %s" % [w, h, path] else puts "Error - #{path}" end end
当然ですが mplayer が必要です。