あけましておめでとうございます。今年もよろしくお願いします。
今年の正月休みは、メンタルには健全だったが(去年は最悪だった)、積み残した仕事が半端じゃない量だった。ようやく一段落したのが 12/30 だった。それから大掃除をして、年賀状を書いて……全般的に2日ぐらい後ろにずれている感じだった。
さて、今年も正月休みは DTM をやっています。YouTube に上げる時には「楽譜付きの動画を作る」に書いたやり方で楽譜をつけているのですが、いろいろ改良しています。
まず、画像のサイズは 1280x720 にする。前に調べた時には、「画像は 1920x1080 (1080p)、音声は非圧縮」にすれば高音質 (opus251) で再生される、ということだった。その後に投稿した動画では、画像が 1280x720 (720p) でも opus251 で再生されることがわかったので、今はこちらでやっています。
1ページ分の動画を作成するのは、下のようなコマンドです。-t 20.52
は1ページ分の時間、-i p01.jpg
が1ページ分の画像、fade=in...
というオプションは、最初と最後に 0.2 秒ずつのフェードイン・フェードアウトをつけるものです。
$ ffmpeg -loop 1 -t 20.52 -i p01.jpg -vf \ "setsar=1,fade=in:st=0:d=0.2,fade=out:st=20.3:d=0.2" \
-pix_fmt yuv420p -y p01.mp4
今回少し長めの曲を処理していて、最後の方でページめくりのタイミングがずれることに気がつきました。いろいろ調べてみると、ページめくりの時刻が1フレームの時間の整数倍になってなかったため、四捨五入の誤差が累積して、ずれてしまったようです。上のコマンドで作成した動画は、フレームレートが 25 fps になっていたので、すべての時刻を 40 ミリ秒(1/25 秒)の整数倍で扱うようにした。
処理は、Alchemusica 内蔵の Ruby インタプリタを使います。まず、トラックを1つ作って、テキストメタイベントでページめくりのタイミングを埋め込んでおきます。時刻0には "title", 演奏終了のタイミングに "end" と入れておく。
次に、Alchemusica の Ruby Console を開いて、次のスクリプトを実行します。
tt = 6 # タイミングトラックの番号
offset = -0.2 # ページめくりのタイミング調整
name = nil # 直前のファイル名(@Text の中身の文字列)
last = 0 # 直前の @Text のタイミング
a = [] # ファイル名を覚えておく配列
self.track(tt).each { |e| # タイミングトラックの各イベントについて繰り返し
next if e.data[0]=="#" # '#' で始まるデータ名はコメントとして無視する
t = ((self.tick_to_time(e.tick)+offset) * 25).to_i # イベントの時刻 (40 ミリ秒単位)
if name # 「直前」があれば
dt=t-last # そこからの経過時間がそのファイルの動画の長さ
printf "ffmpeg -loop 1 -t %.2f -i %s.jpg -vf \"setsar=1,fade=in:st=0:d=0.2,fade=out:st=%.2f:d=0.2\" -pix_fmt yuv420p -y %s.mp4\n", dt*0.04, name, (dt-5)*0.04, name # 動画作成コマンドを出力
a.push(name) # 出力した名前を覚えておく
last=t # nameのタイミング(オフセット込み)
end
name=e.data # 次に使うファイル名
}
print "(for f in #{a.join(' ')}; do echo \"file $f.mp4\"; done) >files.txt\n" # 作成した動画を集めるためのシェルスクリプト
見やすいように改行してコメントを入れていますが、実際には1行に詰め込まないといけません。「コメント+改行」をすべてセミコロン1個に置き換えて、Ruby Console にペーストします。次のようになります。
tt=6;offset=-0.2;name=nil;last=0;a=[];self.track(tt).each{|e| next if e.data[0]=="#";t=((self.tick_to_time(e.tick)+offset)*25).to_i; if name;dt=t-last;printf "ffmpeg -loop 1 -t %.2f -i %s.jpg -vf \"setsar=1,fade=in:st=0:d=0.2,fade=out:st=%.2f:d=0.2\" -pix_fmt yuv420p -y %s.mp4\n",dt*0.04,name,(dt-5)*0.04,name; a.push(name);last=t;end;name=e.data;}; print "(for f in #{a.join(' ')}; do echo \"file $f.mp4\"; done) >files.txt\n"
Ruby Console に出力されたコードをコピーして:
下のスクリプトの # ---- Replace the following lines from Alchemusica output ----
と # ---- end Alchemusica output ----
の間に貼り付けます。
#!/bin/sh
# ---- Replace the following lines from Alchemusica output ----
# ---- end Alchemusica output ----
ffmpeg -f concat -i files.txt -codec copy -y scores.mp4
rm files.txt
ffmpeg -i scores.mp4 -i ../PARTITA_revised.flac -vcodec copy -acodec copy -strict -2 -y movie.mp4
画像は、title.jpg, p01.jpg, ... と1ページずつ順に、1280x720 サイズで作成します。
音声は、Alchemusica で AIFF, 48000 Hz で録音して:
Audacity に読み込み、全選択して「増幅」を選び、New Peak Amplitude を -1 dB にしてレベル調整。(-1 dB に特に根拠はありません。みなさんレベル調整はどうしてるのかな?)
FLAC 形式で書き出します。
先ほどのスクリプトを実行すると、動画が作成されます。20分の楽曲で、170 MB。ずっとハードディスクに置いていると容量を圧迫するけど、一時的に作業するには特に問題ないサイズ。