みかづきの色々

デバイス(スマホからキャンプ用品まで)とかプログラミングとか中心のいろいろ試験的なブログ。

昔作ったスクリプトの改造。

昔、こんなのを使っていた。

#!/bin/sh
Fn=orz.jpg
Tim=00:04:45
Out=OUT.avi

if [ "$1" != "" ];then
  Tim=$1
  if [ "$2" != "" ];then
    Fn=$2
    Out=`echo $Fn|sed s/.jpg/.avi/`
    Out=`echo $Out|sed s/.png/.avi/`
    Flv=`echo $Out|sed s/.avi/.flv/`
    #Ogv=`echo $Out|sed s/.avi/.ogv/`
    Wav=`echo $Out|sed s/.avi/.wav/`
    Mp3=`echo $Out|sed s/.avi/.mp3/`
    Ogg=`echo $Out|sed s/.avi/.ogg/`
  fi
else
  echo "[usage] $0 (time) (jpg)"
fi

# MP3があればそれを使う。なければ作る。
if [ -f "$Mp3" ];then
  echo "$Mp3を使用します。"
  Wav=$Mp3
else
  if [ -f "$Wav" ];then
    echo "$Mp3がないので、$Wavから作成します。"
    lame $Wav $Mp3
    Wav=$Mp3
  else
    echo "MP3かWAVを用意してください。"
    exit
  fi
fi
ffmpeg -f image2 -loop 1 -t $Tim -r 2 -i $Fn $Out
if [ -f "$Ogg" ];then
  ffmpeg -i $Out -i $Ogg $Flv
  echo -n ""
else
  ffmpeg -i $Out -i $Wav -acodec copy $Flv
  echo -n ""
fi

これは、wavファイルと画像ファイルを組み合わせ、固定画像のflvムービーを作成するもの。ニコ動にアップロードする動画を作成する補助スクリプトで、しばらく使っていた。
だけどこれには以下の問題があった。

  • いちいちwavファイルの演奏時間を調べなくてはならない。


はっきりいって面倒くさかったので、ここを自動にするついでに Ruby で作りなおした。

以下のように。

#!/usr/bin/ruby -Ku

require "fileutils"

class String
  def sufchange(suf)
    fb = self.gsub /\..*$/,''
    fb += ".#{suf}"
    fb
  end
  def getDuration
    r = `ffmpeg -i \"#{self}\" 2> /tmp/#{$$}`
    if r == ""
      open("/tmp/#{$$}","r").each{|e|
        if e =~ /Duration/
          r = e.clone
          s = r.split " "
          s.each{|x|
            p x
            if x =~ /\d:\d/
              r = x.gsub /\..*$/,''
              break
            end
          }
          break
        end
      }
    end
    FileUtils.remove("/tmp/#{$$}")
    r
  end
  def wav2flv
    fn = self.clone
    tim = fn.sufchange("wav").getDuration
    avi = fn.sufchange("avi")
    flv = fn.sufchange("flv")
    wav = fn.sufchange("wav")
    mp3 = fn.sufchange("mp3")
    jpg = fn.sufchange("jpg")
    p jpg,tim
    photo = nil
    if tim =~ /:/ && tim != "00:00:00"
      if File.exist?(mp3) == false
        system "lame \"#{wav}\" \"#{mp3}\""
      end
      if File.exist?(jpg) == true
        photo = jpg.clone 
      else
        png = fn.sufchange("png")
        if File.exist?(png) == true
          photo = png.clone 
        end
      end
      if photo != nil
        system "ffmpeg -f image2 -loop 1 -t #{tim} -r 2 -i \"#{photo}\" \"#{avi}\""
        if File.exist?(avi) == true
          system "ffmpeg -i \"#{avi}\" -i \"#{mp3}\" -acodec copy \"#{flv}\""
        else
          print "AVIが作られなかったようです。確認ください。(#{avi})\n"
        end
      else
        print "同名の画像写真がありません。(#{tim})\n"
      end
    else
      print "時間が正しく取得できません(#{tim})\n"
    end
    # jpgがあるなら、jpgをあてはめる。
  end
end

#############

if ARGV.length > 0
  ARGV.each{|fn|
    print "ファイル存在確認:"
    if File.exist?(fn) == true
      print "OK(#{fn})\n" 
      fn.wav2flv
    else
      print "存在しない(#{fn})\n" 
      fna = fn + ".wav"
      if File.exist?(fna) == true
        print "発見しました!#{fna})\n" 
        fna.wav2flv
      else
        print "こちらも、ありませんでした……#{fna})\n" 
      end
    end
  }
else
  print <<EOM
Usage: makemovie file.wav
    or makemovie file.jpg

同名のwavと貼り付ける画像(jpgまたはpng)を用意してください。
用意した固定画像のムービーを作成します。

EOM
end

ffmpeglameを使用する。処理手順は以下の通り。

  1. ffmpeg -i i.wav で実行時間を取得する。
  2. 画像ファイルから静止画&無音のAVIを作る。(ただし小数点以下秒は切り捨てる)
  3. AVIと音声をくっつけて動画とする。

なお、 file.wav に対する file.jpg(またはpng)が必要です。
その画像を表示して音声をひたすら再生するムービーができあがります。

環境は以下。
テスト環境は Debian wheezy である。Mac上に作られた仮想環境上で動いている Debian wheezy 上の開発用コンテナ上で作成された。
ffmpeg は、 debian-multimedia の apt-line を追加している。なくてもOKかもしれないが、ffmpegコンパイルオプション等が全然違うので気をつけて。apt-lineは以下だ。

deb http://www.deb-multimedia.org wheezy main non-free

うん、こんな感じかな。
実行結果は以下です。へたくそなカラオケ音声ですまない。