
本教程以「抖音 / 快手 / B站 短视频去水印」小程序为案例,白话讲解从注册账号到提交审核上线的全过程。
文中不贴代码,只讲清楚每一步做什么、为什么这么做、关键配置填什么。真实项目代码在 watermark-remover/ 目录里。
目录
- 你将做出什么
- 第一章:准备工作(账号、工具、云开发)
- 第二章:理解小程序 + 云开发的架构思路
- 第三章:搭建项目骨架
- 第四章:写第一个页面
- 第五章:核心——解析云函数
- 第六章:前端调用与保存相册
- 第七章:封面优化——截取视频首帧
- 第八章:绕过域名白名单的秘诀
- 第九章:隐私权限与提审
- 第十章:部署与发布
- 第十一章:平台接口多变,如何维护
1. 你将做出什么
一个微信小程序:用户粘贴抖音 / 快手 / B站的分享链接 → 解析出无水印视频地址和视频首帧封面 → 一键保存到相册。支持三平台识别、去水印、自定义进度条保存。
2. 第一章:准备工作
注册小程序账号 打开微信公众平台,用邮箱注册「小程序」类型账号,激活后进入「开发设置」拿到 AppID(wx 开头的一串)。个人主体即可,选「工具/效率」类目就能上架这类工具。
安装开发者工具 下载微信开发者工具稳定版,用注册微信号扫码登录。新建或导入项目时填你的 AppID。
开通云开发 在开发者工具里点「云开发」按钮开通,创建一个环境(起个名,比如 watermark-prod),记下环境 ID。后面重活(解析、下载、抽帧)都放在云函数里做,前端只管展示和保存。
为什么要云开发?小程序前端运行在用户微信里,不能随便请求任意域名,也处理不了视频。把脏活累活交给云函数,前端只拿结果。

