资讯动态

Android 音视频编解码(一) -- MediaCodec 初探

发布时间:2026/10/30 1:14:56 来源:尧图企业网站定制
音视频 系列文章Android 音视频开发(一) – 使用AudioRecord 录制PCM(录音)AudioTrack播放音频Android 音视频开发(二) – Camera1 实现预览、拍照功能Android 音视频开发(三) – Camera2 实现预览、拍照功能Android 音视频开发(四) – CameraX 实现预览、拍照功能Android 音视频开发(五) – 使用 MediaExtractor 分离音视频并使用 MediaMuxer合成新视频(音视频同步)音视频工程前面几章我们已经学习了音视频开发的一些知识这几章我们来学习音视频的编解码如果我们只是简单玩一下音频、视频播放那么使用 MediaPlayer SurfaceView 播放就可以了但如果想加个水印加点其他特效什么的那就不行了所以这里先来学习 Android 自带的硬件码类 – MediaCodec。一. MediaCodec 介绍MediaCodec 是 从API 16 后引入的处理音视频编解码的类它可以直接访问 Android 底层的多媒体编解码器通常与MediaExtractor, MediaSync, MediaMuxer, MediaCrypto, MediaDrm, Image, Surface, 以及AudioTrack一起使用1.2 数据交换接下来注意看下面这张官方的图需要好好理解因为整个流程都是按照这个来的可以看到MediaCodec 的数据分为两个部分从数据的输入到编解码后的数据的输出input MediaCodec 会通过getInputBuffer(int bufferId) 去拿到一个空的 ByteBuffer , 用来给客户端去填入数据(比如解码编码的数据)MediaCodec 会用这些数据进行解码/编码处理output MediaCodec 会把解码/编码的数据填充到一个空的 buffer 中然后把这个填满数据的buffer给到客户端之后需要释放这个 bufferMediaCodec 才能继续填充数据。MediaCodec 内部使用异步的方式对 input 和 output 进行数据处理MediaCodec 会把 input 的数据处理好给到 output共用户去渲染注意output 的数据必须释放不然会影响下一次的数据填充。1.3 数据类型编码器共支持3中数据类型压缩数据原始视频数据原始音频数据这三种数据都是可以通过 ByteBuffer 去处理但是你可以使用 Surface 去解析原始的视频数据Surface 使用底层的视频缓冲而不是映射或拷贝到 ByteBuffer这样会大大提高编码效率。但使用 Surface 时无法访问到原始的视频数据所以你可以使用 ImageReader 来访问未加密的解码(原始)数据。在 ByteBuffer 的模式下你也可以使用 Image 或者 getInput/OutputImage(int) 来获取原始视频帧。1.4 编解码的生命周期它的生命周期可以分为三个StoppedExecuting 和 Released而 Stopped 和 Executing 都有各自的生命周期StoppedError、Uninitialized 和 Configured当调用 MediaCodec 时此时会处于 Uninitialized 状态当调用 configure 之后就会处于 Configured 状态然后调用 start() 进入 Executing 状态接着就可以处理数据了。ExecutingFlushed、Running 和 End of Stream当调用 start() 就会进入 Executing 下的 Flushed 状态此时会拿到所有的 buffers当第一帧数据从 dequeueInoutBuffer 队列流出时就会进入 Running 状态大部分时间都在这个状态处理数据当队列中有 end-of-stream 标志时就会进入 End of Stream 状态此时不再接收 input buffer但是会继续生成 output buffer直到 output 也接收到 end-of-stream 标志。你可以使用 flush() 重新回到 Flushed 状态。周期图如下可以使用 stop() 方法回到 Uninitialized 状态当不再使用 MediaCodec 还需要使用 release() 去释放该资源。请一定要理解上面两张图因为后面的编解码都是基于上面的流程的有时候编解码器会遇到错误并处于错误状态此时会通过排队操作的无效返回值或有时通过异常来传达的。调用reset()使编解码器再次可用调用它可以从任何状态回到初始化状态否则就调用 release() 来移动到终端的 release 状态。关于MediaCodec 的编解码流程我们等到下一章再学习。MediaCodec 的主要 API 如下getInputBuffers获取需要编码数据的输入流队列返回的是一个ByteBuffer数组 已弃用queueInputBuffer输入流入队列dequeueInputBuffer从输入流队列中取数据进行编码操作getOutputBuffers获取编解码之后的数据输出流队列返回的是一个ByteBuffer数组 已弃用dequeueOutputBuffer从输出队列中取出编码操作之后的数据releaseOutputBuffer处理完成释放ByteBuffer数据下一章一起学习MediaCodec 的解码Android 音视频编解码(二) – MediaCodec 解码(同步和异步)参考https://developer.android.com/reference/android/media/MediaCodechttps://www.cnblogs.com/renhui/p/7478527.html

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