Android 屏幕共享 - 表面参数

Android Screen Share - surface parameter

我正在尝试使用 Agora.io 在 Android 上实现屏幕共享。他们的样本很清楚:

MediaProjectionManager projectManager = (MediaProjectionManager) mContext.getSystemService(
Context.MEDIA_PROJECTION_SERVICE);

// Create the intent for screen capture. Call the startActivityForResult method to use the sharing function.
Intent intent = projectManager.createScreenCaptureIntent();
startActivityForResult(intent);

MediaProjection projection;
VirtualDisplay display;

// Override and implement the onActivityResult method of the Activity where you just called startActivityForResult.
@Override
onActivityResult(int requestCode, int resultCode, Intent resuleData) {
    projection = projectManager.getMediaProjection(resultCode, resultData);
    display = projection.createVirtualDisplay(name, width, height, dpi, flags, surface, callback, handler);
}

// The texture retrieved from the Surface will be sent by the SDK.
rtcEngine.pushExternalVideoFrame(new AgoraVideoFrame(...));

// Stop screen sharing.
projection.stop();

但是在 createVirtualDisplay 中它们是表面参数。我不确定那是从哪里来的——或者我如何获得屏幕的 Surface?还是实例化一个新的 Surface 实例?使用接受 SurfaceTexture 作为参数的构造函数。或者可能实施 SurfaceTexture.OnFrameAvailableListener / OnImageAvailableListener(不确定)。

表面文档:

https://developer.android.com/reference/android/view/Surface

createVirtualDisplay 文档:

https://developer.android.com/reference/android/media/projection/MediaProjection#createVirtualDisplay(java.lang.String,%20int,%20int,%20int,%20int,%20android.view.Surface,%20android.hardware.display.VirtualDisplay.Callback,%20android.os.Handler)

您可以通过多种方式获得 Surface:

  1. 如果你正在做一些视频编码,使用MediaCodec.createInputSurface()作为编码模块的输入;
  2. 如果要接收 YUV 帧,请使用 ImageReader.getSurface() 创建 Surface;
  3. 而如果你想自己做OpenGL渲染,你可以在OpenGL上下文中创建一个纹理,并使用该纹理创建一个SurfaceTexture,从而创建你自己的Surface。

但是请注意,不要使用已经附加到视图层次结构的 Surface。