Android中使用FFmpeg录制视频出现绿色色块覆盖问题求助
解决方案
我之前也碰到过类似的FFmpeg录制绿屏问题,结合你的Gradle配置和症状,给你几个针对性的排查和解决方向:
1. 优先排查像素格式不匹配问题
绿屏最常见的原因就是摄像头输出像素格式和FFmpeg编码格式不兼容。Android摄像头默认输出大多是NV21格式,但FFmpeg的很多编码器只支持YUV420P这类标准格式,格式不对就会导致画面色彩错乱。
- 你可以用OpenCV做格式转换:先把摄像头采集的
NV21字节数组转为OpenCV的Mat,再转成FFmpeg需要的格式:// 假设data是摄像头采集的NV21数据,width/height是分辨率 Mat nv21Mat = new Mat(height + height/2, width, CvType.CV_8UC1); nv21Mat.put(0, 0, data); Mat yuvMat = new Mat(); Imgproc.cvtColor(nv21Mat, yuvMat, Imgproc.COLOR_YUV2YUV_I420); // 转成YUV420P // 再把yuvMat的数据传递给FFmpeg编码 - 或者直接用FFmpeg的
sws_scale工具做格式转换,记得在初始化编码器时把pix_fmt设置为AV_PIX_FMT_YUV420P。
2. 检查帧尺寸是否符合编码器要求
FFmpeg的多数编码器要求帧的宽高必须是2的倍数,如果摄像头输出的是奇数分辨率(比如1081x721),就会出现画面异常。
- 先确认摄像头的采集分辨率,要是有奇数尺寸,就把它调整为最近的偶数尺寸(比如1080x720),或者在转换时对帧做裁剪/缩放处理。
3. 修复Gradle依赖的冲突问题
你的配置里同时混了javacv-platform、单独的预设库和本地jar包,很容易出现版本冲突,导致编码逻辑异常。
- 建议统一依赖方式,要么用
javacv-platform(它已经包含了对应版本的FFmpeg和OpenCV),要么只引入指定架构的预设库,别混合使用。比如改成这样:
这样能避免不同版本库之间的冲突,保证编码逻辑稳定。// 删掉libs下的本地jar依赖 compile group: 'org.bytedeco', name: 'javacv', version: '1.4' compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.4.0-1.4', classifier: 'android-arm' compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.4.0-1.4', classifier: 'android-x86' compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '3.4.1-1.4', classifier: 'android-arm' compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '3.4.1-1.4', classifier: 'android-x86'
4. 验证编码器参数和初始化状态
有时候参数配置错误也会导致绿屏:
- 确认编码器上下文的
width、height、bit_rate等参数和实际采集的帧完全一致; - 一定要检查
avcodec_open2的返回值,看看编码器有没有成功打开,有没有报错信息; - 安卓平台建议优先用硬件编码器
h264_mediacodec,它的兼容性比软件编码器好很多,能减少格式适配问题。
5. 确认原始帧数据是否正常
在把帧传给FFmpeg之前,先把原始摄像头帧显示出来(比如用SurfaceView预览),如果原始帧就有绿块,那问题出在摄像头采集环节,得检查摄像头的权限、初始化代码或者设备本身的兼容性。
内容的提问来源于stack exchange,提问作者Appoorva Faldu




