开源 AI 视频编辑器实战:用 Manifest + Adapter 构建可扩展的生成插件系统

最近,我们为开源浏览器 AI 视频编辑器 Timeline Studio 增加了一套生成插件架构。

目前已经接入三类具有代表性的生成工具:

  • Puter.js
  • ComfyUI
  • Stable Diffusion WebUI / Forge

这次改造并不是简单地在界面上增加几张插件卡片,而是尝试解决一个工程问题:

如何将鉴权方式、任务协议和结果格式各不相同的 AI 生成服务,接入同一套视频素材工作流?

项目地址:

https://github.com/MartinDelophy/ai-video-editor

在线体验:

https://video-editor.ai-creator.top/

一、为什么要设计生成插件系统?

Timeline Studio 是一款本地优先、直接运行在浏览器中的开源 AI 视频编辑器。

项目提供多轨时间线、画中画、字幕、配音、音乐、关键帧、遮罩、滤镜、速度调整和离线视频导出,并通过 WebGPU、WebCodecs、WASM 和 ONNX Runtime Web 实现多项浏览器 AI 能力。

随着图片和视频生成服务不断增加,直接在业务组件中接入供应商会遇到明显的扩展问题。

一种常见写法如下:

javascript 复制代码
if (provider === "provider-a") {
  // Provider A 的鉴权和请求
} else if (provider === "provider-b") {
  // Provider B 的轮询和结果解析
} else if (provider === "provider-c") {
  // Provider C 的下载与错误处理
}

最初接入一两个服务时,这种方式看起来足够直接。但随着供应商增加,以下逻辑会逐渐混在一起:

  • 登录与鉴权
  • 连接状态
  • 请求参数
  • 任务轮询
  • 进度解析
  • 任务取消
  • 错误转换
  • 结果下载
  • 素材下载
  • 多语言文案

最终,一个生成 Hook 或 React 组件可能同时理解所有供应商的接口细节。

插件架构的目标,就是把这些变化频繁的供应商逻辑隔离起来,让编辑器核心只处理稳定的能力和结果。

二、先确定插件边界

Timeline Studio 当前的插件主要面向图片和视频生成。

第一版契约覆盖:

  • 文生图
  • 图生图
  • 文生视频
  • 图生视频
  • 工作流图片生成
  • 工作流视频生成

以下能力暂时不属于这套契约:

  • 时间线编辑命令
  • 转场和特效
  • 任意 React 扩展
  • 模型训练
  • 内容信息流
  • 通用网页嵌入

限制插件范围可以防止第一版接口承担过多职责。

编辑操作需要访问复杂的项目状态和撤销历史,生成插件则只需要接收输入并返回媒体。二者的安全边界和生命周期完全不同,不适合使用同一套契约。

三、插件系统的核心闭环

我们对插件完成状态做了一个明确规定:

插件只有在编辑器取得真实媒体数据并保存到 My assets 后,才能报告完成。

完整流程如下:

text 复制代码
选择插件
    ↓
连接服务或完成授权
    ↓
填写提示词、参数或工作流
    ↓
提交真实生成任务
    ↓
同步或轮询任务状态
    ↓
下载图片或视频
    ↓
验证媒体类型和数据
    ↓
提交到 My assets

生成完成后,素材会自动进入 My assets(我的素材),但不会自动插入时间线。

这样设计有两个原因。

第一,远程平台返回的结果 URL 可能带有时效性。只保存 URL 并不能保证用户稍后仍能使用素材。

第二,生成内容是否进入当前作品应由用户决定。插件不应该在没有明确操作的情况下改变时间线结构。

四、Manifest 与 Adapter 分离

插件采用声明信息和传输实现分离的方式组织。

目标目录结构如下:

text 复制代码
src/plugins/generation/
├── contract.js
├── registry.js
├── host.js
└── providers/
    └── example-provider/
        ├── manifest.js
        ├── adapter.js
        ├── Inspector.jsx
        ├── copy.js
        └── index.js

1. Manifest:声明插件能力

Manifest 保存稳定的声明信息:

javascript 复制代码
export const manifest = {
  schemaVersion: 1,
  id: "example-provider",
  displayName: "Example Provider",
  version: "1.0.0",
  runtime: "secure-backend",
  capabilities: ["text-to-image"],
  outputTypes: ["image"],
  auth: "backend",
  defaultEndpoint: null,
};

字段职责包括:

  • id:稳定的插件标识;
  • version:适配器行为版本;
  • runtime:插件运行模式;
  • capabilities:支持的生成能力;
  • outputTypes:可返回的媒体类型;
  • auth:使用的鉴权方式。

Manifest 中禁止保存:

  • API Key
  • Token
  • Cookie
  • 用户账号
  • 工作流密钥
  • 任意远程可执行代码

插件卡片的介绍、按钮和表单字段也不直接写在 Manifest 中,而是从独立的多语言文案模块读取。

2. Adapter:隔离供应商接口

