dsh-short-video-studio

August 31, 2026 · View on GitHub

完全本地 · 免费 · 零云端依赖短剧 / 动画画布工作室,作为 DeepSeek Harness 双面插件运行。所有生成都跑在本地 ComfyUI 上——不需要任何付费云 API、不消耗额度,装好即用,一次生成、无限出片。

一句话:Agent 按你定义的 skill 编排流程,把生成请求派发到本地 ComfyUI 执行,产物落进可视化画布,还能通过飞书远程操控创作。

🌟 模型无关:FLUX 2 / MiniMax H3 只是插件随附的内置默认工作流,不是产品边界。本插件是通用的 ComfyUI 工作流执行器 + 能力注册表——任何 ComfyUI 能跑的模型(SDXL / SD3.5 / Qwen-Image / Wan / CogVideoX / LTX / 本地 Kling 等,图片或视频、带不带声音都可以)都能通过导入一份工作流清单接入,skill 与工具契约无需任何改动。换模型 = 加一份 JSON。

功能亮点

🖥️ 本地化、0 成本的视频工作流

  • 零云端依赖:默认图片用 FLUX 2、视频用 MiniMax H3 音视频 AV 模型带声音、支持参考图绑定画面内原生字幕,对白直接写进 prompt,无需后期叠加)——两者都只是内置默认,可整体替换为你自己的任何 ComfyUI 模型/工作流。
  • 画质/速度两档fast(4 步 + LoRA,调试快 5×+)与 quality(20 步,成片),分辨率按画布比例自动推导,支持 16:9 / 9:16 / 1:1 等任意画幅,snap32。
  • 完整后处理:同场景末帧串联(连续性过渡)、生成式转场镜、抽帧、拼接合成(本机有 ffmpeg 走零重编码,否则 ComfyUI 纯节点链路)——一条龙出片。

🎨 可视化画布

  • 每个会话多一个「画布」tab,按生产顺序预览 / 编辑 / 重做每一步产物:简报、大纲、角色卡、场景卡、镜头表、分镜、逐镜片段、成片。
  • 文本节点实时渲染 markdown(标题/表格/列表/代码块),媒体节点直接内嵌预览;分组、排序、删除、入库(一键登记为跨会话资产)都在画布上完成。
  • Agent 工具与画布页读写同一份持久状态,对话推进的每一步产物都实时可见。

🧩 自由扩展:skill 与 workflow

  • skill 可扩展:生产流程完全由 skill 定义(安装时自动复制到 ~/.dsh/skills/,可热扫描、可被用户覆盖)。写一个 SKILL.md 就能定义你自己的片型流程——插件本体不认识任何流程、任何片型词汇
  • workflow 可扩展:插件退化为「通用 ComfyUI 工作流执行器 + 能力注册表」。换模型、换工作流 = 增删一份 JSON,不动 JS、不动工具、不动系统提示。FLUX 2 / MiniMax H3 只是内置默认,你的任何 ComfyUI 工作流(SDXL / Qwen-Image / Wan / CogVideoX / LTX…)都可以直接导入并设为默认(见导入你的 workflow)。

🎬 多场景创作:一套引擎,任意场景

  • 默认内置 3D 动画短片场景(故事创意 → 角色/场景/镜头/分镜/逐镜/合成),但场景不是插件边界
  • 电商宣传视频(商品/卖点 → 展示分镜 + 口播)、教育课件讲解(知识点 → 图解 + 讲解)、品牌故事、纪念短片、Vlog 解说……任何「输入 X → 产出视频」的创作场景,都通过扩展一个 skill 覆盖——复用同一套画布、生成工具、资产库与飞书交付,只换编排规则(见开发你自己的场景 skill)。
  • 场景与模型双解耦:场景由 skill 定义、模型由注册表定义,两者互不绑定——电商场景也可以随时切换到你想用的任何 ComfyUI 模型。

📱 飞书集成:远程操控工作台创作

  • 会话可以跑在飞书聊天里(配合 dsh-lark 飞书渠道)——你在飞书里说一句话,Agent 就在本地工作台上按 skill 走完整条流水线。
  • 每次提问前,插件自动把画布产物送达飞书:图片/视频直接发原文件,简报/大纲/镜头表/分镜等文本自动导出为 PDF(飞书可直接预览)——无需登录任何后台,聊天里就能收片、审片、下指令重做。

