🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

参考帧抽取 dingchenhui0618-arch/dsh-take-sheet

DeepSeek Harness
dingchenhui0618-arch7 天前有提交已提供中文文档扫描:含敏感能力

按镜头切分视频,勾选帧并导出时间码清单与联系表

29.4/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/11/2 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dingchenhui0618-arch/dsh-take-sheet
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么[目录]—
dsh 原生插件 · other
暂无时间戳·判据 →
装得上吗[实装验证]—
本站尚未做安装检查
暂无时间戳·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 7 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 43 处,展示前 35 条)
  • 读取本地文件
    lib/index.js:47
    const data = readFileSync(path)
  • 读取本地文件
    lib/index.js:179
    if (!existsSync(input)) throw httpError(400, '找不到文件:' + input)
  • 读取本地文件
    lib/index.js:182
    info = statSync(input)
  • 读取本地文件
    lib/index.js:298
    if (!existsSync(path)) throw httpError(404, '缩略图文件不存在')
  • 读取本地文件
    lib/index.js:307
    if (job.export === undefined || !existsSync(path)) throw httpError(404, '还没有导出联系表')
  • 读取本地文件
    lib/index.js:321
    if (!existsSync(path)) throw httpError(404, '文件不存在')
  • 发起网络请求
    lib/client.js:37
    fetch(API + '/state', { headers: { accept: 'application/json' } })
  • 发起网络请求
    lib/client.js:70
    return fetch(API + '/' + method, {
  • 执行外部命令来自配置/变量
    lib/media.js:55
    child = spawn(bin, args, { windowsHide: true, cwd: settings.cwd })
  • 读取本地文件
    lib/media.js:125
    return existsSync(explicit) ? explicit : ''
  • 读取本地文件
    lib/media.js:129
    if (existsSync(beside)) return beside
  • 读取本地文件
    lib/media.js:132
    if (existsSync(candidate)) return candidate
  • 读取本地文件
    lib/media.js:247
    if (typeof explicit === 'string' && explicit.length > 0 && existsSync(explicit)) return explicit
  • 读取本地文件
    lib/media.js:248
    for (const candidate of FONT_CANDIDATES) if (existsSync(candidate)) return candidate
  • 写入本地文件
    lib/media.js:363
    mkdirSync(jobDir, { recursive: true })
  • 读取本地文件
    lib/media.js:375
    if (first.status !== 0 || !existsSync(firstPath)) {
  • 写入本地文件
    lib/media.js:412
    renameSync(source, join(jobDir, shot.thumb))
  • 删除本地文件
    lib/media.js:415
    if (/^cut- {4} jpg$/.test(name)) rmSync(join(jobDir, name), { force: true })
  • 写入本地文件
    lib/media.js:448
    mkdirSync(exportDir, { recursive: true })
  • 删除本地文件递归
    lib/media.js:450
    rmSync(sheetWork, { recursive: true, force: true })
  • 写入本地文件
    lib/media.js:451
    mkdirSync(sheetWork, { recursive: true })
  • 写入本地文件
    lib/media.js:456
    copyFileSync(source, join(sheetWork, pad(i + 1, 4) + '.jpg'))
  • 删除本地文件
    lib/media.js:479
    rmSync(join(sheetWork, 'sheet-0001.jpg'), { force: true })
  • 写入本地文件
    lib/media.js:485
    renameSync(join(sheetWork, 'sheet-0001.jpg'), target)
  • 删除本地文件递归
    lib/media.js:486
    rmSync(sheetWork, { recursive: true, force: true })
  • 写入本地文件
    lib/store.js:21
    writeFileSync(temp, text, 'utf8')
  • 写入本地文件
    lib/store.js:22
    renameSync(temp, path)
  • 写入本地文件
    lib/store.js:32
    mkdirSync(jobsRoot, { recursive: true })
  • 写入本地文件
    lib/store.js:42
    mkdirSync(dir, { recursive: true })
  • 读取本地文件
    lib/store.js:48
    const parsed = JSON.parse(readFileSync(indexPath, 'utf8'))
  • 读取本地文件
    lib/store.js:83
    raw = readFileSync(join(dir, 'scan.json'), 'utf8')
  • 删除本地文件递归
    lib/store.js:126
    rmSync(dir, { recursive: true, force: true })
  • 写入本地文件
    lib/store.js:127
    mkdirSync(join(dir, 'frames'), { recursive: true })
  • 写入本地文件
    lib/store.js:135
    mkdirSync(join(dir, 'frames'), { recursive: true })
  • 读取本地文件
    lib/store.js:140
    if (!existsSync(thumb)) throw httpError(500, '缩略图丢失:' + shot.thumb)
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DeepSeek Harness 标签页:把参考视频切成镜头、挑选帧、导出带时间码的清单和带标注的缩略图总览。纯本地运行,依赖 ffmpeg。

README

由 DeepSeek 最新模型翻译生成
dsh-take-sheet 把一段参考视频按镜头切开,逐镜抽一帧,人工勾选后导出带时间码的参考帧清单和一张联系表。 参考帧面板 这是 DeepSeek Harness 的一个插件:在对话视图里多一个「参考帧」页签。视频、帧和导出物都只在本机处理,不上传。 为什么做这个 做视频、广告或产品动画时,真正要交给下游的不是「一段参考视频」,而是「第 2 秒这一帧、第 6 秒这一帧,按这个顺序」。现成的抽帧工具通常把帧直接喂给模型,或者按固定间隔抽一堆;人还是要自己对着播放器找镜头、记时间码、截图、拼表。 这个插件把这段手工活收成一条流程: 1. 一次解码,检测镜头切点; 2. 每个镜头给一帧缩略图,带精确到毫秒的时间码; 3. 勾掉不要的,留下要用的; 4. 导出 frames.csv、shots.json、frames/ 和一张带时间码标签的联系表。 功能 - 按镜头切:用 ffmpeg 的 scdet 镜头检测,而不是固定间隔。切点阈值可选「敏感 / 标准 / 稳健」。 - 人工勾选:每镜一张 16:9 缩略图,点击卡片或复选框切换;全选 / 全不选;未选中的卡片会变暗。 - 时间码是帧自己的:缩略图上的 00:00:02.000 就是导出文件名和 CSV 里的时间码,不是近似的镜头起点。
展开完整文档(README 剩余 1 节)
dsh-take-sheet

把一段参考视频按镜头切开,逐镜抽一帧,人工勾选后导出带时间码的参考帧清单和一张联系表。

参考帧面板

这是 DeepSeek Harness 的一个插件:在对话视图里多一个「参考帧」页签。视频、帧和导出物都只在本机处理,不上传。

为什么做这个

做视频、广告或产品动画时,真正要交给下游的不是「一段参考视频」,而是「第 2 秒这一帧、第 6 秒这一帧,按这个顺序」。现成的抽帧工具通常把帧直接喂给模型,或者按固定间隔抽一堆;人还是要自己对着播放器找镜头、记时间码、截图、拼表。

这个插件把这段手工活收成一条流程:

1. 一次解码,检测镜头切点;
2. 每个镜头给一帧缩略图,带精确到毫秒的时间码;
3. 勾掉不要的,留下要用的;
4. 导出 frames.csv、shots.json、frames/ 和一张带时间码标签的联系表。

功能

- 按镜头切:用 ffmpeg 的 scdet 镜头检测,而不是固定间隔。切点阈值可选「敏感 / 标准 / 稳健」。
- 人工勾选:每镜一张 16:9 缩略图,点击卡片或复选框切换;全选 / 全不选;未选中的卡片会变暗。
- 时间码是帧自己的:缩略图上的 00:00:02.000 就是导出文件名和 CSV 里的时间码,不是近似的镜头起点。
- 联系表:自动按接近 3:2 的网格排版,黑底、每格左上角标 #01 00:00:00.200;字体找不到时退化为无标签版本,不会让导出失败。
- 导出即文件:CSV / JSON / JPEG / 帧文件都可直接打开、拷进 brief 或提交到项目里。
- 不离开本机:没有网络请求,不读 ~/.dsh 以外的配置。

导出后的联系表:

导出的联系表

导出结果面板(联系表预览 + 三个下载链接 + 本机输出目录):

导出结果

安装

需要 ffmpeg 5.1+(含 ffprobe)。插件不会替你安装它,但会自动在这些位置找:

- DSH_FFMPEG_PATH / FFMPEG_PATH 环境变量;
- Windows 的 WinGet Links 目录(winget install Gyan.FFmpeg 后就在那里);
- C:\ffmpeg\bin、Chocolatey、PATH;
- macOS 的 Homebrew、Linux 的 /usr/bin。

安装到某个 DSH 配置档:

dsh plugin --profile desktop add D:\Projects\dsh-take-sheet

lib/ 已随仓库提交,检出后不需要构建。装好后刷新 Web GUI,在任意会话的页签里点「参考帧」。运行中才装 ffmpeg 也不用重启:面板会提示缺少 ffmpeg,装好后点「重新检测」即可。

使用

1. 粘贴视频的绝对路径(本地文件,不支持 URL),例如 D:\refs\clip.mp4;
2. 选灵敏度和最多镜头数,点「扫描」;
3. 扫完会列出每个镜头的一帧;点卡片或复选框保留 / 去掉;
4. 点「导出参考帧清单」;面板下方出现联系表预览和三个下载链接。

「敏感」更容易把轻微转场也切成新镜头;「稳健」只认硬切。默认「标准」。如果一段片子里切点太多,会按时间均匀保留,并在面板上说明丢弃了多少个切点。

输出

每次导出写到 $DSH_HOME/take-sheet/jobs/<job-id>/export/:

export/
frames.csv
shots.json
contact-sheet.jpg
frames/
01_00-00-00.200.jpg
02_00-00-02.000.jpg
...

frames.csv(UTF-8 BOM,CRLF,Excel 直接打开):

shot,timecode,seconds,start,end,duration,file,source
1,00:00:00.200,0.200,0.000,2.000,2.000,frames/01_00-00-00.200.jpg,"D:\refs\clip.mp4"

shots.json 额外记录源视频的 probe 信息(时长、分辨率、fps、编码)、扫描参数、每个镜头的起止时间和联系表尺寸,方便脚本消费。

文件名里的时间码用 - 代替 :,因为 Windows 文件名不允许冒号;CSV 和画面上的标签仍是标准 HH:MM:SS.mmm。

与已有方案的关系

调研时看过三个 DSH 视频相关插件:

- Something11235/dsh-video-skin:把视频做成壁纸 / 启动动画,不做抽帧;
- HongtaoWang75/dsh-video-see:调用 ffmpeg 抽帧给模型看,带时间戳,也有拼图模式;
- shisuiqingqian/dsh-video-kit:转写 + 关键帧,主要也是给智能体做上下文。

所以「视频抽帧」这件事并不新,日报里「没人做视频理解」的说法不准确。本项目的差别只在流程的重心:镜头切分 + 人在环勾选 + 可交付的时间码清单/联系表,是给人做参考板用的,而不是给模型补上下文。没有复制上述任何项目的代码;抽帧命令是按 ffmpeg 文档和本机实测写的。插件的构建骨架(零依赖 lib/、cordis.patch.yml、host/client 两半、测试结构)沿用了同作者的 dsh-warden,业务代码是重新实现的。

一个实现上的选择:镜头检测用 scdet 而不是 select='gt(scene,T)'。在深色、低对比的产品渲染片上,scene 分数只有 0.24 左右,硬切也只有 ~0.26,很难分;scdet 在同一段素材上硬切约 9–10、普通帧约 0.005,阈值好定得多。

限制

- 只处理本地文件;不下载 URL、不读流媒体。
- 没有音频分析,也没有转写;镜头切分只看画面。
- 单次最多 200 个镜头(默认 60),极长视频需要多扫几段。
- 联系表的字体优先 Consolas / Segoe UI / Arial / DejaVu / Liberation;都没有时导出无标签版本。
- 导出会覆盖同一 job 的上一次导出(export/ 会先清空)。

开发

node scripts/build.mjs # src/ -> lib/,并把 CSS 内联进 client bundlebash
node --test test/*.test.mjs

测试共 39 个:纯函数(时间码、切点规划、CSV/ffmpeg 转义、网格)、media 层参数与版本门禁、host 路由与导出(假 media + 真 store)、client bundle 契约。test/integration.test.mjs 会用真实 ffmpeg 生成一段 6 秒三色视频,验证「两个切点 → 三个镜头 → 带标签联系表」;没有 ffmpeg 的机器上这组会自动 skip,而不是假装通过。

lib/ 是提交进仓库的构建产物。改了 src/ 必须重新 node scripts/build.mjs 并一起提交,CI 会检查 lib/ 与 src/ 是否一致。

License

MIT
预览分享卡片长什么样 ↓dingchenhui0618-arch/dsh-take-sheet
分享 · DeepSeek Harness Hub
dingchenhui0618-arch/dsh-take-sheet

按镜头切分视频,勾选帧并导出时间码清单与联系表

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部