网页视频加水印的四种方式对比:选错方案返工重来
「给视频加个水印」这个需求,产品经理说起来是一句话,做起来是四条完全不同的技术路线。选错路线的代价是返工:CSS 方案上线两周后要加用户 ID,发现做不到;FFmpeg 预压制上线三个月要换水印文案,几万个视频重转一遍。本文把四种方式的实现、优劣、适用边界摆在一起,帮你第一次就选对。
先明确需求,再看方案
加水印的需求至少分五个维度,先问自己:
- 静态还是动态:固定 Logo,还是要移动的防录水印?
- 要不要用户变量:水印里要不要出现「当前观众」的 ID?
- 换水印的成本:改一次水印,要不要重新处理视频文件?
- 清晰度要求:水印是「有就行」还是必须锐利?
- 实现预算:前端十分钟,还是后端转码流水线?
方式一:CSS/DOM 覆盖层
最直觉的方案:<video> 上叠一个绝对定位的 div,文字或图片放里面。
<div class="stage" style="position:relative">
<video src="lesson.mp4" controls></video>
<div class="wm" style="position:absolute;top:8%;right:3%">© MyCourse</div>
</div>
图 1:CSS/DOM 覆盖方案——原生 video 叠定位 div
优点:十分钟上线,纯前端,改文案改样式即时生效。 致命缺点:全屏播放时覆盖层跟着视频走?不同浏览器行为不一;录屏工具抓的是合成画面,但更关键的是——播放器一进全屏/画中画,DOM 覆盖层往往丢失或错位;无法跟随视频画面区域(信箱黑边、画面裁切时水印跑到黑边上)。 适用:内网工具页、内部 demo,凑合用。
方式二:Canvas 后期绘制
用 Canvas 逐帧抓取 drawImage(video) 再叠字,或者干脆用于生成水印贴图。能做到逐帧动态(比如跟随画面的运动水印),代价是:
- 每帧绘制吃 CPU/GPU,4K 视频明显发热掉帧;
- 全屏、画中画、硬件解码路径都会踩坑;
- 本质还是「网页层」水印,防录能力与 CSS 同级。
适用:需要水印与画面内容联动的特效场景,少见。
方式三:FFmpeg 预压制(烧录进画面)
ffmpeg -i in.mp4 -vf "drawtext=text='© MyCourse':x=10:y=H-th-10" out.mp4
把水印直接烧进视频像素,任何播放器、任何下载传播都带着水印。
优点:最「硬」——下载原文件也带水印;零前端成本。 缺点:每个用户相同的静态水印——没有用户变量,溯源无从谈起;换水印 = 全量视频重转码,存储与计算成本随视频数线性增长;与 HLS/DASH 切片流水线耦合,一处改处处改。 适用:品牌声明类水印 + 视频数量稳定的内容库。不适合需要用户溯源的付费内容。
方式四:播放器原生水印(ZWPlayer watermarks)
成熟播放器把水印做成播放能力的一部分——ZWPlayer 的 watermarks 配置:
new ZWPlayer({
playerElm: 'player',
url: 'lesson.mp4',
watermarks: [
{ type: 'text', behavior: 'static', text: '© MyCourse', dock: 'left', x: '3%', y: '90%' },
{ type: 'text', behavior: 'dynamic', text: '{user_id} · {sys_time}',
movement: { direction: 'random', speed: 3 } },
{ type: 'text', behavior: 'tile', text: '内部资料 · {user_id}',
tile: { angle: -30, rowSpacing: 110, colSpacing: 280 } },
],
variables: { user_id: '138****1234' },
});
- 水印渲染在播放器渲染层内,全屏/画中画/网页全屏行为一致,跟随视频画面区域而非容器黑边;
- 三种行为(静态/动态游走/平铺)与
{user_id}/{sys_time}宏变量开箱即用——用户变量、动态防录这两个「CSS 做不到、FFmpeg 做不起」的需求一次满足; - 水印与视频文件分离,换水印零转码:改一份 JSON 全站生效;
- 配合 Watermark Studio 可视化编辑器拖拽配置,不用手写 JSON。
效果即《视频防录屏完全方案》图 4 的三层组合。
对比总结
| CSS 覆盖 | Canvas | FFmpeg 烧录 | 播放器原生 | |
|---|---|---|---|---|
| 实现成本 | 极低 | 高 | 中(流水线) | 低(配置) |
| 动态水印 | 难 | 可 | 不可 | 内置 |
| 用户变量 | 可(脆弱) | 可 | 不可 | 内置宏 |
| 全屏/画中画一致 | 常出问题 | 常出问题 | 一致 | 一致 |
| 换水印成本 | 即时 | 即时 | 全量重转码 | 改配置即时 |
| 下载原文件带水印 | 否 | 否 | 是 | 否 |
选型结论:
- 只要品牌标识、视频量稳定 → FFmpeg 烧录最省心;
- 内部工具页 → CSS 覆盖够用;
- 付费内容、需要用户溯源、水印策略会迭代 → 播放器原生水印是唯一同时满足「动态 + 变量 + 低换装成本」的路线;
- 究极场景(下载原文件也要带用户水印)= FFmpeg 烧录通用层 + 播放器原生用户层,两层叠加。