Adapter 负责供应商相关的传输逻辑:

javascript 复制代码
export function createAdapter(services) {
  return {
    async connect({ config, signal }) {
      // 验证端点或完成授权
    },

    async disconnect() {
      // 清理连接状态
    },

    async generate({ request, signal, onState, onProgress }) {
      // 提交任务并返回统一结果
    },

    async cancel({ job }) {
      // 根据供应商能力取消任务
    },

    normalizeError(error) {
      // 转换为编辑器可展示的错误
    },
  };
}

Adapter 不应该直接修改时间线,也不应该自行维护一套素材库。

它只负责:

  • 连接服务;
  • 提交请求;
  • 读取真实状态;
  • 下载生成结果;
  • 转换错误;
  • 返回标准化数据。

最终素材由共享 Host 验证和提交。

3. Registry:统一发现插件

Registry 是插件的统一注册入口。

编辑器只需要从 Registry 读取可用插件,不必扫描组件,也不必在多个位置维护供应商列表。

新增插件时,开发者注册 Manifest 和 Adapter 即可,不需要在共享 Hook 中增加新的供应商条件分支。

4. Host:统一管理结果

共享 Host 负责供应商不应该自行处理的逻辑:

  • 任务互斥
  • 取消协调
  • 忽略过期回调
  • 结果格式归一化
  • 图片和视频验证
  • My assets 提交

这样可以确保所有插件遵守同一套结果标准。

五、三类插件运行模式

不同服务使用不同的鉴权和部署方式,因此插件需要先选择一种明确的 Runtime。

1. Browser Session

这种模式适合拥有浏览器 SDK、弹窗授权和用户账户体系的服务。

Puter.js 是当前示例。

用户点击连接后打开真实登录窗口,后续生成使用登录用户自己的账户和额度。编辑器不需要保存 API Key,也不能模拟授权成功。

需要注意的是,依赖弹窗的授权必须直接在用户点击事件中同步启动。如果在打开弹窗前执行多个异步检查,浏览器可能将其识别为非用户触发并拦截。

2. Loopback

Loopback 模式用于连接用户电脑上运行的服务,例如:

  • ComfyUI
  • AUTOMATIC1111
  • Stable Diffusion WebUI
  • Forge

插件只允许访问本机回环地址:

text 复制代码
localhost
127.0.0.1
::1

禁止默认连接局域网主机,也不应建议用户:

  • 将未认证服务监听到 0.0.0.0
  • 对整个局域网开放端口;
  • 使用通配符 CORS;
  • 关闭必要的访问控制。

显示"已连接"之前,插件必须验证对应服务的健康检查接口和 CORS。

3. Secure Backend

如果供应商需要开发者持有 Secret,则必须通过安全后端调用。

text 复制代码
Timeline Studio
      ↓
安全连接后端
      ↓
云端生成服务

密钥不能存放在:

text 复制代码
前端源码
浏览器构建文件
localStorage
Manifest
日志
示例配置
Git 仓库

安全后端可以负责创建任务、查询状态、处理回调和签名结果地址。浏览器端 Adapter 只接收完成当前操作所需的受控数据。

六、为什么 ComfyUI 和 WebUI 是两个插件?

ComfyUI 与 Stable Diffusion WebUI / Forge 都能运行图片生成模型,但它们的产品模型不同。

ComfyUI:工作流优先

ComfyUI 插件接收 API Format 工作流,提交真实 Prompt 任务,跟踪执行状态,并下载工作流中声明的全部媒体输出。

它适合:

  • 多节点图片工作流
  • ControlNet
  • 放大和修复
  • 图生图
  • 视频生成节点
  • 自定义节点组合

插件不能假设某个固定节点一定是最终输出,而应根据任务历史和工作流声明收集生成结果。

WebUI / Forge:提示词优先

WebUI 插件直接调用兼容 API,例如:

text 复制代码
/sdapi/v1/txt2img
/sdapi/v1/img2img

它更适合传统提示词、采样器、尺寸、步数和参考图片等参数驱动的交互。

将二者拆成独立插件,可以避免出现一个同时处理工作流 JSON 和普通提示词表单的超大适配器。

七、不要伪造连接和生成进度

插件系统中很容易出现两类"乐观状态"。

第一类是填写地址后立即显示已连接。

第二类是在供应商没有提供进度时,自行生成一个不断增长的百分比。

Timeline Studio 要求连接状态真实反映服务状态:

text 复制代码
disconnected
connecting / authorizing
connected
error

任务状态同样需要明确:

text 复制代码
idle
queued
running
complete
cancelled
error

只有供应商返回具有实际意义的百分比时,界面才能显示数值进度。否则应展示不确定进度状态。

一个任务返回 URL 也不等于完成。插件还需要成功下载并验证媒体数据。

八、处理异步任务中的竞争问题

生成任务通常需要数十秒甚至更长时间,期间用户可能:

  • 取消任务;
  • 断开连接;
  • 切换插件;
  • 修改端点并重新连接;
  • 启动下一次生成。

