不思議動画を手軽に撮影2015/07/13

カメラの入力映像にいろいろなエフェクトをかけて楽しむアプリ
に、動画の保存機能を追加しました。

これで今までは一期一会だった面白映像が、いつでも見返すことができるようになりました。



レインボーお猿:エフェクト「レインボー」
動いているものに、カラフルなブラーが付きます。
昔のテレビで電波状況が悪いと、こんな感じになっていたような…



迫力ある安全運転:エフェクト「放射状」
拡大するブラーがついて、放射状の動きになります。
通常のブラーよりも迫力が出ますが、画面全体にエフェクトがかかるので見にくくはなってしまいます。



ミニチュアのような風景:エフェクト「ミニチュア風」
いわゆる"チルトシフト"っぽい加工で、風景をミニチュアのように見せます。
エフェクトの位置などが固定なので、撮り方にコツが要るのが難点です。


こんな動画が、手軽に撮れてしまう Androidアプリ「おかしなカメラ」。
各種エフェクトありますが、どれも使いようなので、ぜひいろいろ試してみてください。

Androidアプリ「おかしなカメラ」

プログラムで動画作成:Android SDK2015/07/15

前回の記事の通り、アプリ「おかしなカメラ」に、動画を保存する機能を追加しました。

Androidで動画を作成する方法はネットで調べればわかりますが、実際にアプリで機能させるにはそれ以外にも作らなければいけない所があります。
もちろんそれらも調べることはできるのですが、常套手段やどんな手法があるかもわからないと検索するのもままなりません。

そこで今回は検索用のキーワードを挙げる意味でも、簡単に動画作成の流れを追ってみます。


データをエンコードして動画に
動画ファイルの作成には、MediaCodecと MediaMuxerというクラスを使用します。
MediaCodecでデータをエンコード、MediaMuxerでファイルにまとめます。
画像と音声は別データなので、それぞれ MediaCodecが必要です。

MediaCodecは getInputBuffers()で入力用のバッファを取得して、エンコードのためのバイナリデータを送ることができるので、音声の方は AudioRecordで取得したデータを送っています。

ただし、画像の方はこの方法は使いません。
バイナリでやり取りしたのでは重いし、そもそも機種毎に対応している画像フォーマットが違うらしいです。

画像データを送るには、Surfaceを使用する方法が用意されています。
MediaCodecの createInputSurfaceで Surfaceを取得、そこへエンコードする画像を描画します。

Surfaceへの描画というと lockCanvasで Canvasを取得して…という方法がありますが、MediaCodec.javaの createInputSurfaceの所には lockCanvasは使うな、OpenGL ES(の類)を使え、とあります。実際、動画の作成を行うようなアプリが描画に Canvasを使用しているとは思えませんが…。


◇OpenGLによる Surfaceへの描画
こんなことは Androidで OpenGLを使うための基本的な話なんでしょうが、最初から GLSurfaceViewなんて物を使っていると案外知らなかったりします。

それぞれのクラスがどんな役割を持っているか、正確にはわかっていないのですが必要な処理を並べてみます。

・EGL10を取得
・EGLDisplayを取得
・EGLConfigを取得
・EGLContextを作成
・EGLSurfaceを作成
 このとき eglCreateWindowSurfaceの第3引数に、createInputSurfaceで取得した Surfaceを指定します。

後は毎フレーム glMakeCurrentから描画、eglSwapBuffers…とかあるんですが、このあたりはサンプルも含めてちゃんと解説している所を探した方が良いでしょう。

これで OpenGLを使った描画で動画を作成できるようになりました。しかし、まだ問題があります。


◇異なる EGLContext間の描画
実際のアプリでは画面キャプチャ等、画面に表示するテクスチャやフレームバッファで動画を作成する必要が多いのではないかと思います。
ところが、画面描画用の Surface(GLSurfaceView)とエンコード用の Surfaceでは EGLContextが異なっているので、このままではテクスチャを共用できません(テクスチャ等は EGLContextごとに管理されるため)。

一旦テクスチャデータをメモリに落として、エンコード用の Surfaceに切り替えたときにテクスチャを生成すれば描画できなくもありませんが、毎フレームそんな重い処理をするのは避けたいところです。

そこで、shared_contextという手法(実は手法の名前なのか、よくわかっていません)を使って、テクスチャ等を共有します。
具体的には、エンコード用の EGLContextを作成するときの eglCreateContextで、第3引数に画面描画に使用している EGLContextを指定します。
これで、画面に表示するテクスチャやフレームバッファを動画にすることができます。

ちなみに、GLSurfaceViewで使用している EGLContextを取得するには setEGLContextFactoryを使用します。
EGLContextを作成するクラスを作って、createContextの戻り値が必要とする EGLContextとなります。


以上、動画作成部分を実装するまでに調べた所や、つまづいた所を簡単に挙げてみました。
詳しい解説やサンプル等は、それぞれの処理で調べてみてください。

なお、上に挙げた方法がベストとは限りません。また、大体のニュアンスで書いていて細かい所で間違っている表現もあるかもしれないので気を付けてください。

まんがタイムファミリー 9月号2015/07/20

ひかり!出発進行
SLの話はパズルのようだ。
というか、パズルの本にはこの手の動力車と客車のパズルがあったよな。
ちょっとだけよを思い浮かべるのは、どうかと思うが。

寺島さんは悟っている
玄田さんのカツラは、周りにはばれているんじゃなかろうか?
むしろ僧侶もやっていることを出した方が良いのでは…

軍神ちゃんとよばないで
変に史実を混ぜてくると、どこまでが冗談なのかわからなくなってくる。
「兜が必要なくらい敵に迫られた時点で、もう手遅れ」というのは、川中島の前フリなんだろうか?

パパとあそぼう!
いつもながらのことだけど、親父さんオロオロし過ぎだ。
「かしこみかしこみ」の奏衣様のように、落ち着いて見守ってほしいものだ。

不思議な世界の 車窓から2015/07/21

電車に乗る機会があったので、車窓からの風景を「おかしなカメラ」で撮ってみました。



砂の世界:エフェクト「砂状」
歩いている人が、まるで砂のようです。
電車が動き出すと、風景自体が砂状化します。



線の世界:エフェクト「ライン状」
動いている電車から撮ったので、風景すべてが線状になっています。
走り出すところから撮ればよかった…



こんな不思議な動画が、簡単に撮れる Androidアプリ「おかしなカメラ」は、こちらから

おかしなカメラ

まんがタイムスペシャル 9月号2015/07/26

ローカル女子の遠吠え
「夏のカラーページは水着回」というマジメな漫画。
雲春君は桐嶋さんの言ったことに対する感想は心に留めておくだけだが、りん子さんに対してははっきりと意見を言うんだな。

だけど温田さんはひとりでデキない
父親もこの調子では、「ひとりでデキない」のも仕方ない。
でも子供には慕われる…危なっかしいけど。

同姓同盟
日ハムの「田中幸雄」を思い出す。

メェ~探偵フワロ
フワロさんの決死の策により、アーサーとミスレモンの仲は進展するのか?
村中が盛り上がって、ヴィヴィアン孫は「玉の輿」と面白がっている場合じゃなくなってしまったような。