简介: CSDN博客专家、《Android系统多媒体进阶实战》作者
博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址:Audio工程师进阶系列【原创干货持续更新中...... 】🚀
Android多媒体专栏地址:多媒体系统工程师系列【原创干货持续更新中...... 】🚀
专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
专题三:Android14 Binder之HIDL与AIDL通信实战课 🚀
专题四:Android15快速自定义与集成音效实战课 🚀
专题五:Android15音频策略实战课 🚀
专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例) 🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
更多原创,欢迎关注:Android系统攻城狮

🍉🍉🍉文章目录🍉🍉🍉
-
-
- [🌻1. 前言](#🌻1. 前言)
- [🌻2. 用法与应用场景](#🌻2. 用法与应用场景)
- [🌻3. 调用流程剖析](#🌻3. 调用流程剖析)
-
- [3.1 核心步骤](#3.1 核心步骤)
- [3.2 涉及核心时序图](#3.2 涉及核心时序图)
- [🌻4. 实战应用案例](#🌻4. 实战应用案例)
- [🌻5. 用法总结](#🌻5. 用法总结)
-
🌻1. 前言
本篇目的:Android16音频深度解析之 MediaRecorder.setVideoEncoder 调用流程与实战。
在 Android 多媒体录制体系中,MediaRecorder 是实现音视频捕获的核心组件。setVideoEncoder 方法决定了视频数据在写入文件前采用何种压缩算法。在 Android 16 中,随着硬件编码器(如 AV1、HEVC)的进一步普及,正确配置视频编码器不仅关乎录制的清晰度,更直接影响到文件的体积、功耗以及在不同设备上的播放兼容性。
🌻2. 用法与应用场景
MediaRecorder.setVideoEncoder 用于设置视频录制的编码格式。
- 用法说明 :必须在
setOutputFormat()之后且在prepare()之前调用。常见的编码器常量包括VideoEncoder.H264、VideoEncoder.HEVC(H.265) 以及VideoEncoder.AV1。 - 运行结果 :系统将分配对应的硬编或软编资源。如果设置了硬件不支持的编码器,
prepare()阶段将抛出异常。 - 应用场景 :
- 高清录制 :优先使用
HEVC以在保持高画质的同时减小文件体积。 - 通用分享 :使用
H264以确保录制的视频能在绝大多数旧设备或网页浏览器中正常播放。 - 流媒体传输 :在低带宽环境下使用
AV1编码,利用其极高的压缩比优化网络传输效率。
- 高清录制 :优先使用
🌻3. 调用流程剖析
3.1 核心步骤
- 状态机校验 :
MediaRecorder.java会检查当前状态。setVideoEncoder必须在DataSourceConfigured状态(即设置完输出格式后)调用,否则会抛出IllegalStateException。 - JNI 参数分发 :调用进入
android_media_MediaRecorder.cpp,将 Java 层的编码器常量映射为底层video_encoder类型。 - Stagefright 录制器配置 :指令通过 Binder 发送到
MediaServer进程。StagefrightRecorder接收参数并记录预期的编码器类型。 - 编码器组件实例化 :在
prepare()阶段,系统会根据setVideoEncoder指定的类型,通过MediaCodecList查找匹配的硬件加速组件(如OMX.qcom.video.encoder.avc)。 - 数据链路打通 :
Camera或PersistentSurface产生的原始帧数据被送往MediaCodec编码器,编码后的压缩流随后送入Muxer进行容器封装。
3.2 涉及核心时序图
MediaMuxer MediaCodec / OMX StagefrightRecorder MediaRecorder Native MediaRecorder Java 应用代码层 MediaMuxer MediaCodec / OMX StagefrightRecorder MediaRecorder Native MediaRecorder Java 应用代码层 此时仅保存配置,不分配资源 调用 setVideoEncoder(H264) 校验状态 (must be Configured) native_setVideoEncoder 设置录制参数中的编码类型 调用 prepare() 创建并配置对应的编码器组件 编码器初始化完成 调用 start() 开始写入封装数据
🌻4. 实战应用案例
本案例演示了如何正确配置 MediaRecorder 以使用 H.264 编码录制 MP4 视频。
java
public class VideoCaptureManager {
private MediaRecorder recorder;
public void setupRecorder(Surface previewSurface, String outputPath) {
recorder = new MediaRecorder();
try {
// 1. 设置音频和视频源
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
// 2. 设置输出格式(必须先于编码器设置)
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// 3. 设置视频编码器(本篇核心)
// 注意:顺序必须在 setOutputFormat 之后
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
// 4. 设置音频编码器
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
// 5. 配置视频参数(分辨率、比特率、帧率)
recorder.setVideoSize(1920, 1080);
recorder.setVideoEncodingBitRate(5000000); // 5Mbps
recorder.setVideoFrameRate(30);
recorder.setOutputFile(outputPath);
recorder.setPreviewDisplay(previewSurface);
// 6. 准备录制
recorder.prepare();
System.out.println("MediaRecorder 准备就绪,编码器:H.264");
} catch (IOException e) {
e.printStackTrace();
}
}
public void start() {
if (recorder != null) {
recorder.start();
}
}
public void stop() {
if (recorder != null) {
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}
}
}
🌻5. 用法总结
| 调用层级 | 核心职责 | 关键特性/影响 |
|---|---|---|
| 应用框架层 | 状态机维护与 API 暴露 | 严格遵循 OutputFormat -> Encoder 顺序 |
| 系统服务层 | 参数传递与 Stagefright 路由 |
决定了后续 MediaCodec 的选择策略 |
| 媒体引擎层 | 编码器调度与同步 | 负责处理视频帧的缓冲区流转 |
| 编解码层 | 原始数据压缩 | 性能核心,优先使用硬件加速单元 |
| 硬件抽象层 | 硬件资源映射 | 决定设备是否支持 4K、HDR 或 AV1 编码 |
最优实战方案落地步骤:
- 能力探测 :通过
CamcorderProfile.hasProfile()或MediaCodecList确认当前硬件是否支持目标编码器(如 H.265)。 - 严格排序 :确保
setVideoEncoder在setOutputFormat之后调用,否则会触发应用崩溃。 - 参数对齐 :设置完编码器后,务必显式设置
setVideoEncodingBitRate,否则系统默认比特率可能过低导致画质模糊。 - 异常捕获 :在
prepare()处增加健壮的异常处理逻辑,以防因硬件资源被占用或不支持特定 Profile 而失败。