音声ファイルと画像1枚からニコニコ動画用の動画を作る

趣味でSaGa2の「必殺の一撃」のアレンジをGarageBandで作ってみた(id:witchmakers:20090909)、というのがこの間の話。せっかくだからYouTubeニコニコ動画に投稿しようと思ったけれども、あくまで「動画」なので、音声ファイルをそのまま投稿することはできない。

作った音にぴったり合うかっこいいムービーをつける、というのが理想ではあるが、あいにく自分一人ではそこまでのスキルがないしツールも持ち合わせていなかった。だから、音楽がメインの動画を投稿する人がよくやっている、「1枚の画像+音声」(複数枚のこともあるので、紙芝居方式?)でやってみることにした。

道具はフリーの動画エンコードツールであるffmpegを使うと決めた。簡単にできるだろうと高をくくっていたら案外苦労したので、うまくやるコツをメモしておきたい。なお同様の方法がニコニコ動画でもYouTubeでも通用すると思われるが、細かい部分が異なるため、以下ではニコニコ動画限定の話とさせていただく。

準備

自前の環境はMac OS X 10.6.1。MacPortsffmpeg 0.5 Revision 5をインストールしている。ffmpegは最近割と頻繁にアップデートしているようなのでバージョンは新しくしておくとよいだろう。また画像を加工するのにImageMagickを使った。このほか、動画のプレビュー用にVLCもインストールしている。

投稿する動画のアスペクト比は4:3、使用する画像は1枚(複数毎で紙芝居のようにすることもできるようだが、今回は調べていない)とする。

高音質を維持する

音楽を聞かせたい場合の動画の投稿では、音質を犠牲にしてはいけない。ニコニコ動画では投稿した動画のフォーマットやビットレートによっては、投稿された動画をニコニコ動画のサーバー側で再エンコードし、その結果がニコニコ動画プレイヤーで見れる動画になる。再エンコードされると音楽としては聞くに堪えない音質に落ちてしまう(同じことはYouTubeについてもいえるようである)。

エンコードを回避するためのコンフィギュレーションとして、エンコード設定 - ニコニコ動画まとめwikiを参考にし、今回は「形式:MP4、映像コーデック:H.264、音声コーデック:AAC-LC」を選択した。

注意すべきはビットレート制限である。音声ファイル用にそれなりのビットレートを確保するので、そのぶん動画を犠牲にする。画像を1枚しか使わないので、フレームレートはぎりぎりまで下げる。

素材を用意する

ニコニコ動画用のサイズである512x384pixelsの画像をImageMagickなどを用いて用意する。出力フォーマットはJPEGにする。適宜必要なところをトリムしたり縮小したりする。トリムする際の注意として、元画像にExif情報が残っており、Exif情報における画像のサイズとトリムした後のサイズが異なると、ffmpegExif情報を使ってしまいアスペクトがおかしくなるなど不具合が起きる。そこでExifを削除する。このためにはconvertコマンドの-thumbnailオプションが使えるようである。

音声は最終的に使うフォーマットを最初から用意し、音質の劣化を避けるためこれ以上エンコードをせずコピーして使う。今回は128kbps CBRでエンコードしたAAC-LCファイル(ファイル名sound.m4a)となる。

音声ファイルの再生時間を知る

作成する動画の長さは音声ファイルの再生時間に合わせるものとする。それをどうやって知るか?普通は何かしらのプレイヤーで開けば秒まではわかる。しかしループ前提で動画を作るなどの場合、小数点以下の秒に関する情報も欲しい。それを知ることのできるプレイヤーもあるだろう。

ここではやや条件を選ぶが簡便な方法を紹介する。もしMac OS XLeopard)以降を使っているなら、ファイルのメタデータに再生時間が書き込んであり、それを取得することが可能なようだ。

$ mdls -name kMDItemDurationSeconds -raw sound.m4a
# => 131.2616666666667

mdlsコマンドのその他の使い方はmanを参照されたい。

1枚の画像から、映像だけの動画ファイルを生成する

用意した画像をbg.jpgという名前にしたとする。

$ ffmpeg -y -f image2 -r 1 -loop_input -t 132.3 -vcodec 'copy' -i bg.jpg out.avi

この段階で作成する動画ファイルの再生時間は音声ファイルの再生時間より少しだけ長くとる(短いと音声を合成したときに音声の方が途中で切れる)。

これで、out.aviという名前で再生時間が132.3秒、1fpsの音声なしでただ指定した画像が表示されるだけの動画が生成される。
ffmpegのオプションの意味についてはmanおよびffmpeg -hなどで確認されたい。なお、ffmpegはオプションを指定する順番によってうまくいったりいかなかったりするようなので注意。

映像だけの動画ファイルと音声ファイルを合成する

$ ffmpeg -y -i out.avi -vcodec 'copy' -i sound.m4a -acodec 'copy' movie.avi

movie.aviという名前で映像と音声の両方のデータを持つ動画ファイルが生成される。

なお、音声ファイルのコーデックやビットレートなどを変更することも可能だが、エンコードを重ねると音質はだんだん落ちていくので、最初に用意したものをそのまま利用するようにしている。それを見越して、最初からAAC-LCの音声ファイルを用意している。

ニコニコ動画用にエンコードする

$ ffmpeg -y -i movie.avi -f mp4 -acodec 'copy' -vcodec libx264 -vpre hq music.mp4

vpreオプションを忘れるとエラーになるようなので注意。(see also http://rob.opendot.cl/index.php/useful-stuff/ffmpeg-x264-encoding-guide/

なお、ffmpegで使えるフォーマット一覧はffmpeg -formatsで確認できる。結果が長いのでさらにgrepするなどして必要な情報だけ抽出するとよい。


これで以上である。YouTubeにアップする場合などもこれにアレンジを利かせることでできるのではないかと思う。

ffmpegはオプションが多い上、これを使うステップが3つもあって面倒なので、これを簡略化するためのシェルスクリプトを書いた。