ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

短视频去水印微信小程序:JavaScript解析与下载原理

短视频去水印微信小程序:JavaScript解析与下载原理 简介一套基于JavaScript开发的短视频去水印微信小程序完整源码与配套文档整合短视频去水印、无水印下载、历史解析记录、积分签到、福利页与个人中心等实用功能面向小程序开发者及计算机相关专业学生可作为毕业设计、课程设计或项目初期立项演示的模板。压缩包共70个文件大小约280KB文件以PNG图片、JSON配置、WXSS样式、JS逻辑和WXML结构为主附带LICENSE与说明文档页面按首页、视频解析、福利、帮助等模块划分并封装了网络请求与通用工具函数同时含有ColorUI组件便于读者对照源码理解微信小程序的项目组织方式。代码经作者测试运行成功毕设答辩平均分达96分并支持扫码预览能够快速查看实际效果当前已有75人学习下载适合作为练手项目或二次开发基础。如需在此基础上扩展可继续完善广告接入、积分签到、解析历史下载等功能也可替换界面元素直接用于课程作业或初期演示。1. 短视频去水印微信小程序这个标题到底在解决什么问题你大概也遇到过这种场景在短视频平台看到一个不错的教程想存到相册里慢慢看结果保存下来的视频右下角永远挂着一个平台水印和账号 ID。发给同事、剪进自己的素材库观感都差一截。这个标题解决的正是“把已经公开分享出来的视频在本地去掉平台水印再存进相册”这个具体诉求。我把它翻译成技术语言就是拿到用户粘贴的短视频分享链接解析出无水的播放地址下载视频文件再写入用户手机相册。整个过程用微信小程序 JavaScript 就能完成不需要服务器转码不需要自建 CDN天然适合微信生态内“复制链接→粘贴→保存”的交互习惯。这个方向适合三类人想做工具类小程序练手的开发者需要批量收集素材做二次剪辑的内容运营以及想搞清楚“小程序里的视频到底是怎么从平台侧拿下来的”的入门者。注意一点去水印不等于去版权只处理自己有权使用的视频这个我在最后一章会单独说。2. 去水印的技术原理与小程序选型为什么是 JavaScript 而不是后端转码2.1 去水印的三种常见做法改播放地址、裁剪画面、重编码先说清楚“去水印”在技术上有哪几条路不然容易被网上零散的教程带偏。第一种做法是改播放地址。短视频平台在分发视频时带水印的地址和不带水印的地址往往指向同一个视频文件只是 URL 参数不同。解析分享链接拿到视频 ID再拼接一个不含水印参数的新播放地址就能直接下载到原始画面。这个方案零转码开销速度最快也是绝大多数“一键去水印”工具的核心逻辑。第二种做法是裁剪画面。水印如果固定在某个角落直接把视频裁掉那一块也能去掉但会损失画面内容观感很差。一般只在无法拿到无水印地址时作为兜底。第三种做法是重编码。把视频下载到本地后逐帧处理覆盖水印区域。这在服务端用 FFmpeg 能实现但小程序里不现实——JS 侧跑视频解码逐帧处理性能撑不住而且小程序包体积和内存限制会把这条路堵死。所以标题里“JavaScript 实现”并不是噱头。它明确指向第一种做法小程序端只做“请求→解析→下载→保存”不做任何画面处理。这也是我推荐的最可靠落地方案。2.2 为什么小程序端用 JavaScript 就够了省服务器、省带宽、省审核很多人的第一反应是“我是不是得先有个后端在后端解析好再返回给小程序”。这个想法没错但把复杂了。微信小程序前端跑的是 JavaScript而wx.request允许小程序直接请求外部 HTTPS 接口。短视频平台的分享接口和播放地址接口本质上是公开可访问的 HTTP 服务只是参数有规律。你完全可以在小程序端直接完成请求和解析把结果交给wx.downloadFile下载。这样做的好处非常实际第一省服务器。不需要自己维护任何后端服务整个小程序就是一个纯前端工程托管静态资源就行服务器成本为零。第二省审核时间。纯前端代码不涉及“视频存储、分发”这类高风险类目提审的时候用“工具-效率”类目就能过。第三省流量。小程序端只传文本和 URL真正的视频文件是微信客户端直接下载到用户本地的不经过你的服务器不产生任何带宽费用。缺点是有的如果平台端改了接口的签名校验策略你的小程序端代码也得跟着改没法像后端那样“悄悄热更新一段逻辑”。不过对入门级工具来说这个代价可以接受。2.3 接口请求的完整生命周期分享链接 → 视频 ID → 无水印播放地址把流程拆开你会看到这个系统其实只有四个环节。第一步用户从短视频 App 复制分享文案粘贴进小程序的输入框。分享文案通常是“复制打开XXX看看这个视频”这类带口令的文字。第二步从文案里提取真正有用的部分。这里有一个关键点分享文案里的 URL 往往被折叠成了短链比如v.douyin.com/xxxx这种。小程序端要自己请求一次这个短链跟随重定向拿到完整的视频页面 URL。第三步从完整 URL 或页面源码里提取视频 ID。不同平台的提取规则不同有的在路径里有的在 query 参数里有的要解析页面里的 JSON 数据。这部分就是“解析”的核心也是后面代码示例里我最看重的函数。第四步用视频 ID 去请求播放地址接口拿到无水印的视频文件的直链交给下载模块。整个链路里最脆弱的环节是第三步和第四步之间的“接口参数构造”。平台的接口通常会带时间戳、签名等参数这些参数有的是固定算法有的随页面返回。我一般会优先解析页面里已经存在的 JSON 数据而不是自己拼签名——不造请求只做“搬运”稳定性会好很多。3. 把「解析—取流—存本地」跑通小程序端最小可运行代码这一章直接给可复现的代码。假设你已经用微信开发者工具创建了一个 JavaScript 空项目接下来从解析入口开始写。3.1 用 JavaScript 函数解析分享文案和短链先把用户粘贴的分享文案清洗干净提取短链并跟随重定向。// utils/parser.js function extractShortUrl(text) { // 从分享文案中提取 https 短链兼容换行和中文符号 const matched text.match(/https?:\/\/[^\s\u4e00-\u9fa5]/); return matched ? matched[0].replace(/[。]/g, ) : null; } function getRealShareUrl(shortUrl) { // 请求短链跟随重定向拿到完整的分享页 URL return new Promise((resolve, reject) { wx.request({ url: shortUrl, method: GET, // 不跟随重定向会拿不到真实地址必须让微信自动跳转 followRedirect: true, success(res) { // 短链请求成功后可能已经落到最终页面 // 这里优先取 res.data 里的 canonical 或 og:url 字段 const finalUrl res.data.match(/link relcanonical href([^])/); resolve(finalUrl ? finalUrl[1] : shortUrl); }, fail: reject }); }); }这段代码的逻辑是先用正则把用户粘贴的分享文案里的 URL 抠出来再做一次真实请求。注意followRedirect: true必须显式声明不然短链只返回 302你拿不到最终的完整分享页地址。canonical字段是标准 HTML 里声明“当前页面权威地址”的标签绝大多数内容平台都会输出比解析og:url更稳定。3.2 提取视频 ID 并组装无水印播放地址拿到完整的分享页 URL 之后核心工作是提取视频 ID。下面这段代码以常见的短视频平台为例做了三种规则的兼容。// utils/video.js function extractVideoId(pageUrl) { // 常见规则一URL 路径中的纯数字 ID // 例如 https://xxx.com/video/7123456789012345678 let id pageUrl.match(/\/video\/(\d{15,})/); if (id) return id[1]; // 常见规则二query 参数中的 vid / video_id // 例如 https://xxx.com/?vid7123456789012345678fromshare id pageUrl.match(/[?](?:vid|video_id)(\d{15,})/); if (id) return id[1]; // 常见规则三页面 JSON 数据中的 uri 字段 // 这个规则需要配合 3.1 节里拿到的页面 HTML 一起用 // 这里的逻辑是在 HTML 里搜 uri:xxxxxxxx const html globalThis.__pageHtml || ; const uri html.match(/uri:([^])/); if (uri) return uri[1]; return null; } function buildPlayUrl(videoId) { // 将 videoId 拼进平台公开的播放地址模板 // 不同平台模板不同核心思路是替换 id 占位符 const template https://xxx.com/play/?video_id{id}watermarknone; return template.replace({id}, videoId); }这段代码展示的是提取逻辑的“骨架”。真实项目中第三步里的globalThis.__pageHtml来自对分享页的二次请求你需要把页面源码缓存在内存里供提取使用。watermarknone这个参数名在不同平台不一样有的是watermark0有的是去掉wm参数需要对着页面里实际出现的参数来抄。3.3 用 wx.downloadFile 加 wx.saveVideoToPhotosAlbum 落库解析出无水印播放地址后下载和保存是最后一个关键动作。// pages/index/index.js Page({ data: { url: , status: idle // idle | loading | done | error }, onInput(e) { this.setData({ url: e.detail.value }); }, async onResolve() { const { url } this.data; if (!url) return; this.setData({ status: loading }); try { // 第 1 步清洗文案拿到短链 const shortUrl extractShortUrl(url); if (!shortUrl) throw new Error(没有识别到分享链接); // 第 2 步跟随重定向拿分享页真实地址 const realUrl await getRealShareUrl(shortUrl); // 第 3 步从页面 URL 提取视频 ID const videoId extractVideoId(realUrl); if (!videoId) throw new Error(未匹配到视频 ID); // 第 4 步组装无水印播放地址 const downloadUrl buildPlayUrl(videoId); // 第 5 步下载视频文件 const downloadRes await this.downloadVideo(downloadUrl); // 第 6 步保存到相册 await this.saveToAlbum(downloadRes); this.setData({ status: done }); } catch (err) { this.setData({ status: error }); wx.showToast({ title: 解析失败 err.message, icon: none }); } }, downloadVideo(downloadUrl) { return new Promise((resolve, reject) { wx.downloadFile({ url: downloadUrl, success(res) { if (res.statusCode 200) resolve(res); else reject(new Error(HTTP res.statusCode)); }, fail: reject }); }); }, saveToAlbum(downloadRes) { return new Promise((resolve, reject) { // tempFilePath 是下载的临时文件必须转存到相册 wx.saveVideoToPhotosAlbum({ filePath: downloadRes.tempFilePath, success: resolve, fail(err) { if (err.errMsg.includes(auth deny)) { wx.showModal({ title: 需要授权, content: 请在设置中允许保存到相册, confirmText: 去设置, success() { wx.openSetting(); } }); } reject(err); } }); }); } });这段代码有四个参数值得单独说明。第一个是wx.downloadFile的url必须是 HTTPS 且在小程序后台配置了合法域名否则请求直接失败。第二个是tempFilePath它是临时文件路径小程序退出后就会失效所以必须在拿到路径后马上调用saveVideoToPhotosAlbum。第三个是授权失败的分支处理iOS 首次调用会弹授权框拒绝后必须引导用户去wx.openSetting手动打开权限。第四个是状态码检查wx.downloadFile即使返回非 200 也不会走 fail 回调必须自己判断statusCode这是新手最容易翻车的地方。4. 从开发者工具到扫码预览把小程序交到别人手机上的三种方式4.1 扫码预览开发者工具里的「预览」按钮到底做了什么代码写好以后第一步验证不是上传代码而是“预览”。微信开发者工具顶部的“预览”按钮会把你当前正在编辑的版本编译成一个临时体验包生成一个二维码。任何人都可以用微信扫码在真机上直接运行这个小程序。这个流程对视频下载类工具特别重要。开发者工具的模拟器里wx.downloadFile和wx.saveVideoToPhotosAlbum的行为和真机不完全一致——模拟器里相册是虚拟的你根本看不出保存效果。扫码预览才能验证真实路径视频能不能下载、相册权限弹窗是否正常、iOS 和安卓的行为差异。注意扫码预览的二维码有效期只有一段时间过期后需要重新点击预览。多人联调时我习惯让团队成员轮流扫码每人真机各跑一次下载和保存因为不同机型的权限弹窗文案和存储路径差异真的很大。4.2 体验版与真机调试给同事验收的正确姿势预览二维码适合你自己和个别同事快速验证但如果是正式给团队或客户演示用「体验版」更合适。体验版的流程是在开发者工具里点击“上传”把代码传到微信公众平台的“版本管理”后台然后在后台把该版本设为“体验版”生成体验版二维码。体验版的特点是稳定它对应一个明确的代码版本不会因为你本地改代码而变化适合让产品经理、测试同事在不受干扰的环境下验收。这里有一个容易忽略的细节体验版必须把用户添加为“体验成员”否则扫码后只能看到空白加载页。在公众平台“成员管理”里绑定体验成员微信号再让对方扫码这是常规操作。真机调试模式则适合排查问题。开发者工具「真机调试」会拉起一个带调试面板的真机运行环境你可以直接在手机上看console输出、看网络请求的返回内容。当你发现“模拟器里一切正常真机上就是解析失败”时优先开真机调试看wx.request的返回值大概率是合法域名没配或者接口对 UA 有限制。4.3 上线前的配置合法域名、类目与隐私协议预览、体验都没问题时最后一步是提审上线。这一步有四个配置项漏掉任何一个都会被卡。第一个是request合法域名。开发工具里“详情-本地设置-不校验合法域名”可以关掉校验方便本地调试但真机和正式版都强制校验。你需要在公众平台“开发管理-服务器域名”里把解析接口和下载接口的域名都加进白名单。第二个是downloadFile合法域名。很多人只配了request域名忘了下载域名是独立配置项。wx.downloadFile的域名必须加到“downloadFile 合法域名”里否则下载必然失败。第三个是隐私协议。微信要求小程序在收集任何用户信息前声明隐私协议。你这个工具会读取用户粘贴的链接内容需要在“用户隐私保护指引”里声明“收集用户剪切板中的链接信息用于解析视频”并配置隐私弹窗。第四个是类目选择。“工具-效率”类目对视频下载类工具比较友好但审核时可能会要求你补充“仅限下载自有版权视频”的说明。这个我在后面合规章节会展开。5. 短视频去水印小程序的 6 个高频踩坑现象、原因与解决5.1 视频下载成功但相册里保存的是黑屏文件这是最典型的翻车现场。wx.downloadFile返回了 200tempFilePath也拿到了保存到相册后播放却是黑屏或者能播放但只有声音没有画面。原因通常是解析到的播放地址指向的是视频流而非完整文件。有些平台的无水印接口返回的是.m3u8或分片流的首个分片直接下载保存下来自然不是能播放的 MP4。另一个常见原因是地址里有防盗链签名签名只在特定 IP 和 UA 下有效小程序下载时 UA 变了导致服务端返回异常内容。解决办法下载成功后不要急着保存先用wx.getFileInfo或wx.getVideoInfo检查文件是否为可识别的视频格式。如果文件大小只有几 KB大概率是拿到了错误内容。此时换一种解析方案回去从页面 JSON 里找play_addr字段这个字段往往直接指向mp4文件。5.2 保存到相册一直弹“没有授权”设置里也找不到开关真机上第一次运行没问题但用户拒绝授权后再点保存授权弹窗不再出现直接报auth deny去设置里又找不到这个应用的相册权限开关。原因有两层。第一层是 iOS 对已拒绝过的权限不再提示必须去系统设置手动开。第二层是wx.saveVideoToPhotosAlbum走的是“照片”权限但 iOS 的权限文案显示为“相册”安卓部分厂商 ROM 会把小程序权限聚合在“微信”应用下用户找不到入口很正常。解决分两步。代码层面在fail回调里统一弹窗并引导wx.openSetting。产品层面在按钮旁边放一行灰色小字“保存失败时请到右上角设置中允许相册权限”。这句话能省掉大量用户咨询。5.3 用户把整个分享文案粘贴进来解析失败用户不会只复制链接他们从短视频 App 点“复制分享文案”拿到的是“标题 链接 口令”的混合文本。如果你的正则只匹配https开头的部分口令里的特殊字符会干扰匹配。我踩过的具体坑是分享文案里链接前后有中文引号正则[^\s]会把中文引号也吞进去导致请求 URL 里带了一个非法字符短链请求直接 404。解决方法是提取链接后做一次净化把常见的全角符号替换掉再用encodeURI处理。更稳妥的做法是直接匹配v.douyin.com这类已知短链域名前缀匹配到后从域名开始截断到第一个空白字符为止。5.4 安卓能正常保存iOS 上却一直转圈同一个接口安卓手机测得好好的iOS 上进度条一直转。打开真机调试看控制台发现wx.downloadFile的fail回调里报的是一段域名相关错误。这是 iOS 对 HTTP 接口的 ATS 限制更严格导致的。iOS 系统强制要求所有网络请求走 HTTPS且证书链完整可信安卓对自签名证书的容忍度相对高。如果你的解析接口是 HTTP 甚至用了廉价证书安卓能过iOS 必挂。解决思路是让后端或第三方平台给 HTTPS 接口并确认证书是正规 CA 签发的。同时注意某些平台的播放地址会做“临时签名”签名里绑定了来源 Referer。iOS 的 WebView 默认不发送 Referer导致接口拒绝。处理办法是在wx.request里显式带header: { Referer: https://xxx.com/ }这个字段在开发者工具里不管用必须真机验证。5.5 体验版正常正式版切换后请求全部报错这是最容易让人怀疑人生的坑。体验版跑得飞起一点“提交审核”再切到正式版所有请求全部 404 或 502。代码没变域名没变仿佛微信在针对你。原因大概率是你把“体验版”和“正式版”的接口环境混用了。公众平台后台有“开发环境”和“生产环境”两套配置体验版可以绑定体验域名正式版必须单独配置服务器域名。很多教程只教你配体验域名正式版域名留空上线后自然全挂。另一个隐蔽原因是体验版对应的是“开发版本”你可以在后台手动指定一个开发版本作为体验版而正式版永远指向“线上版本”。如果线上版本还是几周前的旧代码那请求行为和新代码不一样也很正常。排查时先确认线上版本号和你本地代码一致再看域名配置。5.6 提审时被驳回「功能与类目不符」或「涉及视频下载」审核驳回理由写得模糊常见的包括“小程序功能涉及视频下载与该类目不符”“请提供相关授权文件”。这让很多人直接放弃了这类项目。先说判断标准。微信对于“视频下载”本身不是一刀切禁止的如果你的产品是“用户粘贴链接后下载自有视频”并且界面里写了“仅支持下载有版权授权的内容”审核通过的案例不少。但凡是拿站方资源做聚合、做“全网视频解析”的基本都被拒。实际可行的路径有两条。一是把类目从“工具-效率”改成“教育-在线教育”等更垂直的类目上传一份《版权声明》或《软件著作权登记证书》作为补充材料。二是把产品定位从“去水印工具”改成“素材管理助手”弱化解析行为强调“保存到相册后统一管理”。后者的通过率高一些但前提是你的代码里不要出现“全网”“任意视频”这类字眼。6. 进阶批量解析与合规边界把去水印工具做成能长期维护的小产品6.1 三个高频进阶需求的取舍工具跑通后用户最先提出的需求是批量解析。我一般不建议在小程序里做“一次解析十个链接”原因有两个一是wx.downloadFile并发下载过多会被微信限流表现为部分下载超时二是短视频平台对短链会有频率限制同一 IP 短时间解析太多会触发风控。稳妥的做法是做一个“排队队列”用户逐条粘贴前一个下载完成后再解析下一个最多连续处理五条完成后提示休息一会儿。第二个常见需求是“相册里区分不同来源的视频”。这需要你在下载后用wx.saveFile把文件从小程序临时目录转存到本地缓存目录再按平台名建子目录。注意wx.saveFile有 10MB 总大小限制适合放短视频不适合放长视频。第三个需求是已有链接的识别。用户复制的是旧版分享口令里面可能没有完整 URL。这时候需要请求平台的“口令转换接口”把口令 ID 转成视频 ID。这个接口的参数结构经常变我的习惯是每次平台发版后花半小时验证一次把失败信息打在真机调试面板里不要等用户反馈。6.2 一把尺子去水印功能的边界怎么划最后说一个我自己的经验教训。做这类工具最容易被忽略的不是技术风险而是版权风险。我的落地方案是三条硬规则第一界面显眼位置写明“仅支持解析用户有权使用的视频”并做成用户必须勾选的协议第二不提供“批量抓取他人主页视频”的功能第三代码里不写任何绕过视频站安全策略的逻辑只处理公开分享页里已经存在的数据。这三条规则不是形式主义。它们决定了你的工具是“素材管理助手”还是“侵权工具”在应用审核和版权争议里是两种完全不同的命运。我做完第一个版本时觉得“能跑通解析和下载”就是终点后来被用户需求推着加了批量、加了历史记录、加了不同平台适配才意识到这个标题真正有价值的地方在于你可以用最小的代码量在微信生态里把一个看似边缘的诉求做成每天有人用的工具。但越是这种“边缘”越要自己拿捏好尺度。保持解析逻辑简单、界面干净、授权明确这个方向就能走得长久。希望帮到你。本文还有配套的精品资源点击获取
返回列表