首先,MediaProjection没有回调接口可以给你屏幕捕获帧的缓冲区,但使用
SurfaceTexture则非常可能实现。这里有一个名为
ScreenCapturerAndroid的实现,可通过SurfaceTexture进行屏幕捕获。
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, 0, width, height, null);
canvas.translate(-contentView.getScrollX(), - contentView.getScrollY());
contentView.draw(canvas);
bmp.getPixels(frame, 0, width, 0, 0, width, height);
canvas.restore();
mHandler.postDelayed(newFrame, 1000 / fps);
}
}
};
}
使用方法
...
private View parentView;
parentView = findViewById(R.id.parentView);
capturer = new ScreenCapturer(this,parentView);
capturer.startCapturing();
capturer.stopCapturing();
使用此功能,您可以将视图内容发送到RTMP流中,您可以使用您活动的父视图来捕获活动的所有内容。
muxer.writeSampleData(trackIndex, encodedData, info)
获取关键帧缓冲区吗?假设你正在进行类似于 https://github.com/google/grafika/blob/master/app/src/main/java/com/android/grafika/ScreenRecordActivity.java 的操作(假设帧足够频繁,但对于你的目的可能不是这样)。 - Morrison Chang