Android MediaCodec 视频重编码实战:从原理到性能优化
·
最近在项目中需要处理视频转码功能,调研了多种方案后最终选择使用 Android 原生的 MediaCodec API。今天就来分享一下我的实战经验,希望能帮助到同样需要做视频重编码的开发者。

为什么选择 MediaCodec?
在移动端处理视频时,我们常常遇到以下痛点:
- 性能问题:软件编码器(如 FFmpeg)CPU 占用率高
- 功耗问题:长时间编码导致手机发热严重
- 兼容性问题:不同厂商设备表现差异大
MediaCodec 作为 Android 系统提供的硬件编解码接口,相比 FFmpeg 有三个明显优势:
- 硬件加速:直接调用芯片厂商的编解码器
- 低功耗:专用电路处理,CPU 占用低
- 系统级优化:Google 和厂商共同维护
核心实现步骤
1. 初始化编解码器
// 创建编码器
val encoder = MediaCodec.createEncoderByType("video/avc")
val format = MediaFormat.createVideoFormat("video/avc", width, height)
format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate)
format.setInteger(MediaFormat.KEY_FRAME_RATE, fps)
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, iFrameInterval)
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface)
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
2. 输入输出缓冲区管理
MediaCodec 有两种工作模式:
- 同步模式:适合简单场景
- 异步模式:性能更好,推荐使用

// 异步模式示例
encoder.setCallback(object : MediaCodec.Callback() {
override fun onInputBufferAvailable(codec: MediaCodec, index: Int) {
val buffer = codec.getInputBuffer(index)
// 填充视频数据
codec.queueInputBuffer(index, ...)
}
override fun onOutputBufferAvailable(codec: MediaCodec, index: Int, info: MediaCodec.BufferInfo) {
val buffer = codec.getOutputBuffer(index)
// 处理编码后的数据
codec.releaseOutputBuffer(index, false)
}
})
性能优化技巧
经过多次测试,我总结了几个关键优化点:
- 色彩空间转换:
- 优先使用 COLOR_FormatYUV420Flexible
-
避免多次色彩空间转换
-
内存复用:
- 复用 ByteBuffer 对象
-
使用 Surface 输入避免内存拷贝
-
参数调优:
- 根据设备性能动态调整 BITRATE_MODE
- 合理设置 KEY_FRAME_RATE
常见坑点
在适配不同 Android 版本时,我遇到了这些问题:
- Android 5.0 以下:某些 COLOR_FORMAT 不支持
- 华为设备:需要特殊处理编解码器名称
- 三星设备:Surface 输入有时会丢帧
解决方案是做好设备检测和降级处理:
fun isFormatSupported(codecInfo: MediaCodecInfo, mime: String, format: Int): Boolean {
return codecInfo.getCapabilitiesForType(mime)
.colorFormats.any { it == format }
}
测试建议
最后分享下我的性能测试方法:
- 使用 adb shell dumpsys media.codec 查看实际使用的编解码器
- 通过 Systrace 分析帧处理耗时
- 监控温度变化和 CPU 使用率
对于想进一步优化的同学,可以研究下:
- 使用 MediaCodec 的异步模式
- 尝试 H265 编码
- 结合 MediaMuxer 实现流式输出
希望这些经验对你有所帮助,欢迎在评论区交流你遇到的问题和解决方案!
更多推荐


所有评论(0)