所用到的东西,

FBO:离屏渲染,得到视频数据,这里用FBO是为了以后扩展特效预留;

MediaMuxer:封装音视频输出成MP4

AudioRecord:录制音频;

MediaCode:编解码,把音频编码成AAC ,把视频编码成AVC也就是H264

整个流程图如下:

视频流程:

自定义GLSurfaceView,因为GLSurfaceView继承SurfaceView 把一些GL的东西做了,不用再做,

然后把SurfaceTexture给Camera,

mCamera.setPreviewTexture(surfaceTexture); 

这个是离屏渲染,OpenGL 不能直接拿到相机的数据,通过绑定纹理的方式去预览,拿到每帧渲染数据;通过Renderer onDrawFrame接口回调,这个时候就进行预览绘制,和录制的离屏绘制,然后把离屏绘制的纹理id给录制类进行处理;

// 这个是手动刷新毎帧
mSurfaceTexture.updateTexImage();
// 预览相机的处理
mSurfaceTexture.getTransformMatrix(mtx);
mCameraFilter.setMatrix(mtx);
int textureId = mCameraFilter.onDrawFrame(mTextureID[0]);
// 绘制
mScreenFilter.onDrawFrame(textureId);

然后再去单独处理录制的,

录制的我使用Android自带的OpenGL es,所以需要EGL;然后通过MedicCodec 去缓冲区拿数据并编码,这里需要在同一线程,

/**
 * 4.配置EGL 环境
 */
HandlerThread handlerThread = new HandlerThread("MyMediaRecorder");
handlerThread.start();
Looper looper = handlerThread.getLooper();
mHandler = new Handler(looper);
mHandler.post(new Runnable() {
    @Override
    public void run() {
        mEGL = new MyEGL(mEGLContext, mInputSurface, mContext, mWidth, mHeight);
        mMediaCodec.start();
        isStart = true;
    }
});
/**
 * 录制 真正执行编码的函数
 *
 * @param textureId
 * @param timestamp 时间戳
 */
public void encodeFrame(final int textureId, final long timestamp) {
    if (!isStart) {
        return;
    }
    if (mHandler != null) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mEGL != null) {
                    mEGL.draw(textureId, timestamp);
                }
                getEncodeedData(false);
            }
        });
    }
}

视频编码后的数据放到Mp4RecorderCalbackRenderer里的队列中,然后让MediaMuxer去封装,为什么要放队列?因为还有音频需要一起处理;

音频处理:

使用AudioRecord 录音然后循环取数据,

while (mIsRecording){
    int len = mAudioRecord.read(mBuffer,0,mBuffer.length);
    if (len>0){
        if (mAacEncoder== null){
            return;
        }
        mAacEncoder.queueData(mBuffer);
    }
}

然后编码给Mp4RecorderCalbackRenderer 队列中,然后让MediaMuxer封装;

MediaMuxer是使用时间戳来同步音视频

详细的代码:Seven: Android音视频

Logo

致力于链接即构和开发者,提供实时互动和元宇宙领域的前沿洞察、技术分享和丰富的开发者活动,共建实时互动世界。

更多推荐