3. 第二章:架构思路(最重要的一章)
整个数据流是这样走的:
- 前端把用户粘贴的链接,通过 callFunction 发给云函数 parse。
- 云函数负责:识别平台 → 抓取页面 → 解析出无水印地址 → 抽首帧 → 把封面/视频转存到云存储 → 把结果(含云存储链接)返回前端。
- 前端用返回的链接展示封面、播放预览;用户点保存时,前端再用 wx.cloud.downloadFile 从云存储取文件,写入相册。
为什么必须走云存储中转? 前端播放视频、下载文件、显示图片,都受「downloadFile 合法域名」白名单约束。抖音、快手、B站的 CDN 域名是动态变化的,根本没法一个个加白名单。而云存储的域名是微信自动加白的,所以把第三方视频先下载到云函数、再上传云存储、前端用 fileID 取,就彻底绕开了限制。这一招是正式版能用的关键。
4. 第三章:搭建项目骨架
项目分两大部分:前端页面(pages/index)和云函数(cloudfunctions/parse)。
全局配置(app.js / app.json)要做三件事:
- 初始化云环境,把环境 ID 填进去(换成你自己的)。
- 在 app.json 里声明「相册写入权限」的用途描述,以及把 getClipboardData(读取剪贴板)加进隐私接口声明 requiredPrivateInfos。不声明的话审核会被拒。
- project.config.json 里把云函数根目录指到 cloudfunctions/,并保留 urlCheck:false(仅本地调试用,正式版不生效)。
5. 第四章:写第一个页面
页面从上到下就四块:
- 输入区:一个多行文本框 + 「粘贴」「清空」按钮 + 「开始解析」按钮。粘贴按钮调用系统剪贴板读取,把链接自动填进框里。
- 结果区(解析成功才显示):平台标签、标题文案、封面大图、「保存封面」按钮、视频预览、「保存到相册」「复制链接」按钮。
- 保存进度区:一个自定义进度条,转存阶段显示流动动画,下载阶段显示真实百分比。
- 错误提示区:解析失败时显示原因。
两个平台差异要处理:
- 抖音 / 快手:直接用
- B站:因为 CDN 防盗链,前端
一个 WXML 语法坑:条件渲染只有 wx:if / wx:elif / wx:else。wx:elif 后面必须带条件表达式,光写 wx:elif 不写条件会编译报错。要么补条件,要么直接改成 wx:else。
6. 第五章:核心——解析云函数
云函数做四件事:识别平台、抓取页面、解析去水印地址、处理封面。
平台识别:根据链接里的关键词判断是抖音、快手还是 B站。
抖音解析(重点在去水印): 抖音分享页的数据藏在页面里的 window._ROUTER_DATA 这个全局变量里,结构是 loaderData 下面一个 video_开头 的 key,再往下 videoInfoRes.item_list[0]。从这里能拿到播放地址和封面。 去水印的核心操作是:播放地址里把 playwm 替换成 play,得到的就是无水印版本。 坑:别用「全局搜索 origincover」这种偷懒办法取封面,会误命中作者头像(avatar)和 BGM 封面。要走精确路径取 video.cover。另外 loaderData 里有个 videolayout 的 key 值是空的,不能无脑取第一个,要先筛出真正含视频数据的那个 key。
快手解析(坑最多): 快手在 2026 年把页面改成了 SPA 化,不再保证服务端渲染出数据变量。所以解析时要带完整的浏览器请求头,并且用正则直接扫整页 HTML 来兜底提取封面图地址和视频 mp4 地址。无水印地址的窍门是:视频地址列表里最后一项通常带水印,取倒数第二项就是无水印的。如果整页啥也扫不到,就老老实实报错「页面已改版,暂时无法解析」,别硬凑。
B站解析(走官方 API): 先从链接里抠出 BV 号(短链就先追重定向拿到 BV 号),然后调 B站的「视频信息接口」拿 cid 和标题,再调「播放地址接口」拿真实播放地址。封面用接口返回的 pic 字段。 关键:B站 CDN 必须带 Referer: https://www.bilibili.com 请求头,否则返回 403。所以云函数下载 B站视频和前端预览都要带上这个头——这也是为什么前端直接用
7. 第七章:封面优化——截取视频首帧
用户的核心需求:封面应该是视频的第一帧画面,不是作者头像,也不是平台给的封面图。
做法分三步:
- 装 ffmpeg:用 ffmpeg-static 这个 npm 包,它自带 Linux 静态二进制,云函数云端安装后直接能调用,不用系统预装 ffmpeg。代码里先做路径解析(优先 ffmpeg-static,找不到再回退系统 ffmpeg),用之前再 chmod 一下防权限问题。
- 抽首帧:云函数把视频下载到临时目录,调 ffmpeg 只取第一帧输出成 jpg。命令要点:只取一帧、定位到开头、设个质量参数、加 update 参数兼容单图写法(否则会报「不是图片序列」的错)。
- 转存云存储:把抽出来的 jpg 上传到云存储,再取一个临时 https 链接返回前端。这样封面也走云存储,正式版预览不受白名单限制。
平台差异处理:
- 抖音 / 快手:用首帧当封面(用户明确要求)。
- B站:用平台自带的 pic 缩略图(转存到云存储),因为 B站很多视频开头是黑屏或 intro,首帧做封面反而难看。
- 任何平台首帧抽取失败:自动回退成把平台封面图转存云存储,绝不因为抽帧失败就让整个解析报错。
8. 第八章:绕过域名白名单的秘诀
前面架构章提过原理,这里说具体做法。
前端播放/下载/显示第三方 CDN 内容受白名单约束,但云函数服务端发请求不受这个限制。所以:
- 解析云函数拿到第三方直链后,在云函数里用 HTTP 请求把文件下载下来(带上对应平台的 Referer 防盗链头)。
- 用云存储上传接口把文件传上去,拿到 fileID。
- 前端用 wx.cloud.downloadFile({ fileID }) 取文件——云存储域名自动加白,正式版可用。
记住:开发者工具里勾「不校验合法域名」只是本地调试,正式版照样受限。中转是生产环境必做的,不是可选项。
9. 第九章:隐私权限与提审
版本描述(提交审核时填) 写清楚这版做了什么。示例:「新增短视频去水印解析功能,支持识别抖音/快手/B站分享链接,提取无水印视频并一键保存至相册。本次优化封面显示逻辑——抖音快手封面改为截取视频首帧,B站预览改为封面图展示(解决防盗链黑屏),所有封面统一经云存储中转确保正式版正常加载。」(约 100 字,留有余量)
隐私采集选择 因为小程序用到了「读取剪贴板」和「写入相册」,都属于隐私接口,所以选「采集用户隐私」,并补全隐私保护指引:
- 相册(仅写入)权限用途:将解析后的视频/封面保存至手机相册。
- 剪贴板读取用途:获取你主动粘贴的分享链接,用于解析视频地址。
第三方 SDK 填微信云开发 SDK,说明用于调用云函数和云存储中转即可(微信自家的,通常不卡审核)。
别忘了在 app.json 声明:把 getClipboardData 加进隐私接口声明,并写相册权限的 desc 描述,否则审核被拒。
10. 第十章:部署与发布
部署云函数(关键) 本环境无法用命令行部署(缺少私钥和 CLI,命令行还报过 token 过期的错),必须走开发者工具的图形界面:
- 开发者工具里打开项目,左侧找到 cloudfunctions/parse。
- 右键 → 上传并部署:云端安装依赖。务必选「云端安装依赖」这一项,这样 ffmpeg-static 才会在云端装上 Linux 二进制。
- 等部署完,在「云开发 → 云函数」里看到 parse 状态变「在线」就成功了。
如果只选「上传并部署:不含依赖」,云端就没有 ffmpeg 二进制,首帧功能会失效。
上传代码 & 提交审核
- 顶部「上传」,填版本号(如 1.0.1)和版本描述。
- 上传后到公众平台管理后台,先发「体验版」自己扫码测一遍。
- 没问题就「提交审核」,填隐私信息,等 1~7 天。
- 审核通过后再全量发布。
11. 第十一章:平台接口多变,如何维护
各平台接口随时变,解析逻辑要定期维护。常见状况和应对:
- 抖音偶发反爬空壳:同一链接有时返回空页面,加重试即可;长期可带 cookie 或用第三方解析服务。
- 抖音封面误成头像:一定要走精确路径取视频封面,别全局搜。
- 快手 SPA 化:页面不再服务端渲染数据,带完整浏览器头 + 整页正则兜底,本例已部分失效,需持续跟进。
- B站 403:下载必须带 B站 Referer。
- 封面正式版不显示:一律走云存储中转,别用第三方直链。
- ffmpeg 不可用:部署时选「云端安装依赖」,用前 chmod 防权限。
调试建议:云函数里多打日志,在开发者工具的「云开发 → 日志」里能看到每次调用的完整输入输出,比瞎猜快得多。

本教程的讲解均来自真实项目 watermark-remover/。平台接口持续变化,落地时以实际抓取结果为准,按维护清单灵活调整即可。
GitHub开源链接:
本文是对公开笔记的知识化整理;原帖中的收入、流量、效果等数据属于原帖陈述,未作独立验证。