截图android演示文稿显示/表面

时间:2015-08-23 06:16:02

标签: android surfaceview android-mediarecorder

我想在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对象,我猜这些对象正在弄乱这个策略。 我也尝试使用带有mMediaRecorder的DisplayPreview的ImageReader,但它在回调中没有收到图像 - 曾经

mMediaRecorder.setDisplayPreview(mImageReader.getSurface());

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

1 个答案:

答案 0 :(得分:1)

Surfaces是生产者 - 消费者数据结构的生产者端。生产者无法将数据从管道中取出,因此尝试从Surface读取帧是不可能的。

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

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

因此,我们的想法是创建一个SurfaceTexture,从中创建一个新的Surface(您将注意到Surface only public constructor采用SurfaceTexture),并将该Surface作为虚拟显示传递输出表面。然后随着框架进入你的前进"通过使用OpenGL ES渲染纹理,将它们传送到MediaRecorder。

这并非完全直截了当,特别是如果您之前没有使用过OpenGL ES。可以在Grafika中找到各种示例(例如"来自相机的纹理"以及"记录GL应用")。

我不知道setDisplayPreview()是否适用于除相机之外的其他任何内容。