安装说明:dsh-lark 飞书渠道是 web profile 的插件,安装时必须带 --profile web;若希望飞书与 dsh web 共用同一个 profile(同一份插件、会话与工作区,Web 画布与飞书聊天看到同一块画布):

dsh plugin --profile web add dsh-lark-channel@latest

装好后在飞书里把 bot 拉进群即可开始远程创作;群聊会先弹审批卡、再出选项卡。

快速开始

前置条件:本机或者远程主机已运行 ComfyUI,并已下载你计划使用的模型——内置默认(FLUX 2 / MiniMax H3)或你自己导入的模型(见配置导入 workflow)。

# 安装插件(三种来源任选其一;npm 为正式发布渠道,推荐)

# ① npm(正式发布,随版本自动更新安装源)
dsh plugin --profile web add dsh-short-video-studio
# ② GitHub(最新源码)
# dsh plugin --profile web add github:fengyungithub/dsh-short-video-studio
# ③ 本地源码(开发用)
# dsh plugin --profile web add file:/path/to/dsh-short-video-studio

dsh web   # 重启后会话出现「画布」tab;自带 skill 已自动装到 ~/.dsh/skills/

安装后自动完成三件事:skills/ 下 skill 复制到 ~/.dsh/skills/(幂等,不覆盖你的修改);Web 设置页新增 ComfyUI 配置菜单;会话多出「画布」视图 tab。

开始创作:在会话里说

把「一只想当宇航员的小狐狸」做成 30 秒 3D 动画短片

Agent 会按 skill 定义的流程推进:项目简报 → 故事大纲 → 角色卡 → 场景卡 → 镜头表 → 分镜 → 逐镜生成 → 拼接合成,关键节点用选项卡确认。产品界面(真实会话截图):

对话体验:流程叙述 + 任务看板对话体验:可视化画布
会话截图1会话截图2

架构概览

完整设计文档见 docs/ARCHITECTURE.mddocs/workflow-contract.md。核心分层:

