黑盒 GIF(#vbb)优化历程与后续空间

面向后期查阅与继续优化。实现主路径:tools/extra-panels/v2g-suite-src/10-shared-encode.js(encodeBlackboxClip / encodeBlackboxClipCore),面板与批处理:40-vbb.js + tools/panels/vbb.html。改分片后必须:

node tools/scripts/build-v2g-suite.cjs
node tools/bump-version.cjs

本地回归(可选):

node tools/vbb-plan.test.js
node tools/vbb-blackbox-fps.test.js
node tools/scripts/vbb-feature-eval.cjs <video1> <video2> [images...]
node tools/scripts/vbb-bench-local.cjs <video...>
node tools/scripts/vbb-merge-edit-bench.cjs <video1> <video2>   # 编辑裁切 → 拼接 → 黑盒
# 结果默认到临时目录;也可用 VBB_BENCH_OUT=tools/.tmp-vbb-bench

硬约束(不可破 · 2026-10-02)

改策略前先改这里;单测:node tools/vbb-blackbox-fps.test.js(已进 CI)。

  1. 时间轴优先于标称高帧 / 宽度:成片 fps 必须落在片源「整除档」
    • ≈24fps 电影 → 24 / 15 / 12(禁止 20;15 必试)
    • ≈25fps 屏录 → 25 / 15 / 12.5(禁止 20;15 必试)
    • ≈30fps → 30 / 15 / 12
    • 其它 → 20 / 15 / 12
  2. ≤24s 进预算后:禁止「可读宽优先」再把流畅档降到更低档换宽度
  3. 拼接产品形态:始终 多段 → 一条中间 MP4 → 一条 GIF(不分段各出 GIF)
  4. 中间片:保留片源帧率;抽到黑盒档只在转 GIF 时做一次
  5. 体积硬闸:默认 ≤10MB,超限不交付
  6. 宽度策略:420 清晰工作点;400 中间档;380 硬底。短片超限:同帧先 420 画质 92→≥80,面积外推跳过注定超限的更窄宽,然后才降整除帧。长片:420 允许 q<80 保帧,不先缩宽。
  7. 画质底线:仅 ≤10s 短片在未到最低整除档前 gifski ≥80(q8/gq83)。更长片优先保帧+420。细档 q4/q6 仅体积 ≤约 1.18×预算时才试。非黑盒 GIF 工具不套此限制。
  8. 调色板 / 摄影色:勿过早 gifsicle --colors 128;禁止「电影 lossy 腾预算再加宽」(见 e95ca7e)
  9. 抬质吃满:略超限可轻压进预算;整档装不下试中间 gq 半档;阶梯含 q18(见 9a98dc6)
  10. 满画质禁 lossy 留底:gq≈92(及已进预算成片)只许 -O3;禁止 compressExistingGifToBlackbox 硬压 / movie lossy / 过早 --colors 留底。干净次档 > 脏满档贴 10MB
  11. 单任务并行:UI 一次只跑一个用户任务;桌面原生 gifski 下同一任务内试档最多 2 路;手机 / wasm 回退保持 1 路

主目标排序:时间轴干净 > 标称高帧 > 420 清晰(画质) > 加宽 > 少试编。


测评结论(2026-10-02)

一句话:核心流程可用、体积达标;卡顿多来自帧率策略(已修);慢是试档成本,手机请用「拉满」。

维度 结论
功能面 vbb-feature-eval 13/13 PASS(工作流、编辑遮罩、打点、切片分析、多选、多图等)
体积硬闸 一键黑盒样本 ≤10MB(IMG_0087 / IMG_0086 / 502;548+549 拼接后 ≤10MB)
流畅 整除档(25 源 25/12.5);拼接中间片保留片源帧率;≤24s 禁换宽降档
性能体感 难压 ~22s 拼片桌面拉满约数分钟——慢来自多次真实试编码
未长测项 合并 GIF、zip、压缩时长、自动去色边视觉、真机分块/防息屏(可另开)

本轮修掉并已上线的问题(详见「变更记录」):

  1. 短片加宽 95% 早退 / 0.99 软帽拒收 → 吃不满预算
  2. 短片硬压掉帧发卡 → 保高档帧率
  3. 拼接 25→20 先抽卡 → 中间片保留 25/30…
  4. 25 源 GIF 用 20 不规则抽帧 → 改为 25/12.5
  5. 手机「自动」偏均衡 → 更倾向拉满
  6. 难压片「更宽更糊」→ 未满档不加宽(gq 门闩)
  7. 601 泥色 → 勿早减色、取消电影lossy腾预算(e95ca7e)
  8. 6.5MB 停画质65 → 抬质可轻压/半档/q18(9a98dc6)
  9. 画质92 密麻颗粒 → 满档抬质禁 movie hard lossy,仅 O3(2026-10-03)
  10. 画质92 仍脏 → 近超限/硬闸/换宽误走硬压;满档一律 O3,减色延到 r8+(2026-10-03 午)

产品目标(验收口径)

在 ≤ 可配置上限(默认 10MB) 下,整段黑盒 GIF 尽量:

  1. 流畅:片源整除档 + 均匀 delay(避免可变 delay / 不规则抽帧顿挫)
  2. 清晰:默认守 420 清晰工作点;有余量先抬画质到满档,再加宽/提帧;不得破坏硬约束 1–2
  3. 不超限:硬闸 enforceBlackboxMaxBytes,超限不交付
  4. 可预期:真实试编码决策(不用「拍脑袋估算」定档)

建议「到极致」验收:

场景 期望
短片 ≤10s(25 源) 优先 25fps 进预算;满画质优先于盲目加宽
中片 / 拼片 ~16–24s(25 源) 12.5fps 整除档;优先 420 + 更高画质,勿「更宽但更糊」
难压长片 ≤上限内优先保 420 清晰与画质,帧率走低档整除;380 仅硬底

当前策略摘要(代码真相)

  • 帧率阶梯(按片源):≈24 电影 → 24,15,12;≈25 屏录 → 25,15,12.5;≈30 → 30,15,12;其它 → 20,15,12
    一律从最高整除档起试(不再按时长先锁 12)
  • 宽度三档:420 → 400 → 380
  • 起点:宽 420、gifski 近无损(质量档 1 / gq92)
  • 进预算顺序(超限让渡):满画质@420 → 同宽降到 ≥80(q1/4/6/8 → 92/88/86/83)→ 400 同样 → 380 同样 → 更低整除档重复 → 最低帧+380 才允许 q15…q30 / lossy
  • 非黑盒(#v2g 转为 GIF、切片「高清 GIF」):按用户选的帧率/宽度/质量,不套 10MB 让渡、不套整除档、不套手机帧率帽
  • 有余量顺序:先抬画质到满档(同宽)→ 满档后才加宽 → 提帧(只提到整除高档)→ 再加宽 → O3 → 硬闸
    (画质未满时跳过加宽,禁止「442 宽 · q65」这类宽而不清)
  • 抬质细则:
    1. 抬到更高 ladder 档时,原始略超 10MB → blackboxAcceptBoostIfFits 试压进预算(不再硬拒)
    2. 满画质(gq≈92)只许 -O3(抬质 / 近超限保 420 / 硬闸第一步 / 换宽轻压 / compressAt 均同);非满档最多 O3 + 一轮很轻 soft(lossy≈28);禁止硬压 movie lossy 留底
    3. 整档仍装不下 → 试 中间 gq 半档(如 65→~70)
    4. 阶梯含 q18(V2G_BLACKBOX_QUALITY_LADDER = [1,8,15,18,22,30])
    5. 硬压 --colors 延到 r8/r9(192/128);满档 qualityBest 时 compressExistingGifToBlackbox 强制 mode=o3
  • 调色板禁令(e95ca7e):取消 finish/O3 后「电影 lossy 腾预算再加宽」;lossy 会合并调色板,加宽失败时留下泥色成片(601)
  • 拼接:多段 → 一条中间 MP4 → 一条 GIF;中间片保留片源帧率
  • 规则单测:tools/lib/vbb-blackbox-fps.js · tools/vbb-blackbox-fps.test.js

关键常量(名称以源码为准):V2G_BLACKBOX_MAX_BYTES、V2G_BLACKBOX_HIGH_PRIMARY_SPAN_SEC、V2G_BLACKBOX_MID_SPAN_SEC、V2G_BLACKBOX_BASE_W、V2G_BLACKBOX_COMFORT_W、V2G_BLACKBOX_MIN_ACCEPT_W、V2G_ENCODE_HARD_W、V2G_BLACKBOX_QUALITY_LADDER。


优化历程(按主题)

A. 体积上限与硬闸

  • 默认黑盒上限从历史档位演进到 可配置持久化、默认 10MB(全站 devtools:blackbox-size)
  • 成片路径统一 O3 优化 →(可选)再加宽 → enforceBlackboxMaxBytes
  • 超限优先「按比例无损重编缩宽/降帧」,尽量晚用 gifsicle --lossy(颗粒感)

B. 帧率与流畅度

  • 去掉 10fps 底线;主决策 20 → 15 → 12
  • 短片曾「先 15 再余量冲 20」,后改为 ≤16s 主试 20(10MB 下更顺)
  • GIF 厘秒时基:改为 固定均匀 delay(20→50ms / 15→70ms / 12→80ms),避免累计取整「一顿一顿」
  • ≥18fps 禁止静止帧合并(可变 delay 在动作段易顿挫);短片 ≤16s 即使 15/12 也不合并;更长片 15/12 仍可合并省体积
  • 「压缩时长」= setpts 倍速缩短有效时长;不应再被误标成「更卡」的原因
  • 拼接卡顿根因(已修):旧逻辑把 25fps 源压成黑盒主档 20 → 中间片与 GIF 都抖;现保留片源帧率

C. 宽度与吃满预算

  • 加宽二分目标贴 ~0.99× 预算;旧「超一点回退过大 + 探次少」会导致常用不满
  • O3 后再加宽,把优化腾出的字节换成清晰度
  • 短片欠填:实测 4.8s@2532 曾只到 ~3.0MB / 630px(约 30%),因 finish/O3 加宽卡在 2× / 1.5×
    → 已改为 ≤24s 探满源宽/1280,提帧后再补一轮加宽(需同片复测确认)

D. 手机 / 性能 / 内存

  • 性能档(自动/拉满/均衡/省电)影响 gifski 帧上限、加宽探次、是否质量上探、批并发
  • 手机分块编码防 OOM;桌面默认少分块;拉满=少分块、加宽探更多
  • 手机始终一次只转一路(batchConcurrency=1),多选也逐个;探宽 ≤2;满档远超预算时跳过中间画质档
  • 手机抬质:最多一档;≥88% 预算跳过抬质;跳过半档 / 第二轮抬质 / 加宽 / O3 后再抬 / gq100 上探(防 wasm OOM)
  • 手机「自动」:未知机型默认拉满;核数 ≥6 抬满(旧 ≥8 / 默认均衡体感偏慢)
  • 电脑桌面/拉满多选最多 2 路;手机 wasm 不能真多线程——单路极致=少试档,不是多核狂编
  • 桌面加速(保流畅+清晰):选定整除帧率与 420 后,抬质能进预算就连爬;上一档 O3 进不去即停(不反复半档/第二轮/O3 后再抬);同档走 trialCache。满档才加宽。
  • 校验:601 桌面 546s→206s,仍 20fps·420·画质74·9.75MB;0087 388s→166s,仍 30fps·420·画质83·9.76MB。帧率/420 未降,去掉的是进不去的白跑。
  • 校验(VBB_BENCH_MOBILE=1,601.mp4 15.8s 1920×1440,强制 wasm):约 146s 出片 · 420·画质70(档18) · 8.24MB · ≤10;日志含 手机加速:满档…从 q18 起试 / 跳过加宽/第二轮抬质
  • 次要选项折叠;布局改为横排紧凑(避免强制竖排全宽)

E. 交互与流程

  • 整段 / 长视频切片 / 手动打点;多选批次;编辑页复用 trim/crop
  • 「拼接后转黑盒」:多段先拼再整段黑盒(后修纯视频高帧中间片)
  • 防息屏 / 完成提示音震动 / 自动打包下载 / 分享到相册
  • 多图 → GIF 模式
  • 文案大幅精简,减少干扰

F. 关键提交路标(便于 git show)

提交 要点
05b282f 上限可配置
03b223a / e8ba68a 拼接后转黑盒
65d1a1b / 5c85209 性能档、O3 后加宽
a8b7c51 默认 10MB 等一揽子
512d355 / c49846d / c8ac5b7 20fps 主策略演进
4a7316c / 39f59c0 均匀 delay、硬闸、顿挫修复
3c31dbe 拼接纯视频 60fps 中间片(修拼接顿挫;后续改为保留片源帧率)
51a9b22 短片加宽吃满预算
920e9d9 完整测评:加宽早退/软帽;vbb-feature-eval
16e9c1b 短片保 20fps(553)
d5e4098 拼接中间片保留片源帧率(548/549→553)
29f16f4 548+549 实测脚本;手机自动更倾向拉满
e9930bc 未满画质不加宽(gq 门闩守 420 清晰)
e95ca7e 推迟减色;取消电影lossy腾预算(修 601 泥色)
9a98dc6 抬质轻压/半档/q18;v2026.10.02-234525

(完整列表以 git log -- tools/extra-panels/v2g-suite-src/ 为准。)


基准快照(修复短片加宽前)

来源:tools/.tmp-vbb-bench/after__*(当时 fpsList 仍可能含 10,策略已演进,数字只作对照)。

样本 成片 体积 占 10MB 备注
4.8s 2532×1170 20fps · 630 3.04 MB ~30% 欠填;加宽上限问题
8.1s 1170×900 20fps · 644 9.79 MB ~98% 短片样板
14.1s 2532×1170 20fps · 508 9.84 MB ~98% 贴满
17.4s 1170×880 15fps · 388 9.80 MB ~98% 贴满但偏窄
20s webm 742×644 12fps · 504 · q65 9.84 MB ~98% 靠深降质进预算再加宽

配套分析 Canvas(本机):canvases/vbb-10mb-ceiling.canvas.tsx(Cursor 会话产物,不一定进仓库)。


仍有的优化空间(按优先级)

P0 — 已验证(2026-10-02)

  1. 短片吃满:4.8s@2532 → 20fps·1116 · 9.59MB(约 96%)✓
  2. 偏窄换宽:17.4s 曾卡 15fps·388;现可降到 12fps 试 ≥420(等比留 0.93 余量,略超可轻压)
  3. 难压片硬压:gifski 输出上 gifsicle 常 0%(20s webm 仍落到 q22 再加宽)——保留路径、不指望它救命

P1 — 观感 / 可读(已落地)

  1. 难压片:高质量近超限先轻压/硬压,再深降质
  2. 贴满但宽 <420:降一档帧率换可读宽;加宽二分按剩余预算收紧上界(避免短片白跑 ~2× 宽)

P2 — 策略调参(需更多样本)

  1. 是否引入 18fps 中间档
  2. 长片 <18fps 静止帧合并 与顿挫的产品取舍(短片已关)
  3. V2G_BLACKBOX_WIDTH_CAP=900 未使用——删或接入
  4. 难压长拼片试档次数多 → 体感慢:已做「远超预算跳中间宽 / 跳浅降质」;仍可考虑试档结果缓存、低成本探测编码

P3 — 工程

  1. 决策日志统一 [vbb-phase]
  2. 联合搜索 (fps×宽×质) 仅 debug
  3. 未长测项补齐:合并 GIF / zip / 压缩时长 / 去色边视觉 / 真机分块

改策略时的注意点

  • 先改 v2g-suite-src/,再 build;不要只热修 v2g-suite.js
  • 动帧率 / delay / 静止合并后,务必用「动作段录屏」看是否顿挫,不能只看体积
  • 动加宽上限后,用「短 + 源很宽 + 画面简单」片验证吃满,用「长 + 高噪/高动作」片验证不超限、不 OOM
  • 面板文案保持短;说明写进本文或面板折叠区
  • 加宽必须沿用当前画质档(encodeKeepQ):q65 入选后再用 q92 探宽会全失败白跑
  • 画质未满档时跳过加宽(以 gifskiQuality 为准,勿只看 ladder quality):避免「442 宽 · 画质 65」宽而不清
  • 抬质改档勿沿用旧 gq:否则会编出「q1 标签 + gq65」假成功
  • 勿过早 --colors 128:摄影/渐变片会泥色;减色只作末档硬压手段
  • 勿恢复「电影lossy腾预算」:省下的字节加宽吃不到,失败却留下崩色成片
  • 抬质略超限要试压:否则易停在 6.5MB·画质65,预算闲置

明天强刷复测(必做 · 约 15–30 分钟)

目标版本:v2026.10.03-111710(满档禁硬压 + 单任务双路试档)。先确认页脚版本号,再测。

强刷步骤

  1. 打开 https://afra55.github.io/tools/(或本地 python3 -m http.server 8080 → http://localhost:8080/tools/)
  2. 硬刷新:Chrome/Edge Ctrl+Shift+R(或清站点缓存);若装了 SW,在 DevTools → Application → Service Workers 点 Unregister 后再刷新
  3. 确认顶栏/页脚 TOOLS_BUILD ≥ 2026.10.03-111710;不对就再强刷一次;本机桥请重启一次(gifski --threads)
  4. 进 #vbb 黑盒,性能档用 拉满,上限 10MB

验收清单

# 样本 / 场景 期望 失败信号
1 601(易泥色摄影/电影向) 成片有正常色彩;画质标签与观感一致;不是灰泥/无色 标签写画质92 但画面泥色 / 色数崩
2 原停在 6.5MB · 画质65 的片(如 IMG_0087 类难压短片) 有余量时应 抬质(gq/阶梯上移)或半档;体积更贴 10MB;宽优先仍守 420 仍停 ~6.5MB·画质65、预算闲置
3 难压片(曾「宽而不清」) 420 宽 + 降质 进预算;未满档不加宽 又出现 442·q65 这类「更宽更糊」
4 易压短片(满画质) 满档后才加宽;色彩正常 满档前就加宽,或加宽后泥色

可选对照命令(本机有片源时):

# 清旧结果目录后跑
Remove-Item -Recurse -Force tools/.tmp-vbb-bench -ErrorAction SilentlyContinue
$env:VBB_BENCH_OUT="tools/.tmp-vbb-bench"
$env:VBB_BENCH_TAG="retest-1003"
node tools/scripts/vbb-bench-local.cjs <601视频> <原6.5MB那条> <其它...>

看日志关键字:抬质轻压进预算 / 干净轻压保 420 / 单任务并行试档 / 余量抬画质半档 / 跳过加宽:画质档;不应再出现「电影lossy腾预算」、满档 电影lossy、或近超限后仍 硬压 留底。


变更记录 · 420 清晰优先(2026-10-02 晚)

动机:难压片曾落到 更宽 + 降质(如 442/466 宽 · 画质 65/55)——宽而不锐。根因:余量加宽门闩在 quality 字段缺失时误判「已满档」,仍按旧 gifskiQuality 加宽。

改动(10-shared-encode.js):

  1. fitFps:满画质@420 → 同宽降质阶梯 → 才试硬底 380
  2. finishBlackbox / O3:有余量先 boostQualityPass;blackboxQualityIsBest(看 gq) 未满则跳过加宽
  3. 抬质改档时不沿用旧 gifskiQuality(避免假成功)
  4. 常量:V2G_BLACKBOX_COMFORT_W(=420)与 MIN_ACCEPT_W(380)职责分开

校验(VBB_BENCH_TAG=comfort420e/d,D:\Download\):

样本 决策选定 成片(≤10MB)
IMG_0087 6.5s 1080p 30fps·420·q22(先守 420 降质) 420 宽 · 画质 65(档22) · 6.91MB · 跳过加宽 ✓
553 13.3s 20fps·420·q30 守 420 420 宽 · 画质 55(档30) · 7.42MB · 跳过加宽 ✓
屏录短 4.8s 20fps·420·q92 满画质 再加宽到 1136·画质92 · 7.04MB ✓
屏录中 14.1s 20fps·420·q92 满画质 加宽到 508·画质92 · 6.18MB ✓

相对旧路径(IMG_0087 曾 442·q65 / 553 曾 466·q55):难压片改为 先 420 降质进预算且未满档不加宽;短易压片仍可满画质后加宽。

终表 · 三连修复后策略(2026-10-02 深夜 · v2026.10.02-234525)

阶段 行为 提交
进预算 守 420 → 同宽降质(含 q18)→ 380 → 降帧 → 晚减色硬压 e9930bc + ladder
有余量 先抬质(可轻压 / 半档 gq)→ 满档才加宽 9a98dc6
O3 后 只 O3;不做电影 lossy 腾预算;加宽基于干净 O3 成片 e95ca7e
硬压 默认摄影友好,movieLike:勿早 --colors 128 e95ca7e

注意:若复测仍见泥色,先查是否旧 SW/旧 ?v=;再查成片是否误走独立旧桥或缓存的 v2g-suite.js。


相关路径速查

路径 用途
tools/extra-panels/v2g-suite-src/10-shared-encode.js 编码核 / 黑盒决策
tools/extra-panels/v2g-suite-src/40-vbb.js 黑盒面板逻辑、拼接
tools/panels/vbb.html 面板 DOM
tools/styles/panels/vbb.css 布局
tools/scripts/build-v2g-suite.cjs 分片拼接
tools/scripts/vbb-bench-local.cjs 本地一键黑盒基准
tools/scripts/vbb-feature-eval.cjs 功能面自动化测评
tools/scripts/vbb-merge-edit-bench.cjs 编辑裁切 → 拼接 → 黑盒实测
tools/vbb-plan.test.js 切片规划单测
tools/lib/vbb-blackbox-fps.js 帧率硬规则(Node 单测源)
tools/vbb-blackbox-fps.test.js 整除档 / 禁 25→20 / 拼接一条 断言
tools/lib/extra-media.js 性能档(自动/拉满/均衡/省电)
tools/extra-panels/v2g-suite-src/README.md 分片说明

完整测评快照(2026-10-02)

摘要见文首「测评结论」。本节保留明细,便于对照复测。

命令:

node tools/vbb-plan.test.js
node tools/vbb-blackbox-fps.test.js
node tools/scripts/vbb-feature-eval.cjs <video1> <video2> [images...]
node tools/scripts/vbb-bench-local.cjs <videos...>
node tools/scripts/vbb-merge-edit-bench.cjs <v1> <v2>

功能面(vbb-feature-eval)13/13 PASS

项 结果
面板启动 / TOOLS_BUILD ✓
整段 / 切片 / 手动打点切换 ✓
上限·性能·防息屏·裁边·下载等控件 ✓
单文件加载 + 编辑入口 ✓
编辑层立刻遮罩+锁滚动+可关 ✓
片尾拖拽预览更新 ✓
手动打点 1 段 ✓
长视频切片分析出方案 ✓
多选列表 / ↑↓ / 编辑 / 禁切片 ✓
多图 UI + 生成 GIF ✓
桌面编辑层 ✓

未在本轮跑通的重编码路径(需另开长测):合并 GIF、zip 打包、压缩时长加速、自动去色边视觉回归、真机分块/防息屏。(拼接后转黑盒已在 548+549 实测补齐。)

一键黑盒体积(10MB)

样本 修复前 修复后
IMG_0087 6.5s 横屏 20fps·420 · 9.64MB(卡 95% 早退) 20fps·426 · 9.91MB
IMG_0086 7.0s 竖屏难压 12.5fps·380 · 9.78MB(~397s) 未复跑;难压路径仍成立
502 28.3s 12.5fps·404 · 9.79MB 未复跑
553 13.3s(旧拼接产物) 约 14.3fps·380·q74 短片保帧后:20fps·398·q65·9.97MB
548+549 编辑后拼接 ~21.9s (旧 12.5fps·440 卡) 中间片 25fps;GIF 15fps·396·q55·9.91MB(保流畅)

测评中修掉的编码问题:

  1. finishBlackbox / 加宽入口用 95% 早退 → 短片卡住 420
  2. blackboxWidenBest 用 0.99 软帽拒收 合法 ≤10MB 结果(420→426 被丢)→ 改为硬闸接纳、0.99 只作停探目标
  3. 短片硬压把 15 抽成 ~13.5 → 显示 14.3、观感卡 → 短片保 20fps
  4. 拼接 blackboxPrimaryFps(总时长) 压片源 → 中间片抖 → 保留片源帧率

变更记录

追加规则:日期 + 现象 + 改动 + 复测;勿删旧条,只在顶部追加。

2026-10-03(残留脏像素路径清扫 + 单任务双路试档)

  • 现象:抬质闸门修完后,满档仍可能脏:fitFps 近超限「轻压保 420」、硬闸、换宽 1.06、compressAt(isLast) 仍走 compressExistingGifToBlackbox movie hard lossy;标签画质 92。
  • 改动:
    1. 上述路径满档只 -O3(qualityBest → mode=o3);抬质失败保留干净次档
    2. 硬压 --colors 延到 r8/r9;满档禁止无必要 lossy/减色
    3. 原生 gifski 显式 --threads(并行时按 inflight 均分核);quality≥90 忽略误传 --lossy-quality
    4. 桌面+本机桥:同一任务内 q1 与下一档最多 2 路并行;手机 / wasm 禁止(双份 RGBA)
    5. 不改成同时编多个用户任务;ffmpeg y4m→gifski 管道本就重叠,wasm 抽帧与编码重叠属大改未做
  • 复测:强刷 #vbb + 重启本机桥;对照旧 617/618 颗粒;控制台应见 干净轻压保 420 或 单任务并行试档,满档不应再 电影lossy

2026-10-03(满画质禁抬质 lossy 颗粒)

  • 现象:D:\Download 新成片 617/618/619 标签画质 92,但密麻颗粒点;调色板仍满 256(非 601 泥色)
  • 样本:617 9.80MB · 420×316 · 25fps · 270帧;618 9.47MB · ~14.3fps · 251帧;619 6.85MB · 20fps · 200帧(同源视频当日未同名落盘,近邻 596/597/601.mp4)
  • 根因:9a98dc6 的 blackboxAcceptBoostIfFits 对满档用硬压前 4 档 movie lossy(≈92–176)硬塞进 10MB;O3 后再叠 lossy 留底 → 抖动噪点
  • 改动:满画质抬质 仅 -O3;非满档最多 O3+一轮 soft≈28;进不去预算则放弃抬质、保留干净次档
  • 复测:强刷 #vbb 后用原片再出一版,对比旧 617/618 颗粒是否消失(可接受略低画质档或略小体积)

2026-10-02(抬质吃满预算 · 9a98dc6 / v2026.10.02-234525)

  • 现象:fitFps 在较低档(如 q22)进预算后,抬到更高档原始常 12MB+ 被硬拒;旧电影lossy 又把成片压到 ~6.5MB,抬质从不「高档+轻压」→ 余量闲置、停在画质65
  • 改动:
    1. blackboxAcceptBoostIfFits:抬质略超限时硬压前 4 档试压进预算
    2. 整档装不下 → 中间 gq 半档(如 65→70)
    3. 阶梯补 q18:[1,8,15,18,22,30]
    4. 不恢复过早减色与电影lossy腾预算
  • 复测:留给次日强刷(见上文「明天强刷复测」);重点看原 6.5MB/画质65 片是否抬质

2026-10-02(调色板修复 · e95ca7e)

  • 现象:601 等成片标签画质高但画面泥色/无色
  • 根因:过早 gifsicle --colors 128;以及 finish/O3 后「电影lossy腾预算再加宽」——lossy 合并调色板,加宽失败却留下崩色成片
  • 改动:推迟减色;取消电影lossy腾预算路径;抬质可轻压进预算;修正 gifski lossy/提亮映射
  • 复测:次日强刷测 601 色彩(见上文清单 #1)

2026-10-02(电影向产品级:锁帧+二分宽+lossy)

  • 场景:用户常处理电影片段(23.976/24/30…),要在 10MB 下尽量又顺又清
  • 改动:
    1. 24fps 源阶梯 24→12;电影/摄像判定 blackboxIsMovieLike
    2. 先探底宽深档 → 不行早弃帧;行则 宽度二分锁帧(少白跑 420/400/380)
    3. 试档缓存;电影向 gifsicle lossy 更积极;O3 后可选 lossy 腾预算再加宽
  • 原生 gifski(已上):统一桥 /ff/gifski/*(session + encode + install);缺二进制时自动下载官方 1.34.0 到桥解压目录 ffmpeg-bridge/vendor/gifski/(EnvKit sync / 探测 ?auto=1 / 编码时均会装);有 gifski 走多线程原生,否则 ffmpeg palette;黑盒无水印时优先,失败回退 wasm
  • 未上(环境限制):GitHub Pages 难开 COOP/COEP → gifski-wasm 多线程仍暂缓(原生路径已多线程)
  • 15fps:未全删。默认阶梯与 ≈30 源仍为 20→15→12 / 30→15→12;电影 24 / 屏录 25 已避开 15
  • 单测:vbb-blackbox-fps.test.js 覆盖 24/25 与源码同步

2026-10-02(锁硬约束 · 不分段)

  • 决定:拼接保持「一条中间片 → 一条 GIF」,不做分段多 GIF
  • 落地:文档「硬约束」五条;tools/lib/vbb-blackbox-fps.js + CI 单测;bench / merge-edit 对 ≈25 源断言成片 ∈ {25,12.5}
  • 主目标排序:时间轴干净 > 标称高帧 > 宽度 > 少试编

2026-10-02(549 单段卡:25 源整除档)

  • 现象:549 单独黑盒也「卡卡的」;实测旧策略成片 20fps·476·9.95MB
  • 根因:片源 25fps,抽成 20 不是整数隔帧 → 屏录/UI 运动不规则顿挫(帧率数字高仍显卡)
  • 改动:≈25fps 源阶梯改为 25 → 12.5(整帧 / 隔一帧);≈30fps 用 30→15→12;其它仍 20→15→12
  • 复测 549-div25:成片 25fps·394·q65·9.90MB(比旧 20·476 略窄,时间轴与片源一致)

2026-10-02(拼接 GIF 卡:保 15)

  • 现象:单段正常、两段拼接 GIF「卡卡的」
  • 根因:≈22s 拼片在 15fps 只试到 q15 就掉 12;随后「可读宽优先」又把已进预算的 15fps·396 换成 12fps·440
  • 改动:≤24s 中长片(含拼接)15fps 走完 q22/q30;硬压保帧;禁止 15→12 换宽
  • 复测 548549-keep15:成片 15fps(示 14.3)·396·q55·9.91MB;中间片仍 25fps;约 5 分钟

2026-10-02(试档早停)

  • 现象:难压片(如 548+549≈22s)桌面拉满约 9.5 分钟;日志里 15/12 在 420→400→380 连续远超预算仍逐档实编
  • 改动:同帧率下若某宽已 >1.55× 上限,按 w² 估算底宽;仍远超则只再试底宽一次并跳过中间宽;长片底宽高质量 >1.6× 时跳过浅降质、过深仍超则提早换更低帧率
  • 复测:同机 548549-prune vs 548549-merge2:merge+gif 567.9s → 410.5s(约 −28%);成片仍 12fps·440·9.96MB(策略未变)
  • 跳过:15@400、15·q8、12@400、12·q8(日志可见「跳过中间宽 / 跳过浅降质」)

2026-10-02(文档:测评结论入库)

  • 文首新增「测评结论」总表;策略摘要改为「拼接保留片源帧率 / 短片保帧 / 手机自动拉满」
  • 功能快照补 553、548+549 行;提交路标补 920e9d9 / 16e9c1b / d5e4098 / 29f16f4
  • 路径速查补 vbb-feature-eval / vbb-merge-edit-bench / extra-media.js

2026-10-02(548+549 实测)

  • 脚本:tools/scripts/vbb-merge-edit-bench.cjs
  • 编辑裁切后拼接:中间片 25fps(片源 25+25);成片约 21.9s → 黑盒 12.5fps·440·q55·9.96MB(难压长拼片)
  • 桌面拉满整段约 9.5 分钟(多次真实试编码);慢主要来自试档,不是没开性能
  • 手机「自动」:未知机型默认改 拉满;核数 ≥6 抬满(旧 ≥8 / 默认均衡偏慢)

2026-10-02(拼接卡顿)

  • 548+549 → 553:片源均为 25fps,旧拼接用 blackboxPrimaryFps(总时长) 压成 20fps,中间片先抖,GIF 再跟抖
  • 修复:中间片保留片源帧率(探测 24/25/30…);转 GIF 时再抽到黑盒档(只抽一次)
  • 对照:旧 553=20fps·265 帧;新策略拼条约 25fps·332 帧(同约 13.3s)

2026-10-02(短片保帧)

  • 553.mp4 13.3s:旧路径掉到显示 14.3fps·380·q74(硬压把 15 抽成 ~13.5)观感卡
  • 短片(≤16s):20fps 可走到 q22/q30 + 放宽硬压门槛;压缩时不降帧;不做静止帧合并
  • 复测:20fps·398·q65 · 9.97MB(针对已是 20fps 的中间片;根因见上「拼接卡顿」)

2026-10-02(完整测评)

  • 新增 tools/scripts/vbb-feature-eval.cjs 功能面自动化
  • 修短片加宽早退 / 软帽拒收,IMG_0087:420·9.64MB → 426·9.91MB
  • 结论:功能面 13/13;体积达标;见文首「测评结论」

2026-10-02(余量优化)

  • finishBlackbox:贴满早退仅当宽 ≥420;加宽/提帧沿用当前画质(encodeKeepQ)
  • 可读宽优先:宽 <420 且近满 → 降帧试 ≥420(门槛 +24);目标宽按 0.93 预算;略超限可轻压
  • 加宽二分:成功后按剩余预算收紧 hiW;几乎贴满则停止(避免中点跳到源宽 ~2× 白跑)
  • fitFps:近超限轻压后再硬压;q15 仍超且 ≤1.2× 时硬压保画质(gifski 上常 0%,保留兜底)
  • 实测:17.4s 录屏 15·388 → 12·430(9.86MB,画质 92);难压 20s webm 仍 q22 加宽(硬压无效)
  • 基准:tools/.tmp-vbb-bench/opt20261002*

2026-10-02(续)

  • 拼接语义校验:确认流程是「多段 → 一条 MP4 → 整段黑盒」;拼接时带上各段编辑(trim/crop);文档策略摘要与实现对齐

2026-10-02

  • 编辑抬手抖动:拖拽中 seek 节流;播放头跟手柄;抬手按帧格吸附且不再读抬起坐标
  • 手机编辑全屏:编辑层 100dvh、禁止横向溢出,微调按钮两列铺满
  • 保存后预览:主预览跳到片头并循环裁切区间;裁画面用 clip-path 反映
  • 拼接第一段卡顿:中间片帧率改为黑盒主档(20/15/12),避免源→60→20 双重抽帧

2026-10-01

  • 文档初稿入库:tools/docs/vbb-blackbox-optimization.md
  • 短片加宽吃满(51a9b22):≤24s 加宽上限到源宽/1280;O3 后短片同步
  • 拼接顿挫(3c31dbe):拼接后转黑盒改为纯视频 + 60fps 中间片
  • 难压先轻压:fitFps 在深降质前,对近超限高质量候选先 compressAt 轻压
  • 可读宽优先:成片贴满但宽 <420 时,试降一档帧率换 ≥420 宽,再视情况加宽

文档起始整理:2026-10-01。后续优化请在本「变更记录」追加(日期 + 现象 + 改动 + 复测)。