Android5.xでMediaProjection/VirtualDisplayを使って端末の画面を.mp4ファイルとして録画するサンプルプロジェクトをGitHubに公開したよ。ルート化不要だよ。
リンクはこちらScreenRecordingSample
中身は取り立てて説明するようなもんじゃないんだけど特徴としては、
- サービスを使ってバックグラウンドで録画を継続
サンプルアプリのアクティビティを終了させただけでは録画終了しません。明示的に録画を終了させない限り永遠と録画します。エラーチェックはしてないから空き容量が無くなった時にどうなるかは知りません^^;
あと、タスクキラーとかでサービスを落とされちゃうとたぶん再生できないファイルが出来上がります。 - 音声付きで録画
コードを1箇所いじれば音声なしも可 - MediaCodec/MediaMuxerを使って録画
まぁ大体は以前から公開しているAudioVideoRecordingSampleってのと一緒で、カメラからの映像の代わりに端末の画面に表示されている内容ををVirtualDisplayでかっぱらって録画します
メッセージと録画開始/終了するためのボタン1個あるだけの手抜きUIだけど、Android端末の操作説明用の動画を実際に操作しながら説明しながら作ったりするのにも使えるかも。
USTREAMで再生している動画とかも録画出来ちゃったりして(*_*)。でも悪いことに使っちゃダメだからね^^;
Android5.x限定だけど、2時間ほどで簡単に実装できちゃった。エンコーダー周りは大部分流用しているからってのもあるけどね。ウイジェットにしてもいいかなぁ^^
プログラムの説明が欲しいなぁって人はコメントに書いてね。
2015/06/07追記:
ふと思いついてもう2時間程かけてウイジェットから起動・停止出来るようにしてみた。おぉ〜これは便利っちゃ。
で2つほど問題を発見^^;
- MediaProjectionManagerでスクリーンキャプチャのパーミッションを要求した時に表示されるダイアログで「次回から表示しない」にチェックを入れちゃうとアプリを削除するまで解除するすべがない ガ━━(;゚Д゚)━━ン!!
USBとかのパーミッションの場合には、設定のアプリマネージャーで「デフォルトでの起動」をクリアしたりアプリのデータを消去したら再度ダイアログが表示されるようになるんだけど、そんなの関係ねぇ〜 - 端末の画面を電源ボタンで切っても録画は継続できます。で問題は次起動した時。パスワードとかパターン認証の画面も全部録画できちゃう。 えぇ〜!?まぁビデオ取説作るなら何でもかんでも取れた方が便利なんだけど、セキュリティ的にはクリティカルな気が…
通知領域見ればスクリーンキャプチャ・・・というかMediaProjection/VirtualDisplayが動いているのがわかるんだけど、リテラシーやセキュリティ意識低い人の端末に入れちゃえばメールでもブラウザでもUSTREAMでも何でも録画し放題になってしまう(゜レ゜) 端末の起動時に自動で録画開始なんてことも技術的には簡単だし。
う〜ん、正しく使えば便利なんだけどなぁ。まぁAndroid4.4以上だとコマンドラインで実行するscreenrecordってのもあるし、Google Playにはスクリーンキャプチャのアプリもそれなりにあるし、ええんかな?
2015/06/11追記:
バックグラウンド録画中に画面を回転させると録画が中断しちゃいます。端末の設定を変更できるようにパーミッション取って録画中は回転しないように設定変更するってのが一番なんかな?でも無理やり回しちゃうアプリもあるしなぁ(゜レ゜)
コメント
非常に参考になる内容、ありがとうございます。
以下2点ご教示いただけると助かります。
1.Nexus7(2013)で動作させると、以下のようにエラーが発生します。色々と試したのですが治らず、修正方法をご存じでしたらご教示いただければと思います。(HWの制約が関係している気がしています)
FATAL EXCEPTION: IntentService[ScreenRecorderService]
Process: test.alphere.com.screencapturesampletest4, PID: 12759
android.media.MediaCodec$CodecException: Error 0xfffffc0e
at android.media.MediaCodec.native_configure(Native Method)
at android.media.MediaCodec.configure(MediaCodec.java:577)
at com.serenegiant.media.MediaVideoEncoderBase.prepare_surface_encoder(MediaVideoEncoderBase.java:71)
at com.serenegiant.media.MediaScreenEncoder.prepare(MediaScreenEncoder.java:77)
at com.serenegiant.media.MediaMuxerWrapper.prepare(MediaMuxerWrapper.java:76)
at com.serenegiant.service.ScreenRecorderService.startScreenRecord(ScreenRecorderService.java:131)
at com.serenegiant.service.ScreenRecorderService.onHandleIntent(ScreenRecorderService.java:76)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
2.個別にお仕事として(有償で)、お願い事をさせていただくことは可能でしょうか。可能なら、メールアドレスの連絡先までご連絡いただければと思います。
よろしくお願い致します。
こんばんは。
あぁ〜これは普通は悩んでもわからないはずです。
Nexus7(2013)ではMediaCodecでのハードウエアエンコーダーのサイズ制限が縦1080ピクセルまでだったと思います。ですが画面の解像度は1920×1200…そのまま録画しようとすると修復不可能な例外でクラッシュします。まぁ古いから仕方ないっちゃ仕方ないのですが、この頃…というより2014年頃までの端末には結構こういうたぐいの制限がある機種が多いです。
今時720p以下しか対応していない機種なんてのは無視することにして、縦が必ず1080以下になるように修正して、ついでにAndroidStudioのプロジェクトに換えてGitHubのリポジトリを更新しておきました。
saki
ありがとうございます。そういうことですね。
無事動きました。
いつも有益な情報、ありがとうございます。
今後ともよろしくお願い致します。