web-dev-qa-db-ja.com

Android Screen Recording-どのようにして各フレームを取得できますか?

Androidアプリで画面を記録するためにMediaRecorderとMediaProjection Apiを使用しています。rtmpストリームで送信できる各フレームを取得できません。RTMPストリームで公開するには、 JAVACV Androidライブラリを使用しています。

たとえば、カメラを介したライブストリーミングの場合、onPreviewFrame()コールバックで各フレームを取得できます。各フレームを取得した後、私は単純にJAVACVライブラリのFFmpegFrameRecorderを使用して、各フレームをrtmp urlにストリーミングします。

画面記録でどうすれば同じことができますか?

ここでどんな助けもいただければ幸いです。前もって感謝します!

7
umesh lohani

最初に、画面キャプチャされたフレームのバッファを提供できるMediaProjectionのコールバックインターフェイスはありませんが、 SurfaceTexture を使用すると、可能です。以下は、SurfaceTextureを使用した画面キャプチャの1つの実装 ScreenCapturerAndroid です。

画面コンテンツをビデオストリームとしてキャプチャするVideoCapturerの実装。キャプチャは、SurfaceTextureのMediaProjectionによって行われます。 SurfaceTextureHelperを使用して、このSurfaceTextureを操作します。 SurfaceTextureHelperはネイティブコードによって作成され、VideoCapturer.initialize()でこのキャプチャーに渡されます。このキャプチャーは、新しいフレームを受信すると、それをテクスチャーとしてCapturerObserver.onFrameCaptured()を介してネイティブコードに渡します。これは、指定されたSurfaceTextureHelperのHandlerThreadで行われます。各フレームで完了すると、ネイティブコードはバッファをSurfaceTextureHelperに返します。

ただし、アプリビューのストリームを送信する場合は、次のスクリーンキャプチャを使用すると役立ちます。

public class ScreenCapturer {
    private boolean capturing = false;
    private int fps=15;
    private int width,height;
    private Context context;
    private int[] frame;
    private Bitmap bmp;
    private Canvas canvas;
    private View contentView;
    private Handler mHandler = new Handler();
    public ScreenCapturer(Context context, View view) {
        this.context = context;
        this.contentView = view;
    }

    public void startCapturing(){
        capturing = true;

        mHandler.postDelayed(newFrame, 1000 / fps);
    }
    public void stopCapturing(){
        capturing = false;
        mHandler.removeCallbacks(newFrame);
    }
    private Runnable newFrame = new Runnable() {
        @Override
        public void run() {
            if (capturing) {
                int width = contentView.getWidth();
                int height = contentView.getHeight();
                if (frame == null ||
                        ScreenCapturer. this.width != width ||
                        ScreenCapturer.this.height != height) {

                    ScreenCapturer.this.width = width;
                    ScreenCapturer.this.height = height;

                    if (bmp != null) {
                        bmp.recycle();
                        bmp = null;
                    }
                    bmp = Bitmap.createBitmap(width,
                            height, Bitmap.Config.ARGB_8888);

                    canvas = new Canvas(bmp);
                    frame = new int[width * height];
                }
                canvas.saveLayer(0, 0, width, height, null);
                canvas.translate(-contentView.getScrollX(), - contentView.getScrollY());
                contentView.draw(canvas);

                bmp.getPixels(frame, 0, width, 0, 0, width, height);


               //frame[] is a rgb pixel array compress it to YUV if want and send over RTMP

                canvas.restore();
                mHandler.postDelayed(newFrame, 1000 / fps);

            }
        }
    };


}


用途

...
//Use this in your activity 

private View parentView;

parentView = findViewById(R.id.parentView);
capturer = new ScreenCapturer(this,parentView);

//To start capturing
 capturer.startCapturing();


//To Stop capturer
capturer.stopCapturing();

これを使用して、ビューコンテンツをRTMPストリームに送信できます。アクティビティの親ビューを使用して、アクティビティのすべてのコンテンツをキャプチャできます。

3
Afsar edrisy