在Android屏幕录制中-如何获取每一帧?

我正在使用MediaRecorder和MediaProjection Api在Android应用程序中记录屏幕。我无法获得可以通过rtmp流发送的每个帧。为了通过RTMP流发布,我使用的是JAVACV Android库。

例如-如果通过摄像机进行实时流传输,我们可以在onPreviewFrame()回调中获取每一帧。获得每个帧后,我只需使用JAVACV库的FFmpegFrameRecorder将每个帧流式传输到rtmp url。

如何通过屏幕录制实现相同的目标?

这里将提供任何帮助。预先感谢!

crazyboylp 回答:在Android屏幕录制中-如何获取每一帧?

首先,MediaProjection没有回调接口,可以为您提供屏幕捕获帧的缓冲区,但是使用SurfaceTexture很有可能。这是使用SurfaceTexture进行屏幕捕获的一种实现方式ScreenCapturerAndroid

VideoCapturer的实现,用于将屏幕内容捕获为视频流。 捕获是由MediaProjection在SurfaceTexture上完成的。我们与此互动 使用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,width,null);
                canvas.translate(-contentView.getScrollX(),- contentView.getScrollY());
                contentView.draw(canvas);

                bmp.getPixels(frame,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流。您可以使用活动的父视图来捕获活动的所有内容。

本文链接:https://www.f2er.com/2741346.html

大家都在问