Skip to content

v0.4.2

Choose a tag to compare

@siwilizhao siwilizhao released this 27 Sep 09:43
· 270 commits to main since this release

Added

  • 视频列表批量下载(两种模式):
    • 模式 A downloadAllPageVideos(喂食流):列表页卡片内直接播放的
      (feed/瀑布流),当前页嗅探 + DOM 扫描到的视频全部入队——去重、跳过
      blob:/DASH/纯音频,文件按 01- 02- 序号落 <保存位置>/<文件夹>/
      (默认以页面 host 命名)。
    • 模式 B downloadVideoList(逐页解析):每项有独立详情页的列表——
      由 Agent 收集详情页地址清单(用户确认后)交给原生引擎:隐藏 WebView
      逐页加载
      (串行 + 2-5s 抖动,复用应用桌面 Safari UA 与嗅探脚本),
      等播放器起流拿真实媒体地址,≤2 并发下载。解析梯度:等嗅探 → 周期
      DOM 扫描 → 点播放(静音)。
    • Cloudflare 三层防线:隐藏 WebView 与浏览标签页共享 Cookie 池,
      非交互挑战自动放行;交互式 Turnstile 先自主通过——解析器 webview
      弹成小窗后用 SyntheticInput(真实 NSEvent,isTrusted=true)点复选框
      (最多 3 次);仍不成才降级为等人工(人工是最后兜底,不是第一响应),
      引擎继续轮询挑战解除后不重载页面直接续跑。
    • 失败自动重试(同批同文件夹):失败项冷却后自动重跑(≤3 次尝试,
      每次重新解析拿新签名 URL)——2026-09-26 真实站点 12 部批量实测:403 过期
      靠模型手动开新批次,文件散落三个目录;本轮根治。新增
      retryBatchDownloads 工具作规范重试入口,工具描述明确禁止失败后用
      downloadMedia 单补(散落根源)。
    • 解析节流:下载占满并发槽时不预解析下一页——签名 URL 按需签,
      提前解析的地址会在队列里过期(403 主因)。
    • 低空间主动询问:剩余空间低于阈值(默认 20 GB)时队列挂起,经
      UserPromptCenter 问用户(继续 / 换位置 / 取消,超时视为继续);
      "换位置"走目录选择器并把位置落为偏好。新桥端点
      GET /agent/prompt + POST /agent/prompt/answer。
    • 命名偏好体系:clean(默认——按最小周期折叠站点标题模板的重复段,
      真实站点那批"同一句话截三遍"的文件名根治;尾部模板残留番号一并去除)、
      code(番号/代号优先)、title(原样)。工具 naming 参数显式传入的
      值会持久化并写入长期记忆(addFact, category=preference)——模型
      下次直接知道;自定义保存位置同理。
    • 磁盘预留硬底线 + 人性化配置:剩余空间低于预留线(reserveGB,
      默认 5GB)时挂起整批——在跑项收回 pending(不烧 attempts)、
      发会话备注 + 系统通知、面板提问(换位置/取消/已清理空间继续);
      空间监视每 30s 巡检,恢复到 预留 + 512MB 迟滞线以上自动续跑。
      预留不做"继续"绕过——防止写满磁盘是目的。配置经
      GET/POST /media/batch/config(reserveGB / naming / baseDirectory)。
    • 批量任务管理:新增 manageBatchDownloads 工具与桥端点——
      暂停/恢复整批、skip 单项(含下载中的项)、向既有批次追加任务
      (按 sourceURL 去重、序号接续,已完成批次追加后自动重跑)。
    • 可观测性:快照带批次级聚合(各状态计数、暂停/挂起原因)与
      逐项进度(done/total/单位,ffmpeg 路径按秒、内置下载器按段);
      引擎关键转移(解析/完成/失败/挂起/恢复)进统一日志
      (subsystem == "me.siwi.Desire", category == "downloads")。
    • 清晰度智能选择 + 变体族去重:"按最高清晰度下载"真正进引擎——
      stream 候选里 master 播放列表(无画质标记形态)优先于任何带画质标记
      的变体(master 内部由 MediaExporter 取最高码率),无 master 时按画质
      标记(720p/1080P…)取最高;page 模式规划做变体族去重:master 与
      其目录下的画质变体同时被嗅探到时只留 master(此前同一视频会按两个
      画质各下一份)。
    • 已下载索引(跨批次去重):完成的项把来源/媒体 URL 记入索引
      (DiskStore,2000 条上限按时间淘汰),重跑同一列表自动跳过已下载项
      (skipped 注明原路径),force 参数(工具/桥)可强制重下;
      batch.skipDownloaded 开关可全局关闭。
    • 下载原子化 + 完整性校验:所有下载一律写 <final>.part、成功后
      原地改名——崩溃/强杀只留一个 .part(下次尝试原地覆盖),根治崩溃
      残件触发 -1 后缀链的问题;完成后用 ffprobe 校验输出(时长 + 分辨
      率),摘要带 ✓ 60.0s, 320x240(无 ffprobe 或校验不过则不显示)。
    • 下载历史 + 并发配置:GET /media/batch/history(索引只读视图,
      最新在前,供回答"之前下过什么");batch.maxConcurrent(1-4,默认 2)
      经 config 端点可调。
    • DASH (.mpd) 支持的可行性结论:本机 Homebrew ffmpeg 无 dash
      demuxer
      (Unknown input format: 'dash',仅 webm_dash_manifest)——
      ffmpeg 直连不可行,维持跳过并注明;要支持需自写 mpd 解析 + 分段下载
      • 合流,暂不做。
    • 批量断点续传:未完成批次持久化到 DiskStore(状态转移点即时落),
      app 强杀/崩溃后重启恢复到队列(暂停态)——在途项收回到 pending
      (下载地址保留,签名过期由自动重试兜底),resume 续跑;终态自动清理。
    • listBatchDownloads 查进度(含 attempts);批次完成/取消/需要人工
      验证时发会话备注 + 系统通知(单项下载静默,批次统一汇总)。
    • 下载器 Cookie 透传:MediaExporter 把同域 webview Cookie(30s
      缓存)附到 URLSession 分段请求、Cookie 头给 ffmpeg——媒体 CDN 也挂
      Cloudflare 的站点(此前分段 403)现在可下。
    • 已知边界:DASH (.mpd) 与 DRM 流不支持(批量中明确跳过并注明原因);
      IntersectionObserver 懒加载的播放器靠点播放缓解,个别站点可能需把该页
      转到可见标签页人工触发。
    • 配套修复:批次取消后快照残留 resolving 行;重试后文件名序号叠加;
      低空间询问回答后永久卡住;resolveAll 对已解析项反复重解析。

Changed

  • 纯逻辑单测新增 BatchMediaPlan 用例(规划 16 项 + 命名风格 9 项,
    共 166 项)。

安装

未签名构建(CI 无 Developer ID 证书),仅支持 Apple Silicon(arm64,macOS 26.5+)。

  1. 解压 Desire-v0.4.2-macos-arm64.zip(双击,或
    ditto -x -k Desire-v0.4.2-macos-arm64.zip .)。
  2. 安装:把解压出来的 Desire.app 拖进 /Applications。
  3. 移除一次隔离标记(未签名构建必需),路径写你放 app 的那个:
xattr -cr /Applications/Desire.app
  1. 打开 Desire.app。首次启动 Gatekeeper 会检查一次;做过第 3 步就能正常打开。

报 xattr: No such file: Desire.app 说明当前目录里没有解压好的 app——
命令要写完整路径(如 /Applications/Desire.app),或先 cd 到它所在目录。