【问题标题】:screenshot android presentation display/surface屏幕截图 android 演示文稿显示/表面
【发布时间】:2015-08-23 06:16:01
【问题描述】:

我想在 Android 中制作 Presentation 对象的“即时”屏幕截图。我的演示文稿通常呈现到虚拟显示器 (PRIVATE),该虚拟显示器由设置为录制视频的 MediaRecorder 的表面支持。将演示文稿录制为视频效果很好。

mMediaRecorder = new MediaRecorder();
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(getScratchFile().getAbsolutePath());
mMediaRecorder.setVideoEncodingBitRate(bitrateInBitsPerSecond);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

mVirtualDisplay = mDisplayManager.createVirtualDisplay(
        DISPLAY_NAME, // string name required
        mVideoSize.getWidth(),
        mVideoSize.getHeight(),
        160, // screen densityDpi, not sure what it means in this context
        mMediaRecorder.getSurface(), // the media recorder must already be {@code prepare()}'d
        DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY); // only we can use it

mPresentation = new MyPresentation(getActivity(), mVirtualDisplay().getDisplay());

如何随时获取 mMediaRecorder.getSurface() 的屏幕截图,包括 mMediaRecorder 已设置但未录制时?

我已经尝试了许多与 Presentation 根视图对象上的 view.getDrawingCache() 相关的方法,但我只能得到清晰/黑色的输出。演示文稿本身包含 TextureView 对象,我猜这是搞砸了这个策略。 我还尝试将 ImageReader 与 mMediaRecorder 的 DisplayPreview 一起使用,但它在回调中没有收到任何图像——永远

mMediaRecorder.setDisplayPreview(mImageReader.getSurface());

我真的很想用某种方法将支持演示文稿的 Surface 镜像到 ImageReader 并将其用作消费者,我只是看不出如何将一个表面作为生产者“镜像”到另一个“消费者”类.看来 SurfaceFlinger 应该有一个简单的方法。

【问题讨论】:

    标签: android surfaceview android-mediarecorder


    【解决方案1】:

    表面是生产者-消费者数据结构的生产者端。生产者无法从管道中拉回数据,因此无法尝试从 Surface 读取帧。

    当提供 MediaCodec 或 MediaRecorder 时,消费者端处于管理媒体硬件的不同进程 (mediaserver) 中。对于 SurfaceView,消费者位于 SurfaceFlinger 中。对于 TextureView,两端都在您的应用程序中,这就是为什么您可以轻松地从 TextureView 获取帧(调用 getBitmap())。

    要拦截传入的数据,您需要在同一进程中同时拥有生产者和消费者。 SurfaceTexture 类(也称为“GLConsumer”)提供了这一点——它是将接收到的帧转换为 GLES 纹理的消费者。

    所以想法是创建一个 SurfaceTexture,从中创建一个新的 Surface(您会注意到 Surface 的 only public constructor 采用 SurfaceTexture),然后将该 Surface 作为虚拟显示输出 Surface 传递。然后当帧进入时,您通过使用 OpenGL ES 渲染纹理将它们“转发”到 MediaRecorder。

    这并不完全简单,尤其是如果您以前没有使用过 OpenGL ES。在Grafika 中可以找到各种示例(例如“来自相机的纹理”和“记录 GL 应用程序”)。

    我不知道 setDisplayPreview() 是否适用于相机以外的任何东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-21
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多