Android 使用 MediaRecorder 从 SURFACEVIEW 录制视频

AV *_*eer 2 android surfaceview video-recording android-mediarecorder

我刚来这地方。

我在 android 中有一个应用程序,可以通过网络流式传输相机,并有一个 SurfaceView 组件来显示预览(我正在流式传输的内容)。

我想记录我在预览(surfaceview)中看到的内容而不重新打开相机,因为它刚刚从流中打开。

在棒棒糖中,我看到您可以使用 MediaRecorder api 进行录制并将视频源设置为 SURFACE。

我如何记录简单地添加一个从表面记录的新 MediaRecorder 对象。假设您已完成所有内容设置,应用程序可以正常工作并进行流式传输,并在 SurfaceView 组件中显示预览。我想定义一个新的记录器,并将源设置为表面视图。

谢谢

编辑:

您好,我尝试使用以下代码进行记录:

mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(getVideoFile(activity, true).getAbsolutePath());
mMediaRecorder.setVideoEncodingBitRate(10000000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int orientation = ORIENTATIONS.get(rotation);
mMediaRecorder.setOrientationHint(orientation);
mMediaRecorder.prepare();
Run Code Online (Sandbox Code Playgroud)

假设您有一个应用程序可以打开相机并流出网络并在 SurfaceView 中显示预览。我想添加一个新的媒体记录器来记录表面视图中的内容。

fad*_*den 6

您无法从 SurfaceView 进行录制。当您在 SurfaceView 上播放视频时,帧将被发送到 Surface,它是具有生产者-消费者接口的缓冲区队列。该应用程序只能访问生产者端——系统图形合成器(SurfaceFlinger)是消费者。

您需要做的是播放视频两次,一次用于演示,一次用于录制。对同一视频流进行两次解码效率很低,因此您需要将每个解码帧渲染两次。我还没有使用 MediaRecorder 完成此操作,因此我将提供两种方法。

方法#1:最简单的方法?不要将视频发送到 SurfaceView 的 Surface,而是将 MediaRecorder 置于SURFACE输入模式,并将其输入 Surface(从getSurface()获取)传递给播放器。然后,使用SurfaceView的Surface调用MediaRecorder的setPreviewDisplay 。理论上,这应该可以让您在录制视频时获得视频的“预览”。

方法#2:通过 SurfaceTexture 运行视频。SurfaceTexture 的 Surface 在应用程序中同时具有生产者和消费者接口,因此您可以访问生成的帧。

这确实涉及到一些 OpenGL ES 的工作。基本步骤是:

  1. 在新的 EGL 上下文中创建 SurfaceTexture。
  2. 将视频播放器的输出定向到 SurfaceTexture 而不是 SurfaceView。
  3. 从SurfaceView获取Surface(用于显示),从MediaRecorder获取Surface(用于录制)。后者来自getSurface()
  4. 当 SurfaceTexture 中的每个帧变得可用时,将其渲染到两个 Surface。

这种方法的工作量要大得多,但更灵活,允许在显示和/或记录之前对图像进行操作。一些使用较低级别 MediaCodec 而不是 MediaRecorder 的示例可以在Grafika中找到。