コンピュータを楽しもう!!

今、自分が面白くていろいろやってみたことを書き綴りたいと思います。連絡先はtarosa.yでgmail.comです。

3DViewerDS用動画データの作り方

久々にNintendoDSの話題です。私のNDS用アプリ公開サイトに公開しているアプリに、3DViewerDSというものがあります。これはDSの2画面に視差のある画像を表示し、立体視するというアプリです。以下、ニコニコ動画に公開している画像です。
D

海外からの問い合わせはあるものの、日本人からの問い合わせは全く無かったので、メールでやり取りするくらいで、ブログでの解説は特に放置していたのですが、今回、動画データのフォーマットを教えて欲しいという問い合わせを、初めて日本の方からもらいました。そこで、簡単ですが、3DViewerDS用の動画データの作り方を紹介したいと思います。

私の使用ツール

基本的にニコニコ動画などにアップされている立体視動画から3DViewerDS用の動画データを作り出しています。動画データといっても、実際はNDSのVRAMのマッピングに対応した静止画データの塊です。ですので、作業としては動画から静止画を切り出すだけです。静止画の切り出しに使っているツールは3個です。

  • ffmpeg : flvやmp4ファイルから静止画データを切り出すツールです。ダウンロードはここからできます。StaticのLastestを選択すれば問題無く動くのではないでしょうか。
  • IrfanView32 : 超有名な画像ツールですよね。画像データから必要な部分を切り出すために使っています。これで左右画面用のデータを切り出しています。ダウンロードはここからできます。
  • ndsGazouConv : NDS GazouConv Ver0.5.3というbmpやjpg画像からNDSのVRAMに対応したデータに変換するツールです。自作ツールです。しかも、超手抜きで作っているので非常に低速です。ダウンロードはここからできます。

やり方の解説

それでは動画データの作り方を順に説明します。下記のニコニコ動画にfeifei22さんが投稿された動画をサンプルに使わせていただきました。
D
とりあえず、上の動画をmp4ファイルとして保存します。このやり方の説明は省きます。「ニコニコ動画 保存」などでググレばわかると思います。

動画から静止画の切り出し

それでは、動画データを作成する手順を順を追って説明したいと思います。サンプル動画のデータを3dtest.mp4として取得しているとします。ここからffmpegを用いて、BMP静止画を切り出します。3dtest.mp4のあるフォルダ下に、test30fpsというフォルダを生成し、下記のコマンドをコマンドプロンプトから実行することにより、3dtestxxxx.bmpを生成します。%04dと書いているのは、0詰め4桁通し番号を打つという意味です。

ffmpeg -i "3dtest.mp4" -f image2 -vcodec bmp "test30fps/3dtest%04d.bmp"

3dtest.mp4は30fpsの動画なので、何も指定しないと、秒30コマ分の静止画が切り出されます。何fpsかが知りたい場合は、一度、ffmpegで動画を開いてみると画面に表示されるのでわかると思います。下記はffmpegで静止画を切り出したときの画面の一部です。

メタデータを見てみると、動画サイズ512×288、動画時間は2分7.96秒、フレームレートは30fpsということがわかると思います。よって、test30fpsフォルダに、512×288サイズのBMPファイルが約3838枚(127.96×30)生成されていると思います。

動画から静止画の切り出し(その2)

上の方法でいいのですが、実は3DViewerDSの動画データは10fps固定で作っています。動画再生プログラムを処理落ちを考慮して作っていないので、遅めのフレームレート固定にして作成しました。よって、ffmpegで静止画を切り出すときに、10fpsになるように切り出してもいいです。実際にはやったことが無かったのですが、試してみたいと思います。test10fpsというフォルダを作って下記のコマンドを実行してみました。

ffmpeg -i "3dtest.mp4" -r 10 -f image2 -vcodec bmp "test10fps/3dtest%04d.bmp"

誤差が出たようですが1281枚のBMP画像が生成されました。実際には127.96*10=1279枚かな?

左右画像の切り出し

次に、IrfanView32を用いて右目と左目用の画像を切り出したいと思います。切り出された画像は、512×288サイズで下記のようになっていると思います。

よく見ると、動画データは288の高さになっていますが、有効高さは256のようです。すなわち、一画面のサイズは512×256となっているようでした。
NDSの一画面の画像サイズは256×192です。そこで、この画像から左右二枚の256×192画像を生成します。512×256を単純に二分割すると256×256ですが、画像全体を使いたいので、画像を75%縮小して192×192サイズにしたいと思います。そして、横の左右に黒ぶち部分を32ドット追加して、256×192画像を作りたいと思います。

IrfanView32の設定

IrfanView32にはフォルダに保存している画像ファイルを一気に全て加工する機能があります。これを使って全BMPファイルを一気に切り出したいと思います。先ず、IrfanView32を起動し「一括変換 形式/名前」を選びます。

そうすると、下記のような画面になります。ここで、「ファイルの場所」をffmpegで切り出したtest30fpsに選びます。そして「全て追加」を選ぶと全てのBMP画像が選択されます。
次に、機能を選択します。「ファイル形式の一括変換後にファイル名の一括変換を行う」を選びます。そして、変換後の形式を「BMP」に設定し、「詳細設定を使用」にチェックを入れます。さらに、名前の形式を「image####」とします。これは画像ファイルが4桁あるからです。そして、保存フォルダをしていします。