这会产生典型的异步竞争问题。

例如,第一次连接请求响应较慢,用户已经修改配置并完成第二次连接。如果第一次响应随后返回,就可能覆盖最新状态。

因此,共享 Host 需要识别当前任务所有权,并忽略来自旧请求的迟到回调。

可以使用递增版本或唯一任务标识:

javascript 复制代码
const attemptId = ++currentAttempt;

const result = await adapter.connect(config);

if (attemptId !== currentAttempt) {
  return;
}

setConnection(result);

生成任务也需要类似处理。取消本地等待并不一定代表远端任务已经停止,因此 Adapter 还必须准确说明取消语义,不能把"停止轮询"描述成"远端任务已取消"。

九、错误信息也属于插件契约

网络请求失败时,浏览器可能只返回:

text 复制代码
Failed to fetch

这条信息对用户几乎没有帮助。

Adapter 需要把底层错误转换成可操作的提示,例如:

  • 本地服务尚未启动;
  • 端口或协议配置错误;
  • 当前编辑器来源未被 CORS 允许;
  • 登录状态已经过期;
  • 工作流不是 API Format;
  • 服务返回了不支持的媒体格式;
  • 结果地址已经过期;
  • 当前账户没有生成额度。

供应商特有错误由 Adapter 识别,共享 Host 再将其转换为统一错误结构,最后由多语言界面展示。

十、当前为什么采用源码集成插件?

Timeline Studio 当前的插件是经过代码审查的源码集成连接器,并不是可以下载任意第三方 JavaScript 的开放市场。

开放式插件运行时还需要解决:

  • 权限模型
  • 沙箱隔离
  • 插件签名
  • 版本兼容
  • 数据访问控制
  • 安装与卸载
  • 恶意代码检查
  • API 生命周期

在这些机制完成前,把源码适配器称为"可任意安装插件"会造成错误预期和安全风险。

因此,当前新增插件的正确方式是:

  1. 阅读插件开发契约;
  2. 评估供应商 API 是否满足要求;
  3. 创建隔离的 Manifest 和 Adapter;
  4. 补充插件专属界面与多语言文案;
  5. 验证连接、取消、错误和输出下载;
  6. 通过 Pull Request 接受代码审查。

十一、如何参与项目?

完整的插件开发规范已经放在仓库中:

Timeline Studio 生成插件开发文档

本地运行项目:

bash 复制代码
git clone https://github.com/MartinDelophy/ai-video-editor.git
cd ai-video-editor
npm install
npm run dev

项目使用 MIT License,欢迎参与以下方向:

  • 接入新的图片或视频生成服务;
  • 完善 ComfyUI 工作流兼容;
  • 改进 WebUI / Forge 参数支持;
  • 建设安全的云端连接层;
  • 优化插件任务状态与错误处理;
  • 完善国际化文案;
  • 参与 WebGPU、WebCodecs 和浏览器 AI 能力开发。

GitHub:

https://github.com/MartinDelophy/ai-video-editor

在线体验:

https://video-editor.ai-creator.top/

总结

一个可用的 AI 生成插件,不能只是展示一张供应商卡片,也不能只是嵌入一个外部网页。

它至少需要完成:

text 复制代码
真实连接
+ 真实生成
+ 真实状态
+ 自动下载
+ 媒体验证
+ 素材入库
+ 安全鉴权

Timeline Studio 通过 Manifest、Adapter、Registry 和 Host 分离插件职责,让云端服务、浏览器 SDK 和本地生成工具能够接入同一套素材工作流。

AI 模型还会继续变化,但视频编辑器的核心不应该跟着每个供应商反复重写。

如果你也在关注浏览器 AI、视频编辑或生成服务集成,欢迎体验 Timeline Studio,并在 GitHub 上提交 Issue、建议或 Pull Request。

相关推荐
小唔w1 小时前
告别水印烦恼:2026年AI去水印工具实测与梳理
人工智能
人民广场吃泡面1 小时前
DLSS 5 深度解析:当 AI 学会“创造”画面,实时游戏渲染迎来“GPT 时刻”
人工智能·gpt·游戏
行走的小派1 小时前
香橙派高质价比OPi 4系列4款板卡如何匹配不同开发需求
人工智能
tuanxiang1 小时前
文本AI率检测免费实现方案:本地部署绕过商用接口配额限制
人工智能
明月_清风1 小时前
GPT-6 Astra 与 AGI 的门槛:我们到底在争论什么?
人工智能·后端·openai
PcVue China1 小时前
智控能耗,数驱能效 | PcVue线上研讨会进行中!
大数据·人工智能·能源·制造·直播·scada·pcvue17
技灵AI1 小时前
Seedance 视频生成提示词怎么写?从镜头方法到 10 套可直接改的完整 Prompt
人工智能·prompt·aigc·音视频
RoboWizard1 小时前
拍4K视频手机内存不够用怎么办?
智能手机·音视频