我使用 MediaProjection api 以及 VirtualDisplay 和 ImageReader 来共享屏幕。下面是创建 VirtualDisplay 和 ImageReader 的方法:
private void createVirtualDisplay(Activity mContext) {
final DisplayMetrics metrics = new DisplayMetrics();
mContext.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
final int width = metrics.widthPixels;
final int height = metrics.heightPixels;
final int densityDpi = metrics.densityDpi;
final int MAX_IMAGES = 2;
mWidth = width; // 1080
mHeight = height; // 2400
mDensity = densityDpi;
Log.d(TAG," >>> Creating display metric w: " + mWidth + " h: " + mHeight + " dens: " + mDensity);
mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, MAX_IMAGES);
mVirtualDisplay = mMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight,
mDensity, getVirtualDisplayFlags(), mImageReader.getSurface(), null, mHandler);
mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);
mCallback.onReceivedDisplayInfo(mWidth, mHeight);
}
并且在 OnimageAvailable 上接收到 rgba 原始字节:
private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
@Override
public void onImageAvailable(ImageReader reader) {
try (Image image = mImageReader.acquireLatestImage()) {
if (image != null) {
publishFrame(image);
}
} catch (Exception e) {
e.printStackTrace();
mCallback.onError(e.getMessage());
}
}
}
private void publishFrame(Image image) {
int mWidth = image.getWidth();
int mHeight = image.getHeight();
// Four bytes per pixel: width * height * 4.
byte[] rgbaBytes = new byte[mWidth * mHeight * 4];
// put the data into the rgbaBytes array.
image.getPlanes()[0].getBuffer().get(rgbaBytes);
image.close();
if (mCallback != null) {
mCallback.onScreenFrameCaptured(rgbaBytes);
}
}
到目前为止,一切都很好,并且框架可以毫无问题地渲染到表面视图上。但事情在这一点上变得有趣:
将宽高改为640 x 480后,效果好一点:
但如您所见,共享屏幕的纵横比有问题。最后,当我将宽度和高度更改为 768 * 1366 时,结果在某种程度上可以接受但
为什么当我为 Imageريالeader 和 VirtualDisplay 设置设备屏幕的宽度和高度时,共享屏幕损坏了?(对于这个设备:宽度=1080 高度=2400)
为什么当我设置高度大于宽度时,共享屏幕是好的?
在上一张图中,共享屏幕并没有覆盖整个目标 SurfaceView。如何为 VirtualDisplay 和 ImageReader 设置覆盖整个 SurfaceView 的分辨率?