また、処理が遅くなるので「プレビューを表示」のチェックは外します。
次に、「ファイル形式の一括変換設定」の「詳細設定」をクリックします。

画像のトリミング設定(左の画像)

「切り抜き」にチェックをし、切り抜く画像を指定します。ここでは切り抜き開始位置とサイズを指定します。左の画像は座標(0,16)から書かれています。そして、サイズは前記したように256×256です。
「リサイズ」にチェックをし、変更サイズを設定します。先ず高さを192にするため、256×256を192×192にリサイズします。
そして、「アスペクト比を保存」と「リサンプル処理を行う」にチェックを入れます。

さらに、横幅を256ピクセルにする必要があるので、「画像サイズ」にチェックを入れて「設定」を押します。
横幅を256にする必要があるので、Left sideとRight sideに32ピクセルずつを追加する設定をします。

「OK」「OK」を押して設定を終了します。そして、実行を押します。そうすると、画像変換処理が走ります。一気に画像の切り出し変換が掛かるので終了するまでしばらく待ちます。終了すると3838枚の256×192サイズのBMP画像(image0001.bmp〜image3838.bmp)が生成されているはずです。

画像のトリミング設定(右の画像)

次に、右画像の設定を行います。「ファイル形式の一括変換設定」の「詳細設定」をクリックするところまでは同じです。右の画像は座標(256,16)から書かれています。そして、サイズは同様に256×256です。座標指定以外は全く同じで、「OK」「OK」を押して設定を終了します。そして、実行を押します。以上で右画像ファイル群が生成されます。

動画データファイルの生成

最後に、自作のNDS GazouConvを用いて動画ファイルを生成します。ndsGazouConvを起動します。そして、先ほどのimage0001.bmp〜image3838.bmpの画像ファイルが入ったフォルダをndsGazouConvにドラッグ&ドロップします。このフォルダには必要な画像データ以外のファイルが入っていないようにしてください。ndsGazouConvは、ドラッグされたフォルダ内にある画像データを全ての画像ファイルを、NDS用画像データに変換して結合します。フォルダをドラック&ドロップすると「mode5画像データを出力」ボタンが水色にかわります。この状態で「結合する」にチェックします。このチェックを忘れると1枚1枚のファイルが生成されます。

ステップの設定

最後に、ステップ値を設定します。このステップ値は結合する画像のサンプリング間隔を示す数値です。1にすると全ての画像データを結合します。3DViewerDSは秒10コマの画像を表示します。ffmpegで生成した画像は30fpsなので、秒30枚分の画像が生成されています。そこで、ステップ数=3として結合すると、10コマ/秒の画像結合データが出来上がります。
ステップ値を3と設定した後、「mode5画像データを出力」をクリックすると動画ファイルの生成が開始されます。ファイル名は「フォルダ名.bin」という名前で、画像ファイルのあるフォルダ内に生成されます。

以下が、生成中の様子です。非常に遅いので、生成が終わるまで放置しておいてください。画面に「RGB(31,31,31)データ出力処理は終了しました。」と出ればデータ生成終了です。

10fpsのデータからも生成してみる

IrfanView32を使って、10fps画像からも動画データを作ってみたいと思います。まずは左右画像の切り出しを行います。やり方は全く同じです。枚数が少ないので処理は早く終わるはずです。
次に、ndsGazouConvを用いて画像ファイルを結合します。10fpsの場合はすでに10fpsになっているので、ステップ数を1にして「mode5画像データを出力」を行います。

最後に

以上で、3DViewerDS用の動画データ(binファイル)ができました。30fpsから作ったbinファイルは125829120バイトでした。DSの1画面のデータサイズは98304バイトなので、割り打算すると125829120/98304=1280枚のコマがあることがわかります。1280/10=128秒の動画データですね。元動画が127.96秒なのでうまく生成していると思います。10fpsデータの方は画像データが1281枚なので、1コマ多くなっています。誤差でしょうかね。

3DViewerDSのINIファイル設定

左右のLEFT.binとRIGHT.binファイルをマイクロSDメモリにコピーして3DViewerDSのINIファイルに登録したいと思います。動画ファイルが1つしかないときには、kosuu = 1となります。left.binとright.binファイルは、/3dviewer/test/フォルダ下にコピーしました。動画のコマは全部で1280コマなので、komaCnt = 1280となります。また、repeatCnt = 1とすると1回のみの再生です。この数は再生回数です。設定した回数まで再生を続けます。
音楽は、otoname = noneとしているので音は鳴りません。音データの生成方法は、次の機会に説明したいと思います。

[Read File Suu]
 kosuu = 1
[Read File Data1]
 leftFilename = FAT:/3dViewer/test/left.bin
 rightFilename = FAT:/3dViewer/test/right.bin
 title   = Do-Dai
 otoname = none
 komaCnt = 1280
 sHz = 20000
 repeatCnt = 1

以上が3DViewerDSの動画データの生成方法です。