MAME から無劣化動画を作る (かなり面倒くさい)

MAME の AVI 作成機能ではなくて MNG 作成機能から lossless の動画を作りました. 10年前に試したところ AVI 作成機能は圧縮一切なしの超巨大ファイルを作るし、 MNG は対応しているソフトが当時も今も皆無です.

MAME で入力を記録する

mame [gamename] -record [recordname]

満足のいく内容が取れるまでゲームを遊びます. [] で囲ったところは任意です.

MAME で入力を再現させて、それを MNG file と wav file でだす

mame [gamename] -playback [recordname] -mngwrite [mngfilename] -wavwrite [wavfilename]

mng ファイルは、表示フレームをすべて png 画像として圧縮してそれを順番にいれているものです. 圧縮するので再現中はゲームのスピードがかなり遅くなるので気長に待ちます.

出力された mng と wav のファイルは間違って消さないように readonly 属性を付けておいたほうがいいでしょう. コマンドラインだと履歴巡って再実行でファイル上書きでやりなおしの事故がよくあります.

MNG file を連番の PNG file として大量に出力する

gitlab.com

対応しているソフトがないので分離します. やること自体は単純で IHDR と IEND の間の chunk を切り出して png のヘッダをつけてファイルに出します.

問題は1秒間で60個、1分間で3,600個、10分間で36,000個のファイルになるので2時間も録画したものを分離すると、ディスクの圧迫は当然としてファイルシステムやファイル管理に異常が出るらしくファイルの出力が何故か遅くなります.

この対策として 10,000 個ずつ png ファイルを出して、それを1つの mp4 ファイルに統合を繰り返し、複数の mp4 ファイルを1つに統合する、という流れであればマシになりました.

分離ソフトは自作です.先述のように1時間30分ほどの1つの mng ファイルを一度に分離したらファイル生成が妙に遅くなって出力に4時間かかりました. 10,000単位なら1分程度で終わります. 1分でも遅いのですがボトルネックはファイル出力にあるので、自分の力では改善できそうにありませんでした.

連番の PNG file 群を1つの mp4 ファイルに統合する

rm -f [09999.png]
ffmpeg [options] -r [fps] -i [%06d.png] -c:v libx264 -preset ultrafast -crf 0 -f mp4 [v%04d.mp4]
  • [09999.png] は分割生成で結合前に最終フレームのファイルを1つ消します. かなり重要で、結合の部分で説明します.
  • [options] は -y とか -loglevel とか好きなのを入れます
  • [fps] は MNG file の MHDR chunk 内部の Ticks_per_second から取得します. これは整数なのが気になりますがそれでうまくいきました. http://www.libpng.org/pub/mng/spec/mng-1.0-20010209-pdg.html#mng-MHDR
  • [%06d.png] は入力ファイル, [v%04d.mp4] は出力ファイル

これで 1 frame 欠けてますが、可逆圧縮の H264 でエンコードできます. MAME が出す AVI ファイルに比べるとかなり小さく、MNG ファイルより小さくなりました.
png への分離と H264 へのエンコードを繰り返します.

連番の映像ファイルを1つに統合する

ffmpeg [options] -f concat -safe 0 -i [list] -c copy video.mp4

このコマンドは web 上のffmpeg のマニュアルや野良情報と同じです.

この結合機能は入力ファイルごとになぜか 1 frame ずつ増えてしまい、音ズレの原因となっていました. 16個も分離した場合には後半の音のズレがひどいので使い物にならないので、入力側から 1 frame 削除しておくのが妥協案だと思います. (この原因解明に1日かかりました)

結合前に音をいれておくと音ズレは予防できたのですが、今度は結合フレームで音が切れてしまう問題があり、その点でもこれが一番マシだと思います.

統合した映像ファイルに音声を追加する

野良情報と同じなので省略します.

一連の処理をスクリプトで管理する

mng から png 分離プログラムとスクリプトはまだ未完成なのでできたら公開するつもりです.

かなり変数をとってくる必要があるので bat や bash では無理でした.
あとは中間ファイルの削除もスクリプトにいれる必要があります.

ようやく編集する

この面倒な作業を終えるとようやく編集できますのでアスペクト比とかfpsの変更、ステージごとの分割ということができます.