网页视频加水印的四种方式对比:选错方案返工重来

「给视频加个水印」这个需求,产品经理说起来是一句话,做起来是四条完全不同的技术路线。选错路线的代价是返工:CSS 方案上线两周后要加用户 ID,发现做不到;FFmpeg 预压制上线三个月要换水印文案,几万个视频重转一遍。本文把四种方式的实现、优劣、适用边界摆在一起,帮你第一次就选对。

先明确需求,再看方案

加水印的需求至少分五个维度,先问自己:

  1. 静态还是动态:固定 Logo,还是要移动的防录水印?
  2. 要不要用户变量:水印里要不要出现「当前观众」的 ID?
  3. 换水印的成本:改一次水印,要不要重新处理视频文件?
  4. 清晰度要求:水印是「有就行」还是必须锐利?
  5. 实现预算:前端十分钟,还是后端转码流水线?

方式一: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>

CSS 覆盖层水印 图 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 烧录通用层 + 播放器原生用户层,两层叠加。

相关文章