如何使用CameraX API在视频保存时为录制视频添加水印
CameraX 录制视频添加水印实现方案
优先方案:零二次处理的实时水印(性能最优)
该方案全程在视频编码前完成水印叠加,输出的本地视频直接是带水印的成品,没有任何转码等待开销,性能损耗极低。
- 前置要求:将项目中CameraX核心依赖、video模块依赖升级至1.3.0及以上版本,该版本开始官方开放视频帧自定义处理入口,无需hack内部逻辑
- 实现逻辑:
- 提前将需要添加的水印(文字、logo图片)绘制成固定Bitmap,在OpenGL环境下初始化为可复用的纹理对象,避免录制过程中重复创建资源
- 自定义类实现
VideoFrameProcessor接口,拿到相机输出的每帧原始纹理后,通过GPU渲染将水印纹理按指定位置、透明度叠加到原始帧上,渲染结果直接输出给VideoCapture的编码Surface - 将实现好的帧处理器封装为
VideoEffect实例,通过VideoCapture.Builder的setVideoEffects()方法绑定到视频录制用例上即可
- 性能表现:整个叠加过程由GPU完成,CPU占用率增幅低于5%,1080P/60fps规格录制不会出现掉帧、卡顿问题。
备选方案:受版本限制无法做实时处理时的最快后处理方案
如果项目无法升级CameraX版本,优先选择硬件加速的后处理方案,比传统纯CPU处理的ffmpeg方案速度快2~4倍:
- 最优选型:基于Android原生
MediaCodec+OpenGL实现硬编转码
解码阶段调用系统硬件解码器拿到原视频的帧纹理,通过OpenGL叠加水印后直接送入硬件编码器输出,全程走GPU和硬件编解码通路,处理1080P/30fps视频的速度可以达到录制速度的2~3倍,且包体积增量仅百KB级别,无额外依赖负担。 - 低代码选型:裁剪优化版ffmpeg
不要使用老旧的纯CPU编译的ffmpeg库,选择开启了MediaCodec硬件编解码、NEON指令集优化的裁剪版ffmpeg,仅保留overlay滤镜相关功能,包体积可控制在3MB以内。添加水印时直接调用硬件编码参数即可,核心命令参考:ffmpeg -i 输入视频路径 -i 水印图片路径 -filter_complex "overlay=20:20" -c:v h264_mediacodec 输出视频路径 - 避坑提醒:不要使用Java层Canvas逐帧处理Bitmap的纯CPU方案,该方案处理1分钟1080P视频通常需要数十秒,性能极差,不建议使用。
内容的提问来源于stack exchange,提问作者Nino Sand
相关产品推荐
相关产品推荐

