Android作業ログ
=動画キャプチャ=
Androidで作ったゲームはインストールの手間があるため、事前に動画でゲーム内容を伝えたい。そのためにゲームの動画をキャプチャしたい。
普通にやる場合はSepteni Engineer's Blogなどを参考にandroidscreencastを使ってキャプチャすれば良いと思う。しかし、自分の場合はPCが貧弱なのでキャプチャがガタガタになってしまう。また、静止画のキャプチャにもズレが生じる。そこで、今回は自前で毎フレームキャプチャして連番画像として保存し、それをつなげることで動画を作ってみる。音が記録できないけど、このレベルなら後付けでなんとかできるはず。
=静止画キャプチャ=
まず、OpenGLで描画したもののキャプチャはAndroidのOpenGL ESで地球をこの手に - Schlechte WeltのglReadPixelsあたりや、http://www.saturn.dti.ne.jp/npaka/android/SnapShotEx/index.htmlの保存まわりを参考にしつつ独自に書いた。
//Member public byte[] m_CaptureBytes; public Bitmap m_CaptureBitmap; public ByteBuffer m_CaptureBuffer; public int m_CaptureCount; //onSurfaceChanged内 m_CaptureBytes = new byte[4 * width * height]; m_CaptureBuffer = ByteBuffer.wrap(m_CaptureBytes); m_CaptureBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); m_CaptureCount = 0; //drawの最後 if(m_CaptureBuffer != null){ //結果をBufferにコピー gl.glReadPixels(0, 0, surfaceWidth, surfaceHeight, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, m_CaptureBuffer); //バッファをBitmap化 m_CaptureBitmap.copyPixelsFromBuffer(m_CaptureBuffer); //BitmapをJpeg化 ByteArrayOutputStream os = new ByteArrayOutputStream(); m_CaptureBitmap.compress(Bitmap.CompressFormat.JPEG, 80, os); byte[] w = os.toByteArray(); //保存 if(m_CaptureCount < 100) { String file_name = Integer.toString(m_CaptureCount++) + ".jpg"; OutputStream out=null; try { out=openFileOutput(file_name, Context.MODE_WORLD_READABLE); out.write(w,0,w.length); out.close(); } catch (Exception e) { try { if (out!=null) out.close(); } catch (Exception e2) { } } } }
ただし、このコードだと上下反転した画像が保存されるっぽい。コード側での対応は面倒そうだったので、動画化してから上下反転することにした。
=保存した画像の抜き出し=
Android内だけで動画まで作れれば良いのだけど、そういう仕組みはなさそう。(MediaRecorderでできれば良かったんだけど)
というわけで、上で作った連番画像をPCにコピーする。
上の処理では/data/data/(パッケージ名)/files/0.jpg〜99.jpgに最初の100フレーム分の画像が保存される。
ローカルファイルの保存先について | mucchinのAndroid戦記を元に、adbのpullを使ってPCに持ってくる。
自分はパスを通してないので「"C:\Program Files\Android\android-sdk\platform-tools\adb.exe" pull 〜」と直にadbのパスを指定している。
また、どうもローカルファイルはディレクトリまるごとコピーができないようなので、仕方なく以下のようなバッチを作って1つずつコピーするようにした。(バッチについては炎のコマンドプロンプト入門/バッチファイル/繰り返し処理を参考にした)
for /l %%B in (0,1,99) do "C:\Program Files\Android\android-sdk\platform-tools\adb.exe" pull /data/data/showohealer.game.monochroll/files/%%B.jpg D:\screenshot
ちなみに30FPS&30秒分の録画でも900枚になるので、場合によっては容量的にきついかも。
=連番画像の動画化=
あとは抜き出した連番画像を動画に変換すれば良い。できればタイトル(一枚絵)を入れたいし、フェードイン・フェードアウトなども設定できればなお良い。
というあたりで良さそうなツールを探してみたところ、TMPGEncと他の動画編集ソフトを組み合わせれば良さそうだった。(「テキスト動画」だと1つだけでいけそうだったんだけど、画像の一部しか表示されなかったので断念)
連番画像から動画に変換するのはTMPGEncを使い、連番画像ファイルを動画に変換する方法(TMPG Encを使う) - Poser覚書を参考にして簡単にできた。
あとはそれをタイトルとかとつなげたりすればOK。Windowsだと「Windowsムービーメーカー」なるものがあるので、これで良いかもしれない。ここから先はもう少し色々と試す予定。