12

Is it possible to record all actions inside some View in Android as video? Maybe using C/C++ or anything else?

I know that there is way to record using shell, but root is required. It would be better without. Also we would make it from SDK Version 16.

fadden
  • 51,356
  • 5
  • 116
  • 166

3 Answers3

9

You can use the javacv library to combine a set of bitmaps taken from the view; the code will look like this:

FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("/sdcard/test.mp4",256,256);
try {
    recorder.setVideoCodec(avcodec.AV_CODEC_ID_MPEG4);
    recorder.setFormat("mp4");
    recorder.setFrameRate(30);
    recorder.setPixelFormat(avutil.PIX_FMT_YUV420P10);
    recorder.setVideoBitrate(1200);
    recorder.startUnsafe();
    for (int i=0;i< 5;i++)
    {
        view.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
        view.setDrawingCacheEnabled(false);
        recorder.record(bitmap);
    }
    recorder.stop();
}
catch (Exception e){
    e.printStackTrace();
}

And here is a full example on how to record

androidLover
  • 302
  • 1
  • 4
  • Thanks for your answer! I tried to use the library. It seems that it is right for me. But I have a question, is it possible to record 30 bitmaps per second? Otherwise, to call `Bitmap.createBitmap(view.getDrawingCache());` 30 times in one second? How can it affect the performance? –  Apr 17 '16 at 12:45
  • 1
    What is v1? This api doesn't work anymore. recoder.record doesn't take bitmap. – Jeffrey Liu Sep 25 '17 at 21:05
  • @JeffreyLiu `v1` is your View from what you want to take a screen =) –  Oct 30 '17 at 19:19
  • 1
    @JeffreyLiu didi you get any solution? i'm getting same error recorder.record(bitmap); required org.bytedeco.javacv.Frame not Bitmap – PriyankVadariya Jul 19 '18 at 12:26
  • No I have not @Priyank – Jeffrey Liu Jul 19 '18 at 23:38
6

You can get screen shots of your app's Views with a well-known technique. If you capture several consecutive images you can combine them into a video.

If you want to do this live with a higher frame rate, the recommended approach is to use a virtual display through the MediaProjection class, feeding the output into a video encoder. This requires API 21.

Recording the screen on an API 16 device would require native code and the use of non-public interfaces. It's possible but not easy.

Community
  • 1
  • 1
fadden
  • 51,356
  • 5
  • 116
  • 166
  • Thanks for your quick answer! I have considered the options to use this technique (video from images) as you and @androidLover have suggested. But I think that this option would not be best for my problem, because I need to capture with a high frame rate. I suppose encoder will not have time to record at 30 frames per second. Is it so? –  Apr 16 '16 at 18:36
  • The hardware video codec will be able to keep up with 30fps at a reasonable resolution (720p or 1080p) on most devices. The trouble is getting the frames rendered and into the encoder that fast. You really want to keep all of the data in the GPU and video codec. – fadden Apr 17 '16 at 00:35
  • Hi @fadden please elaborate more on the 'MediaProjection' approach. Some sort of code snippet would be very helpful. – abhishek kumar gupta Jun 08 '17 at 13:58
  • 6
    How to record just a view, not the whole screen? – Jeffrey Liu Sep 25 '17 at 21:06
0

You can check this for capturing a view i tried on cardView layout and it worked perfectly fine

For Video Recording

https://github.com/z4hyoung/ViewRecorder

For Image Capturing

fun loadBitmapFromView(v: View): Bitmap? {
        val b: Bitmap = Bitmap.createBitmap(v.width, v.height, Bitmap.Config.ARGB_8888)
        val c = Canvas(b)
        v.draw(c)
        return b
    }

val fos: OutputStream = FileOutputStream(fileDir)

            fos.use {
                // Finally writing the bitmap to the output stream that we opened
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)
            }