先日公開した「楽譜付きの動画」の作り方メモ。iMovie か何かを使って、音声ファイルに静止画をくっつけていくのが簡単なんだろうけど、何となくコマンドラインでやりたくて、いろいろ模索しました。
結論から言えば、ffmpeg
を使えばできる。Mac 用の ffmpeg
は、osxexperts からバイナリをもらってきた。
まず、楽譜を画像化しないといけない。全部同じ大きさにしないといけないのが地味に面倒。ImageMagick
を使うのが簡単かな。楽譜を A5 横サイズの pdf に整形し、次のコマンドで 960×680 ピクセルの png に変換。img-1.png, img-2.png,...
という連番のファイルができる。
$ convert -density 116 score.pdf -extent 960x680 img.png
この静止画を指定時間ずつ表示する動画を作るには、次のようにすればよい。
$ ffmpeg \
-loop 1 -t 14.9 -i img-1.png \
-loop 1 -t 28.2 -i img-2.png \
-loop 1 -t 27.7 -i img-3.png \
-filter_complex "[0:v][1:v][2:v] concat=n=3:v=1:a=0 [v]" \
-map "[v]" -pix_fmt yuv420p -y out.mp4
-t
オプションで指定しているのが、各静止画の表示時間。ポイントは filter_complex
です。[0:v][1:v][2:v]
で、「0番目・1番目・2番目のストリームのビデオソース」を指定し、concat=n=3:v=1:a=0 [v]
で「3つの入力を結合してビデオストリームを1つ(名前が [v])、オーディオストリームを0個」作る。そして -map "[v]"
で結合後のストリームを指定し、その後のオプションに従って out.mp4
に書き出す。
このコマンドラインを手動で打ち込むのは骨が折れる。せっかくシーケンサを使っているんだから、ここはシーケンサに計算させたい。このため、シーケンサ (Alchemusica) を開き、タイミング計算用のトラックを作成して、楽譜を切り替える位置にダミーのイベントを置いて行く。
Alchemusica は(誰も知らないと思うけど)実は Ruby インタプリタを内蔵している。Window
メニューから Ruby Console
を開いて、次のように打ち込むと、トラック5(今回使ったタイミング計算用トラック)中のイベントの時刻が秒単位で取得できる。
% self.track(5).each { |e| puts self.tick_to_time(e.tick) }
14.856236
43.048685
70.757131
82.84784
...(中略)...
250.062446
これを利用して、コマンドラインを自動生成させる。
% i = 0; last = 0.0; self.track(5).each { |e| t = self.tick_to_time(e.tick); printf "-loop 1 -t %.1f -i img-%d.png \n", t-last, i; last = t; i += 1 }; print "-filter_complex \""; i.times { |j| print "[#{j}:v]" }; print " concat=n=#{i}:v=1:a=0 [v]\" \n"
-loop 1 -t 14.9 -i img-0.png \
-loop 1 -t 28.2 -i img-1.png \
-loop 1 -t 27.7 -i img-2.png \
-loop 1 -t 12.1 -i img-3.png \
...(中略)...
-loop 1 -t 8.8 -i img-19.png \
-filter_complex "[0:v][1:v][2:v][3:v][4:v][5:v][6:v][7:v][8:v][9:v][10:v][11:v][12:v][13:v][14:v][15:v][16:v][17:v][18:v][19:v] concat=n=20:v=1:a=0 [v]" \
生成されたコマンドラインを、次のシェルスクリプトの指定位置に貼付けて保存する。これを実行すれば、指定したタイミングで画像が切り替わる動画ができあがる。
#!/bin/sh
ffmpeg \
...(先ほどの出力)...
-map "[v]" -pix_fmt yuv420p -y out.mp4
ここまではまだ画像だけなので、次にオーディオデータと結合する。
$ ffmpeg -i out.mp4 -i audio.mp3 -vcodec copy -y movie.mp4
できました。全部コマンドラインで制作したので、制作過程をシェルスクリプトの形で残しておけるのは便利。