使用 MediaRecorder 录制视频时,如何设置分辨率、帧率和码率?
解读
面试官问“如何设置”并不是想听一句“调 setVideoSize / setVideoFrameRate / setVideoEncodingBitRate 就行”,而是考察候选人是否:
- 知道 MediaRecorder 的“先解锁摄像头 → 配置 CamcorderProfile → 再绑定到 MediaRecorder”这一套国内 ROM 也通行的生命周期;
- 能区分“Profile 硬编码能力”与“业务层动态降级”两套策略,避免在低端机上直接写死 1080p 导致 prepare() 抛 CamcorderProfile 为 null 的 Crash;
- 理解帧率、码率与最终文件大小、发热、编解码器负载之间的权衡,能给出“国内短视频 720p@30 fps 1.5 Mbps”这样可直接落地的经验值;
- 熟悉国产定制 ROM(华为、小米、OPPO)对 MediaRecorder 的隐藏限制,例如部分机型强制要求 setOutputFormat 必须在 setVideoSource 之后立即调用,否则报 -38 错误。
知识点
- MediaRecorder 状态机:Initial→Initialized→DataSourceConfigured→Prepared→Recording→Released,任何参数设置必须在对应状态之前完成,否则抛 IllegalStateException。
- CamcorderProfile 与动态参数两套 API:
- 官方推荐 CamcorderProfile.hasProfile(cameraId, quality) 先判存在,再用 profile.videoFrameWidth/Height、profile.videoFrameRate、profile.videoBitRate 一次性 apply 到 MediaRecorder;
- 若要做“非标准分辨率”或可变帧率,需手动 setVideoSize(w,h)、setVideoFrameRate(fps)、setVideoEncodingBitRate(bps),但必须先通过 CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP 查询 MediaCodecInfo.CodecCapabilities 是否支持该组合,否则 prepare() 直接崩溃。
- 国内兼容性细节:
- 华为 EMUI 11 之后若 targetSdk≥31,需在 AndroidManifest 声明 android:hardwareAccelerated="true" 且动态申请 CAMERA+RECORD_AUDIO,否则 MediaRecorder.start() 报 “start failed -22”;
- 小米 MIUI 14 对后台录制限制极严,若应用退到后台 5 s 内未调用 startForegroundService,系统会强制 reset MediaRecorder,表现为主播端“点击开始录制后秒退”。
- 性能与体验权衡:
- 帧率:短视频业务 30 fps 足够,直播带货场景可降到 24 fps 降低发热;
- 码率:720p 使用 1.5–2 Mbps、1080p 使用 3.5–4 Mbps,在 H.264 baseline 下可兼顾清晰度与上传流量;
- 分辨率:国内低端 4G 存量机(Android 8–9)最高仅支持 1280×720@30 fps,需在代码层做 capability 降级,不能依赖后台配置。
答案
分三步落地,兼顾兼容性与性能:
第一步:获取相机能力
CameraManager cm = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String backId = cm.getCameraIdList()[0];
CameraCharacteristics chars = cm.getCameraCharacteristics(backId);
StreamConfigurationMap map = chars.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] videoSizes = map.getOutputSizes(MediaRecorder.class);
// 取最大 720p 尺寸作为上限
Size targetSize = chooseMax720p(videoSizes);
第二步:构造 Profile 或手动参数
MediaRecorder recorder = new MediaRecorder();
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)) {
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);
profile.videoBitRate = 1_500_000; // 国内 720p 1.5 Mbps
profile.videoFrameRate = 30;
recorder.setProfile(profile);
} else {
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setVideoSize(targetSize.getWidth(), targetSize.getHeight());
recorder.setVideoFrameRate(30);
recorder.setVideoEncodingBitRate(1_500_000);
}
第三步:对齐与启动
recorder.setPreviewDisplay(surface);
recorder.setOutputFile(outputPath);
try {
recorder.prepare();
recorder.start(); // 进入 Recording 状态
} catch (IOException e) {
// 国产 ROM 常见 -38、-22 错误在此捕获,提示用户“权限或参数不支持”
}
录制完成后按顺序 stop()→reset()→release(),防止小米 ROM 报 “media server died” 异常。
拓展思考
- 如果产品需求是“60 fps 高帧率 + 慢动作回放”,MediaRecorder 已无法满足,需要转向 MediaCodec + Camera2 自定义流水线,同时把帧率提升到 120 fps,码率同步翻倍到 6–8 Mbps,并手动写 MP4 封装(MediaMuxer),此时要处理国产芯片平台(麒麟、天玑)对 H.264 High Profile 的兼容差异。
- Android 14 引入 Ultra HDR 录制,需使用 Camera2 的 DynamicRangeProfiles.HLG10 并搭配 MediaRecorder.setVideoHDR(true),但目前小米 14 系列仅开放给系统相机,第三方应用调用会抛 UnsupportedOperationException,面试时可作为“国内 ROM 策略限制”案例,展示对最新趋势的跟踪。
- 对于隐私合规,国内监管要求“录制前必须弹窗告知用户并征得同意”,可在 MediaRecorder.start() 前插入自定义蒙层,同时把录制文件路径存入 MediaStore.VOLUME_EXTERNAL_PRIMARY,确保卸载后用户仍可在系统相册回看,避免“强行写私有目录”被应用市场审核驳回。