今天做的不是给视频画面“擦掉一个水印按钮”,而是把豆包生成过程中已经出现、但不容易直接拿到的图片和视频资源,整理成一个页面内的资源助手:发现资源、看清楚、选出来、再下载。更重要的是,我先把原程序到底做了什么查明白,再开始重新封装,避免把“看起来像去水印”和“实际拿到了无印直链”混成一件事。
发现资源
从豆包页面响应中识别图片与视频,不再只盯着页面上的渲染结果。
页面内预览
缩略图、小窗、上一项、下一项,以及播放、静音和进度控制。
单个与批量下载
可先筛选再保存,最多提交 30 个已勾选资源,并显示下载状态。
First Principle
先弄清楚:这不是像素级擦除水印
功能名称可以叫“无印资源”,但实现机制必须讲准确:它是在响应链路里找到更适合下载的资源地址,而不是把已经下载到本地的画面逐帧修图。
我在原程序里确认了什么
最开始我去找的是浏览器程序目录里的源码,但目录中没有原始的 .cs、.js 或工程文件,真正的实现载体是编译后的 DolaMultiBrowser.dll。通过 .NET 元数据、方法名和字符串引用的静态分析,确认到了豆包备用接口提取、解析、视频源下载、预览转换和资源下载这些方法。
所以这次的核心结论是:原程序不是把视频画面上的水印擦掉,而是拦截豆包响应,提取 fallback_api,再经过解析得到 main_url / videoUrl,最后把它作为“无印资源”展示和下载。原始 C# 源码没有找到,具体的像素级去水印算法也没有被确认。
已经确认的调用链
im/chain/single图片 / 视频
fallback_apimain_url预览 / 下载
这一步的意义是把问题从“猜它怎么去水印”变成“确认它如何找到可用资源”。只有先分清这两件事,后面的插件封装才不会写成一个看似能点、实际上靠猜的壳。
今天最重要的判断:把一个功能做得可靠,第一步不是立刻改 UI,而是先确认它真实依赖什么、已经验证到哪一层、还有哪些地方不能宣称已经完成。
Rebuild the Chain
怎么做:把原程序的资源链路重新封装成 MV3 扩展
我没有把 DLL 硬拆成一个独立工具,而是按浏览器扩展的边界,重新写了页面侦测、界面桥接、下载和设置这几层。
四个文件,各自只负责一件事
page-hook.js:运行在页面 MAIN world,观察豆包页面的响应,在im/chain/single这类响应中递归寻找图片的image_ori_raw.url,同时识别视频的fallback_api。content-bridge.js:运行在扩展侧,负责创建“无印资源”面板、资源卡片、缩略图、筛选、选中状态、小窗预览,以及播放和导航交互。service-worker.js:调用浏览器下载 API,统一文件名和下载目录,把单个下载与批量下载从页面 UI 中分离出来。manifest.json:声明 Chrome / Edge Manifest V3、豆包页面匹配范围、下载与设置权限,以及可替换的解析接口配置。
图片和视频为什么是两条不同的路径
图片可以直接从豆包响应里的 image_ori_raw.url 取到,所以 0.2.0 就能完成图片预览和下载;视频则需要把 fallback_api 交给原 DLL 使用的解析服务,得到可下载的视频地址。这个解析服务是第三方依赖,不是我今天新建的服务,因此它可能因为接口变化或服务不可用而失败,设置页也保留了替换地址的入口。
这样拆分之后,插件能把“发现资源”和“保存资源”放在浏览器里完成,同时把外部解析依赖单独标记出来。以后哪一层变化,才知道应该改页面侦测、解析配置,还是下载逻辑。
From Working to Usable
功能是怎么一步步长出来的
今天不是一次性写完全部功能,而是沿着真实使用中暴露的问题,把“能发现”继续推进到“看得懂、选得准、下得稳”。
先做成 Chrome / Edge 插件版本,捕获页面响应,识别视频资源,支持单独下载。这个版本证明了 DLL 里的链路可以在页面侧重新组织,但还没有图片和完整的资源管理界面。
增加图片提取,按 image_ori_raw.url 识别图片,支持预览和下载。到这里,面板从“视频下载按钮”变成了图片和视频共用的资源入口。
增加图片 / 视频筛选、缩略卡片、可调大小的小窗、上一项 / 下一项、单个下载、勾选多项下载、全选、取消全选和状态提示。离线样例中验证了 3 个视频和 1 个图片的提取,以及 PNG / MP4 下载路由。
列表滚动后,“已选 4 项”容易让人误以为当前可见区域也有 4 项,于是补上“当前可见”数量;同时补了播放 / 暂停、静音、进度条和播放时间,让视频预览不再只像一张静态截图。
移除视频强制填满小窗的规则,改为读取真实媒体尺寸,再根据屏幕可用空间计算窗口大小;最终版本 0.3.3 同时读取视频的 videoWidth / videoHeight 和图片的 naturalWidth / naturalHeight,继续保留播放控制。
Bug Fixing
今天最难的 bug:预览比例为什么看起来不对
这次没有继续凭感觉改 CSS,而是把截图、媒体真实尺寸、预览容器和浏览器行为放在一起对照,先确认根因,再只改一条链路。
根因不是视频源被裁切,而是容器比例不匹配
旧的小窗大约固定为 760 × 600,同时视频元素又被要求把宽和高都填满预览区。对于横屏、竖屏或其他比例的视频,这会造成黑边、视觉比例不协调,甚至让人误以为素材本身被裁掉了。
第一轮修复把图片和视频改为自动宽高、最大宽高限制和等比显示;第二轮进一步加深遮罩,避免豆包页面底部的按钮视觉穿透;最后在 0.3.3 中加入窗口自适应:先读取媒体真实宽高,再在屏幕允许范围内计算 stage 和小窗的宽高。
最后采用的计算思路
aspect = mediaWidth / mediaHeight
stageWidth = min(screenWidth, maxWindowWidth)
stageHeight = stageWidth / aspect
if stageHeight > maxStageHeight:
stageHeight = maxStageHeight
stageWidth = stageHeight * aspect
window = stage + header + footer这段逻辑的价值不在于代码多,而在于它把“视觉上像比例不对”的问题,变成了可以测量、计算和复查的规则。最终保留了上一项、下一项、下载当前、播放、静音、进度条和时间显示。
Why It Matters
这个功能有什么用:让素材真正进入我的创作流程
它解决的不是“少点一次鼠标”这么简单,而是把生成页面里的临时资源,变成可以筛选、复看和进入后续制作的素材。
对 AI 短视频和短剧制作来说
- 先看再下:生成了多张图或多条视频时,先在面板里看缩略图和预览,减少把不合适的素材全部下载下来再筛选。
- 批量收集:需要把一轮生成结果带入剪辑、分镜或素材整理时,可以勾选后一次提交下载,减少手动复制临时链接。
- 比例可靠:横屏和竖屏资源在预览中按真实尺寸显示,减少因为小窗拉伸造成的错误判断。
- 链路可维护:页面侦测、外部解析和浏览器下载分开,豆包接口变化时,可以定位到具体一层,而不是重新猜整个功能。
对我自己的工作方式来说
以前拿到生成素材,往往是在页面里找按钮、打开开发者工具、复制临时地址,或者依赖一个完整的浏览器程序。现在的思路是:把“发现资源”做成页面上的固定入口,把“预览”和“下载”做成连续动作,把资源直接放进后续视频生产的素材流里。
当然,这个助手只用于我有权使用的内容。它不是一个绕过权限或处理任意视频的工具;它依赖豆包前端响应结构和第三方解析服务,也不能保证平台接口变化后永远有效。
真正有用的功能,不是多一个按钮,而是把下一步工作变短:从“我知道资源在那里”到“我能确认它、选中它,并把它放进项目里”。
Evidence & Boundaries
今天验证到了什么,哪些还不能提前宣布完成
把验证结果和未验证项分开,是这次工作里和代码同样重要的一部分。
已经完成的本地检查
- 完成 JavaScript 语法检查。
- 完成图片和视频提取样例检查。
- 完成单个与批量下载路由检查。
- 完成媒体真实宽高和预览自适应规则检查。
目前仍然存在的边界
- 原始 C# 源码不在发现的浏览器目录里,当前扩展是按已确认行为重新封装,不是从源码直接编译出来的版本。
- 视频依赖原 DLL 使用的第三方解析服务;解析服务不可用、豆包接口改变或响应尚未完成时,面板可能不会出现资源。
- 今天的本地检查不等于已经在当前登录的豆包页面完成长期实时回归,下一步仍需重新加载扩展并在实际页面里验证一轮。
- 批量下载最多提交 30 个资源,浏览器可能根据下载安全策略弹出确认。
Next Iteration
下一步:从“能用”继续走向“稳定可复用”
今天先把关键链路和主要交互跑通,下一轮会把实时验证、失败提示和长期维护补齐。
重新加载 0.3.3,刷新豆包页面,确认图片、视频、预览和下载在实际登录环境中都能按预期出现。
区分“没有发现响应”“解析服务失败”“资源已过期”和“浏览器拦截下载”,让使用者知道该重试哪一步。
后续可以考虑资源去重、按项目命名、保存一次生成批次,以及把下载后的素材和分镜、剪辑项目建立关联。
今日复盘:先做逆向确认,再做功能拆分;先修真实根因,再谈界面完成。今天完成的是一版本地可用、边界透明的 0.3.3 扩展草稿。
返回文章归档 ↗