┌──────────────────────────────────────────────────────────────┐
│ 展示层(浏览器半)  lib/client.js + studio/                     │
│  「画布」会话 tab + 「ComfyUI」设置页(配置 / 注册表 / 导入)      │
├──────────────────────────────────────────────────────────────┤
│ 契约层(纯数据 + 校验)  workflows/*.json + lib/manifest.js      │
│  能力词汇表 · 注入原语 · $assets 占位 · $model 哨兵 · 强校验     │
├──────────────────────────────────────────────────────────────┤
│ 执行层(宿主半)  lib/index.js                                 │
│  ComfyUI 客户端 · 渲染编排 · 分辨率策略 · 注册表解析 · 画布存储  │
├──────────────────────────────────────────────────────────────┤
│ 集成层                                                        │
│  Agent 工具注册 · GUIDANCE · HTTP 路由 · skill 安装 · 渠道送达  │
└──────────────────────────────────────────────────────────────┘

设计主张:插件不认识「FLUX」「H3」这些名字,只认识能力(capability)与工作流清单(manifest,数据而非代码)——FLUX 2 / MiniMax H3 只是注册表里「恰好是默认」的两条记录,任何模型接入后享有同等地位。三层正交契约:

内容载体
① 任务契约Agent 只描述「要什么」:capability + 类型化输入Agent 工具参数
② 能力契约抽象作业词汇表:image.text2image / video.reference2video / audio.tts…(开放集合)CAPABILITIES
③ 工作流绑定契约一份清单 = 一个 capability → 一个 ComfyUI 图 + 注入点 + 资产 + 质量档(JSON 数据workflows/*.json

清单里的 $assets.<key> 占位让「换模型文件只改配置」;["$model", 0] 哨兵让「按质量档插 LoRA 链」由编译期自动完成。注册表来源优先级:内置 workflows/ < 用户 ~/.dsh/dsh-short-video-studio/workflows/(同名遮蔽)< assetOverrides / 环境变量(换模型文件名,不动图结构)。

目录结构

├── lib/
│   ├── index.js          # 宿主半:ComfyUI 客户端、渲染编排、画布存储、路由、Agent 工具、GUIDANCE
│   ├── manifest.js       # 契约引擎:能力词汇、manifest 校验、图编译、注册表加载
│   ├── concat.js         # 视频拼接(ffmpeg 优先 / ComfyUI 纯节点退化)
│   ├── convert.js        # ComfyUI「导出 API」JSON → workflow manifest 转换器
│   ├── assets.js         # 跨会话资产库(角色卡 / 场景卡 / 风格锚点)
│   ├── pdf.js            # 文本节点 → PDF(puppeteer-core 优先,CLI 兜底)
│   └── client.js         # 浏览器半:画布 tab + ComfyUI 设置页
├── studio/               # 画布页(自包含 HTML/CSS/JS,无构建)
├── workflows/            # 内置工作流清单(数据,非代码)
├── schemas/              # workflow-manifest 权威 JSON Schema
├── skills/               # 自带 skill(安装时复制到 ~/.dsh/skills/)
├── docs/                 # 架构 / 契约 / 实验报告
└── scripts/              # 冒烟 / e2e / 导入转换脚本

内置工作流清单(默认,可替换)

下表是插件随附的内置默认。导入你自己的清单后即可通过 preferred 把它设为某能力的默认工作流——内置清单可以不用、可以遮蔽、可以删除。

清单能力说明
flux-text2imageimage.text2imageFLUX 2 文生图(角色卡 / 场景卡 / 分镜图)
minimax-h3-ref2vvideo.reference2videoH3 参考绑定,ref_nodes 绑定身份/环境,带声音
minimax-h3-i2vvideo.image2videoH3 首/末帧串联(同场景续接镜 / 转场镜),带声音
extract-frameimage.from_video抽帧(末帧 / 首帧 → 图片节点)

Agent 工具契约

工具
生成comfy_generate_image · comfy_generate_video · comfy_render(通用入口,模型无关)· comfy_list_workflows(查能力/工作流)
后处理extract_frame(抽帧)· video_concat(拼接成片)
画布canvas_list_nodes · canvas_write_node · canvas_get_node · canvas_group_nodes · canvas_reorder · canvas_get_state · canvas_set_state
资产asset_list · asset_to_canvas

全部工具模型无关:capability 由注册表 preferred 解析到具体工作流,prompt 与流程里不硬编码模型名。

扩展:开发你自己的场景 skill

适配场景:插件默认内置的 skill 是 3D 动画短片这一种场景(故事创意 → 角色/场景/镜头/分镜/逐镜/合成)。但场景不是插件边界——任何「输入 X → 产出视频内容」的创作场景,都能通过扩展 skill 覆盖,复用同一套执行层工具(生成 / 画布 / 资产 / 拼接 / 飞书交付),只换编排规则:

场景输入skill 定义的编排重点
3D 动画短片(内置默认)一句话故事创意角色一致、场景连续、镜头表自检、H3 原生字幕
电商宣传视频商品 / 卖点文案产品展示分镜、口播逐字稿、卖点高光镜、BGM 与节奏
教育课件讲解知识点 / 讲义图解卡片、讲解分镜、字幕与口型绑定、节奏控制
品牌故事 / 纪念短片 / Vlog 解说…素材与主题按你的业务规范自定义

每个场景 skill 就是一个 SKILL.md(纯文本编排规则),插件对它零认知——触发哪个 skill 就完全按它执行。三步即可定义一种新场景:

  1. ~/.dsh/skills/ 下新建目录(或本仓库 skills/ 下),写 SKILL.md,frontmatter 声明触发条件:
---
name: my-niche-skill
description: 把 X 素材做成 Y 风格短片的完整流程。当用户提到「X 转 Y 短片」时使用。
whenToUse: 适用于……不适用于……
---

## 生产流程
1. 开场:用 canvas_set_state 声明画幅/时长/音频模式与分组展示顺序
2. 用 comfy_generate_image 建角色卡/场景卡(单视图、零文字)
3. 用 comfy_generate_video 逐镜生成(mode=fast 调试 → quality 成片)
4. 用 video_concat 拼接,交付前把文本要点写进回复(飞书自动送达产物)
  1. 用能力词汇而非模型名:skill 里只写 comfy_render(capability=video.reference2video) 这类调用;具体工作流由注册表 preferred 决定,用户换模型时你的 skill 不用改。

  2. 关键节点用选项卡确认ask_user_question),把耐用产物全部落画布。

扩展:导入你自己的 ComfyUI workflow

三种途径,任选其一:

方式 A · 设置页粘贴(推荐):Web 设置页 → ComfyUI → 工作流导入。粘贴你的工作流清单 JSON,或直接粘贴 ComfyUI「Export (API)」导出的原始 JSON({nodeId:{class_type,inputs}} 格式)——插件会自动转换:抽取模型资产、识别可注入的标量字段,并输出「待人工确认的语义绑定」清单(哪些字段对应 prompt / 宽高 / 参考图)。

方式 B · CLI 转换

node scripts/import-comfy.mjs exported.json \
  --id sdxl-text2image --capability image.text2image --name "SDXL 文生图"

方式 C · 手写 manifest:参照 schemas/workflow-manifest.schema.json 与内置 workflows/ 示例,写一份清单放到 ~/.dsh/dsh-short-video-studio/workflows/<id>.json(重启或设置页刷新后即入注册表)。强校验保证错误清单被拒绝而不是静默降级:

{
  "id": "my-video",
  "version": 1,
  "capability": "video.reference2video",
  "runner": "comfyui",
  "displayName": "我的视频工作流",
  "output": { "mediaType": "video", "hasAudio": true },
  "assets": { "unet": { "kind": "checkpoint", "default": "my_model.safetensors" } },
  "graph": {
    "1": { "class_type": "UNETLoader", "inputs": { "unet_name": "$assets.unet" } }
  },
  "params": [
    { "name": "prompt", "inject": { "type": "scalar", "to": [["5", "prompt"]] } },
    { "name": "width",  "inject": { "type": "scalar", "to": [["5", "width"]] } }
  ]
}

导入后即可用 comfy_render / comfy_list_workflows 按能力调用;同名清单遮蔽内置版本;preferred 决定默认工作流。

配置(个性化)

优先级:环境变量 > 配置文件 > 默认值。Web 设置页的 ComfyUI 菜单提供可视化编辑,保存即生效:

ComfyUI 设置页
ComfyUI 设置

配置文件:~/.dsh/dsh-short-video-studio.json(或 DSH_SVS_CONFIG 指定路径):

{
  "baseUrl": "http://localhost:8188",
  "apiKey": "",
  "pollMs": 2000,
  "timeoutMs": 900000,
  "models": { "fluxUnet": "flux2_dev_fp8mixed.safetensors", "h3Fps": 24, "…": "…" },
  "preferred": { "video.reference2video": ["minimax-h3-ref2v"] },
  "assetOverrides": { "minimax-h3-ref2v": { "unet": "my_custom.safetensors" } }
}
  • models.* / 环境变量(DSH_SVS_COMFY_URL / DSH_SVS_FLUX_MODEL / DSH_SVS_H3_MODEL_REF 等):换模型文件不改图结构;
  • preferred:每个能力默认用哪个工作流(设置页「设为默认」写回这里)——把你导入的工作流设为某能力的默认,即完成「换模型」,内置清单可保留可遮蔽可删除
  • assetOverrides:按清单粒度覆盖资产文件(同 $assets 机制,优先级最高);
  • apiKey 非空时请求带 Authorization: Bearer(适配需鉴权的 ComfyUI 网关)。

渠道交付(飞书 / TUI)

前置:飞书渠道 dsh-lark 是 web profile 插件,需 dsh plugin --profile web add dsh-lark-channel@latest(与 dsh web 共用同一 profile,见飞书集成)。

「画布」tab 只在 Web 可见;跑在 TUI / 飞书时,插件在每次提问(ask_user_question)前自动把画布未送达产物发到飞书:媒体文件直接发,文本/表格节点自动导出 PDF(文件名取节点标题,如 主角卡.png / 简报.pdf)。群聊会先弹审批卡、再出选项卡。Web / TUI 无此通道,产物在画布/工作区,按工具返回的绝对路径自取。详见 docs/channel-delivery.md

实战要点(沉淀自真实生产)

  1. 参考图必须用单视图:参考图里有几个身体,画面就倾向出现几个角色;三视图拼图必然产生角色副本,且 prompt 声明无效(实验报告)。只用单视图卡。
  2. 参考图内不得有任何文字:角色名、FRONT VIEW 之类标注会被视频模型渲进成片。名字只写画布标题与资产元数据。
  3. 多角度对模型无增量价值:单张正面卡足以支撑转身/走远镜头;多角度时把多张单视图分别放进不同 ref_nodes 槽位,绝不拼成一张图。
  4. 原生字幕:使用带原生字幕能力的视频模型(如内置默认 H3)时,对白字幕写进 prompt 末尾即可端到端渲染(含中文);换成不带该能力的模型后,此条不适用,字幕需走其它方式。
  5. 末帧串联仅用于同场景续接;跨场景只放「角色 + 场景」参考。
  6. 角色分状态建卡:同一角色不同着装分别建单视图卡。

H3 结构化 prompt(本地版 H3-Context-IR 替代)

本地 H3 工作流(minimax-h3-*)的逐镜 prompt 默认走 H3 结构化格式,用「本地 agent + skill」复刻官方云端 H3-Context-IR 的核心产物,提升成片质量(官方明言 Context-IR 直接决定输出质量):

  • h3-prompt-writing skill(插件适配版):官方 MiniMax 规范(references/base-en.txt / ref-en.txt 只读引用)+ 插件映射表 references/studio-mapping.md。参考绑定镜输出 Ref2VA 六段式(subject_definitions / summary / retention_analysis / detailed_description / overall_soundscape / non_diegetic_music);首末帧串联镜 / 转场镜输出 I2VA / FL2VA 三段式(对齐指令 + integrated_multimodal_description + overall_soundscape + non_diegetic_music)。仅当解析工作流 id 前缀为 minimax-h3- 时启用,其他模型自动回退自由格式(模型无关)。
  • 片型 skill 委托:3D 动画等片型 skill 的 Step 7 只写「加载 h3-prompt-writing 重写」,不内置任何 H3 字段细节(职能单一)。
  • hook 门兜底tools/pre-execute 校验 H3 系工作流的 prompt 是否携带结构化字段,缺失时 deny 并引导 agent 加载 skill 重写(同一 agent 连续 2 次后降级放行,不会死循环)。
  • 关闭方式:覆盖 / 删除 ~/.dsh/skills/h3-prompt-writing 的「插件对接」适配节(或整体删目录)即回到自由格式组装;lib/index.jsH3_PROMPT_GATE 常量可单独关掉 hook 门。

✅ 字幕兼容已实测定稿(A/B 六变体,见画布「A/B 实验结论」):六段式下字幕必须以英文双引号 on-screen text 声明内嵌 detailed_description 对白处(中文措辞指令任何位置不生效),dialogue 镜成片用 quality 档保证字准;口型安全 / 一致性 / 音频与旧格式同级,动作执行略优。

示例:《一只想当宇航员的小狐狸》

一个完整走完流水线的 30 秒 3D 动画短片(6 镜、quality 档、H3 原生字幕),展示画布各步骤的真实产物

角色卡与场景卡

⚠️ 以下角色卡为历史三视图拼图 + 带标注文字,属反面示例(实测会导致多角色副本与文字烙印);正确做法见上文实战要点——单视图、零文字。

小狐狸(不穿)小狐狸(穿宇航服)小兔子
小狐狸不穿小狐狸穿小兔子
夜晚森林白天工作台森林小径山顶星空
场景A场景B场景C场景D

逐镜成片截图

S01S02S03
S01S02S03
S04S05S06
S04S05S06

成片 1344×768 · 24fps · 29.6s · H.264 + AAC(H3 声音)· H3 原生中文字幕。对白(含字幕):S01「总有一天,我要飞到星星上去!」→ S02「我要做一件宇航服!」→ S03 小兔子「狐狸怎么能当宇航员呀?」→ S04「梦想又不需要翅膀,只需要勇气!」→ S05「看,我就要起飞啦!」→ S06「星星……我来啦……」。

复现:在会话里说「把『一只想当宇航员的小狐狸』做成 30 秒 3D 动画短片」,Agent 会按 skill 的 Step 0→8 逐步落画布并逐镜生成。


发布新版本(维护者)

npm 包由 GitHub Actions 自动发布(推送 v* tag 触发,见 .github/workflows/npm-publish.yml;发布前自动跑冒烟自检并带 provenance 供应链签名)。前提:仓库已配置 NPM_TOKEN secret(npmjs.com → Access Tokens → Automation 类型)。

npm version patch        # bump 版本并打 vX.Y.Z tag(minor / major 同理)
git push origin main --follow-tags   # 推送即触发自动发布

发布后安装方式:dsh plugin --profile web add dsh-short-video-studio


更多设计细节:架构 docs/ARCHITECTURE.md · 工作流契约 docs/workflow-contract.md · 渠道交付 docs/channel-delivery.md