android MediaCodec录视频原理

简介

使用android自带的sdk完成视频录制需要用到MediaCodec、AudioRecord、MediaMuxerd等api,sdk使用的是硬编码,理论上说速度是较快的,但是各个厂商内部实现原理不一样,肯能并不如ffmepeg软编码

  • MediaCodec 可以实现音视频的编解码
  • AudioRecord 录音api,输出的是音频裸流
  • MediaMuxer 将音视频数据合成一个文件,主要是根据通道不同向其写入数据
    至于视频数据,则是通过cramer设置预览回调previewCallback获取原始视频数据,转换后传递给MediaCodec即可

MediaCodec

使用MediaCodec进行编解码需要知道其编解码过程所使用到的组成,其由输入缓存队列(ByteBuffer数组)和输出缓存队列,编码时,先获取输入流队列,从其中找到一个空闲位置的下标index,在向这个位置写入数据,MediaCodec拿到数据编码;输出时时类似

  • mediaCodec.getInputBuffers() 获取输入流队列
  • queueInputBuffer:输入流入队列
  • dequeueInputBuffer:从输入流队列中取数据进行编码操作
  • getOutputBuffers:获取编解码之后的数据输出流队列,返回的是一个ByteBuffer数组
  • dequeueOutputBuffer:从输出队列中取出编码操作之后的数据
  • releaseOutputBuffer:处理完成,释放ByteBuffer数据

编码解码都是这个流程,主要是配置MediaCodec时,配置的是一个编码Codec就是编码,解码Codec就是解码

AudioRecord

直接录取音频原始数据流,使用前提前获取AudioRecord能接收最小的录音大小,然后初始化一个buffer至少到与这个最小值,开始录音后,就从AudioRecord读取data,送入Codec进行编码

视频数据录取

使用camera前设置视频格式,尺寸大小以及预览回调,视频格式参考我的另一篇文章YUV420可进一步了解格式,需要注意的时,camera录取的数据不能直接送入MediaCodec编码,需要对其转换一下才行,不然会出现花屏。

MediaMuxer

混合音视频组装成文件,音视频数据对应不同的Track通道,分别写入数据即可;MediaExtractor和Muxer相反,它是负责把音视频流分解成多个通道输出,分别输出各通道的数据,出来的数据也是编码过的,如果播放还需要交给MediaCodec解码在播放的

除以上谈到的录制API,Android还提供了MediaRecorder录制,MediaRecorder录制是在AudioRecord上封装了一层,录取数据是编码并形成文件的