加水印后音频消失的根本原因是FFmpeg默认只处理视频流(-vf)时自动丢弃音频流,必须显式指定音频处理方式:用-c:a copy无损复制或-c:a aac重编码,且-filter_complex与-c copy互斥。

为什么加水印后音频消失了
根本原因不是水印本身吃掉了声音,而是 FFmpeg 默认只处理视频流(-vf)时,会自动丢弃所有非视频流——包括音频流。哪怕你没显式禁用音频,只要命令里没明确告诉 FFmpeg “把音频也带上”,输出文件就只剩画面。
常见错误写法:ffmpeg -i input.mp4 -i watermark.png -vf "overlay=10:10" output.mp4 —— 这条命令压根没提音频,FFmpeg 就默认不复制也不编码音频,输出自然无声。
必须显式保留或重编码音频
修复的关键是让音频流参与处理流程。有两类稳妥做法,取决于你是否需要重新编码音频:
- 如果原视频音频格式兼容(如 AAC),优先用
-c:a copy无损复制:ffmpeg -i input.mp4 -i watermark.png -filter_complex "[0:v][1:v]overlay=10:10" -c:a copy output.mp4 - 如果复制失败(报错
Could not find a proper output format或音频无法播放),说明封装或编码不匹配,改用重编码:ffmpeg -i input.mp4 -i watermark.png -filter_complex "[0:v][1:v]overlay=10:10" -c:a aac -b:a 128k output.mp4 - 注意:不能只写
-c copy(它会同时复制音视频),但叠加水印必须走-filter_complex,而-c copy和滤镜互斥——这条组合直接报错。
Android 或移动端调用时额外注意
在 Android 上用 FFmpeg 命令行或库(如 Mobile-FFmpeg)加水印后无声,除了上述音频流遗漏问题,还要检查:
- 输入视频路径是否真实可读:Android 10+ 的
content://Uri 不能直接传给 FFmpeg,selectedVideoUri.path大概率返回null,必须先通过ContentResolver拷贝到应用私有目录再传路径; - FFmpeg 构建版本是否启用了音频编解码器:精简版(如
ffmpeg-kit-lite)默认不带aac编码器,-c:a aac会静默失败,需换用ffmpeg-kit-full或改用-c:a libmp3lame(若支持); - 某些旧版 FFmpeg(overlay + 音频流的 map 行为不稳定,升级到 7.1 后仍需强制指定
-map 0:a?显式声明“可选地取输入0的音频”:ffmpeg -i input.mp4 -i watermark.png -filter_complex "[0:v][1:v]overlay=10:10" -map 0:a? -c:a copy output.mp4
验证音频是否真的被包含进去了
别靠播放器“听”,用命令快速确认:
ffprobe -v quiet -show_entries stream=codec_type -of csv=p=0 output.mp4
正常输出应包含两行:video 和 audio。如果只有 video,说明音频流确实没进去——回头检查 -c:a 或 -map 参数是否漏写、拼错,或者输入源本身就没音频(比如录屏时只录了画面)。
最常被忽略的一点:加水印不是“覆盖操作”,而是“重建容器”。音频不会自动继承,每一帧都要你亲手拉进来。

















