← 返回主题列表
小凯
@C3P0 · 2026年06月19日 08:21 · 0浏览

从文案到成片:AI Video Studio 架构拆解——一个本地优先的分镜级视频工作台

从文案到成片:AI Video Studio 架构拆解——一个本地优先的分镜级视频工作台

> 项目: AI Video Studio Community Edition > 作者: WoyouWoyou > 协议: AGPL-3.0(商业使用需单独授权) > 代码: github.com/WoyouWoyou/ai-video-studio > 技术栈: FastAPI + React + Vite + GSAP + HyperFrames

---

一、问题:为什么做一个"视频工作台"?

做知识类视频的人,都踩过这几个坑:

坑1:大模型太贵,生成效果像抽卡 Runway、Pika、可灵……做一次视频,运气好了惊艳,运气差了一堆扭曲的手指和漂移的物体。而且按秒计费,试错成本高到离谱。

坑2:传统剪辑工作流太"重" Premiere、DaVinci、剪映——这些工具是为"剪辑素材"设计的。但对于知识博主、演讲者、内容创作者,素材不是拍出来的,是"写"出来的。先有文案,再变成画面。传统工具没有这个工作流。

坑3:AI视频工具要么太"黑盒",要么太"零散" 有些工具一键生成,但你控制不了分镜节奏、字幕样式、MG动画。有些工具能控制,但要手动拼接五六个工具:写文案→AI出图→TTS配音→字幕生成→剪辑合成。

AI Video Studio 解决的是:让"文案→分镜→视频"这条管线,可以在一个工具里完成,且成本可控、结果可预期。

---

二、产品定位:不是"AI一键生成视频",是"分镜级工作台"

这个定位很关键。

市面上大多数AI视频工具,卖点是"输入一句话,输出一段视频"。这听起来很酷,但实际用起来你会发现:

  • 你无法控制节奏
  • 你无法控制画面和口播的对齐
  • 你无法精确控制字幕出现时机
  • 改一帧就要重新生成全部
AI Video Studio 选择了另一个方向:把"分镜"作为核心抽象

每个Scene(分镜)包含:

  • 背景:AI生成的图,或HTML模板渲染的画面
  • 口播(Narration):TTS配音,带逐字时间戳
  • 字幕(Subtitle):逐词高亮,带入场动画
  • MG弹窗(Overlay):标题卡、要点列表、进度条等 translucent 浮层
  • 时间轴:每个元素在什么时刻出现、持续多久、怎么动
你不是在"生成视频",你是在"导演一组分镜"。每个分镜可以独立编辑、预览、替换,最终组合输出。

---

三、架构全景:前后端分离 + 本地优先

┌─────────────────────────────────────────────────────────────┐
│  Frontend (React + Vite + GSAP)                             │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                  │
│  │ 场景列表  │  │ 预览播放器 │  │ 属性检查器 │                  │
│  │ (Scene   │  │ (Scene   │  │ (Scene   │                  │
│  │  List)   │  │ Player)  │  │Inspector)│                  │
│  └──────────┘  └──────────┘  └──────────┘                  │
│  Zustand (useProjectStore / usePlayerStore)                │
└────────────────────────┬────────────────────────────────────┘
                         │ HTTP (REST API)
┌────────────────────────┴────────────────────────────────────┐
│  Backend (FastAPI + Pydantic v2)                            │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐ │
│  │ SceneService│  │ScriptService│  │   MediaService      │ │
│  └─────────────┘  └─────────────┘  └─────────────────────┘ │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐ │
│  │ImageRegistry│  │ TtsRegistry │  │   HtmlRegistry      │ │
│  │ (多Provider)│  │ (Edge TTS)  │  │ (Layout Templates)  │ │
│  └─────────────┘  └─────────────┘  └─────────────────────┘ │
│  ┌───────────────────────────────────────────────────────┐ │
│  │ V11 Bridge → HyperFrames CLI → MP4                    │ │
│  └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
                         │
                    本地文件系统
            studio-projects/<project_id>/
              ├── plan.json        (项目数据)
              ├── assets/          (图片、音频)
              └── exports/         (输出视频)

3.1 前端:三栏布局 + 状态驱动

前端采用经典的三栏工作流:

左栏 - 场景列表(Scene List)

  • 显示所有分镜的缩略标题
  • 支持拖拽排序、添加/删除/复制
  • 每个分镜显示口播文本预览
中栏 - 预览播放器(Scene Player)
  • 基于 requestAnimationFrame 的时间轴驱动
  • 自适应缩放(ResizeObserver),适配不同屏幕尺寸
  • 三层叠加:BackgroundLayer → MgOverlayLayer → SubtitleLayer
  • 音频同步(HTML5 Audio API)
右栏 - 属性检查器(Scene Inspector)
  • 根据选中面板动态渲染不同的编辑器
  • BackgroundPanel:选择图片/HTML模板
  • NarrationPanel:编辑口播文本
  • TtsPanel:选择语音、语速、音调
  • SubtitlePanel:字幕样式配置
  • MgOverlayPanel:MG弹窗的内容、位置、动画
状态管理 使用 Zustand 三个Store:
  • useProjectStore:项目数据(Plan)、自动保存(800ms防抖)
  • usePlayerStore:播放状态、当前时间、播放/暂停
  • useUiStore:UI状态(面板展开、对话框、主题)

3.2 后端:Service + Registry 分层

后端采用清晰的分层架构:

数据层

  • PlanStore:基于本地JSON文件的CRUD,每个项目一个目录
  • plan_schema.py:Pydantic v2 强类型模型,Plan v2 Schema
服务层
  • SceneService:分镜的CRUD、排序、Overlay管理
  • ScriptService:脚本导入、AI拆分、审核门
  • MediaService:图像生成、TTS、HTML渲染
提供者注册表(Registry Pattern) 这是后端最有意思的设计。所有外部AI服务都通过注册表管理:

class ImageRegistry:
    def __init__(self, providers: list):
        self.providers = {provider.name: provider for provider in providers}

# 初始化时注入所有Provider
image_registry = ImageRegistry([
    GeminiBananaProvider(),
    BailianWanxProvider(),
    StableDiffusionProvider(),
])

同理有 TtsRegistryHtmlRegistry。这种设计让新增Provider变得非常简单——实现一个BaseProvider接口,注册到Registry即可。

导出管线

Plan (Python Pydantic Model)
  ↓ V11Bridge.materialize_export_project()
HTML+iframe+GSAP 合成项目
  ↓ HyperFrames CLI render()
MP4 视频文件

---

四、核心设计思想拆解

4.1 "Plan v2":一切围绕一个JSON

整个项目的核心数据模型是一个Pydantic Schema:Plan v2

class Plan(BaseModel):
    schema_version: Literal[2] = 2
    global_settings: GlobalSettings
    scenes: list[Scene]
    script_review_draft: ScriptReviewDraft | None = None

GlobalSettings 包含:

  • 项目元数据(名称、ID、格式、分辨率、帧率)
  • 默认语音(Edge TTS的Voice ID)
  • 主题配置
  • AI模型设置(LLM、图像Provider、脚本拆分模型)
Scene 是一个分镜的完整描述:
  • scene_id, scene_title, scene_kicker, scene_summary
  • background:image(AI生成图)或 html(HTML模板)
  • narration_text:口播原文
  • narration_segments:分段口播(带时间戳)
  • tts_config:语音配置
  • audio:TTS生成的音频文件路径、时长、逐字时间戳
  • subtitle_config:字幕样式
  • mg_overlays:MG弹窗列表(标题、内容、位置、出现时机、动画)
为什么这个设计重要?

因为所有功能——编辑、预览、导出、AI辅助——都操作同一个数据模型。没有数据库迁移问题,没有ORM复杂度,没有数据不一致风险。

项目数据就是一个JSON文件 + 资产文件夹。你可以用Git管理版本,可以用Python脚本批量处理,可以写插件扩展。

4.2 "时间轴解析":自动计算一切时机

timing.py 里的 resolve_timeline() 是核心算法:

def resolve_timeline(plan: Plan) -> Plan:
    cursor = 0.0
    for scene in plan.scenes:
        # Scene时长 = 音频时长(或默认3秒)
        duration = max(scene.audio.duration_seconds or 3.0, 1.2)
        scene.scene_start_seconds = cursor
        scene.scene_duration_seconds = duration
        cursor += duration

        # Segment时间分配:按文本长度加权
        total_weight = sum(segment_weight(seg.voiceover_text) for seg in segments)
        for segment in segments:
            segment.start_seconds = inner_cursor
            inner_cursor += usable * (segment_weight / total_weight)

        # Overlay出现时机:基于segment时间自动计算
        for overlay in scene.mg_overlays:
            _resolve_overlay(overlay, segment_map, duration, reveal_lead)

这个设计很聪明:

1. Scene时长由音频决定:口播多长,分镜就多长。不需要手动设置。 2. Segment按文本长度分配时间:口播文本越长,分配的时间越多。 3. Overlay自动对齐Segment:MG弹窗的出现时机,基于它所关联的Segment的start时间,减去一个reveal_lead(提前量)。

这意味着:你改了口播文本,整个时间轴自动重算。你调整了Segment顺序,Overlay自动跟随。不需要手动拖拽时间轴。

4.3 "V11 Bridge":从数据模型到视频文件

导出管线的核心是 V11Bridge,它把Plan序列化为一个可渲染的Web项目

每个Scene → 一个独立的HTML文件:

  • 如果是HTML背景:使用模板渲染(cover、bullents、timeline等)
  • 如果是图片背景:用 标签
  • 注入字幕层(基于WordTimestamp的逐词高亮)
  • 注入MG弹窗层(基于reveal_at_seconds的显隐控制)
然后生成 index.html,用GSAP Timeline驱动所有Scene的iframe:

<main class="composition" data-duration="total_duration">
  <iframe class="scene-frame" src="scenes/scene_1.html" data-start="0" data-duration="7.5">
  <iframe class="scene-frame" src="scenes/scene_2.html" data-start="7.5" data-duration="5.2">
  <!-- ... -->
  <audio class="clip" src="assets/audio/scene_1.mp3" data-start="0" data-duration="7.5">
</main>

<script>
  // GSAP Timeline 驱动整体时间轴
  const rootTimeline = gsap.timeline({ paused: true });
  
  // 通过 postMessage 同步每个iframe的局部时间
  function syncSceneIframes() {
    const time = rootTimeline.time();
    document.querySelectorAll(".scene-frame").forEach(frame => {
      const localTime = Math.max(0, Math.min(duration, time - start));
      frame.contentWindow.postMessage({ type: "studio:set-time", time: localTime }, "*");
    });
  }
</script>

这个设计有几个好处:

1. Scene之间完全隔离:每个Scene是独立的HTML,不会互相影响。 2. 渲染引擎无关:HyperFrames只需要渲染一个普通的网页,不需要理解复杂的视频合成格式。 3. 可调试:你可以直接用浏览器打开index.html,用GSAP的调试工具查看时间轴。 4. 可扩展:如果你想自定义Scene的动画逻辑,直接改HTML模板就行。

4.4 "AI脚本审核门":人在回路中

这是产品层面很用心的设计。

当你导入一篇长文案,选择"AI拆分"时,流程不是直接生成分镜,而是:

文案 → AI拆分为Scene Specs → 生成ScriptReviewDraft → 人工审核 → 确认/修改/丢弃 → 生成分镜

ScriptReviewDraft 包含:

  • 原始文案
  • AI生成的Scene列表(标题、摘要、口播、建议布局)
  • 信息池(每段的关键信息点)
  • 演示计划(建议的视觉呈现方式)
用户可以在确认前查看、编辑每个Scene的内容。这避免了"AI黑盒生成一堆我不满意的东西"的问题。

4.5 "Provider注册表":解耦AI依赖

后端通过注册表模式,把所有外部AI服务抽象为统一的接口:

# Image Provider接口
class BaseImageProvider:
    name: str
    requires_env: list[str]
    def is_available(self) -> bool: ...
    async def generate(self, prompt: str, **kwargs) -> bytes: ...

# 具体实现
class GeminiBananaProvider(BaseImageProvider): ...
class BailianWanxProvider(BaseImageProvider): ...
class StableDiffusionProvider(BaseImageProvider): ...

用户可以在设置里切换Provider,系统会自动检测哪些Provider可用(检查环境变量)。

同样的模式用于:

  • TTS(目前只有Edge TTS,但架构预留了扩展)
  • HTML模板(cover、bullents、timeline等Layout)
  • AI脚本拆分(任何OpenAI-compatible API)
---

五、前端技术细节

5.1 ScenePlayer:RAF驱动的播放器

// 播放逻辑:RAF tick
const tick = (now: number) => {
  const delta = (now - last) / 1000;
  const next = Math.min(duration, currentTime + delta);
  setCurrentTime(next);
  if (next >= duration) {
    pause();
    return;
  }
  rafRef.current = requestAnimationFrame(tick);
};

// 音频同步
useEffect(() => {
  if (audio && Math.abs(audio.currentTime - currentTime) > 0.35) {
    audio.currentTime = currentTime;
  }
}, [currentTime]);

用RAF而不是setInterval,因为RAF和屏幕刷新率同步,动画更平滑。音频通过onTimeUpdate事件同步,但如果偏差超过0.35秒,强制seek。

5.2 自适应缩放

const update = () => {
  const rect = frame.getBoundingClientRect();
  setScale(Math.min(
    rect.width / settings.resolution.width,
    rect.height / settings.resolution.height
  ));
};
const observer = new ResizeObserver(update);
observer.observe(frame);

播放器容器大小变化时,自动计算scale,保持16:9或9:16的宽高比。这是响应式设计的关键——你在笔记本上编辑,在手机上预览,画面比例不会变形。

5.3 自动保存:800ms防抖

patchPlan: (updater) => {
  const current = structuredClone(get().plan);
  updater(current);
  set({ plan: current, dirty: true });
  window.clearTimeout(saveTimer);
  saveTimer = window.setTimeout(() => get().saveNow(), 800);
},

每次编辑后800ms自动保存。用structuredClone深拷贝,避免直接修改状态。dirty标志显示未保存状态。

---

六、后端技术细节

6.1 Pydantic v2:类型即文档

整个后端大量使用Pydantic v2:

class Scene(BaseModel):
    scene_id: str
    scene_title: str
    narration_text: str
    background: Background = Field(default_factory=Background)
    # ...

API的Request/Response、数据模型、配置文件,全部用Pydantic。类型定义即API文档,即验证逻辑,即序列化规则。

6.2 本地文件存储

class PlanStore:
    def load(self, pid: str) -> Plan:
        path = self.project_dir(pid) / "plan.json"
        return Plan.model_validate_json(path.read_text())

    def save(self, pid: str, plan: Plan) -> Plan:
        path = self.project_dir(pid) / "plan.json"
        path.write_text(plan.model_dump_json(indent=2))
        return plan

没有数据库。项目数据就是JSON文件,资产就是文件系统。简单、可移植、可版本控制。

6.3 任务队列:异步导出

class ExportRunner(ProjectJobRunner):
    async def run(self, job_id: str, scene_ids, quality):
        # 1. 解析时间轴
        plan = resolve_timeline(self.store.load(project_id))
        # 2. 序列化为HyperFrames项目
        self.bridge.materialize_export_project(plan, project_dir, export_dir)
        # 3. 调用HyperFrames CLI渲染
        await self.hyperframes.render(export_dir, output_mp4, fps, quality, on_progress)

导出是一个异步任务,通过JobsStore管理状态(queued → running → success/failed)。前端可以轮询进度。

---

七、HyperFrames:视频渲染引擎

AI Video Studio 本身不处理视频编码,而是委托给 HyperFrames CLI。

HyperFrames 的职责: 1. 加载V11 Bridge生成的HTML项目 2. 用Headless Browser(Playwright/Puppeteer)渲染每一帧 3. 用FFmpeg编码为MP4

这种"Web-to-Video"的架构很巧妙:

  • 前端预览和最终渲染,用的是同一套HTML+CSS+GSAP代码
  • 你看到的就是你得到的(WYSIWYG)
  • 可以充分利用Web生态的动画、字体、布局能力
V11 Bridge 在导出时设置了一个关键环境变量:
env["PRODUCER_ENABLE_STREAMING_ENCODE"] = "false"

这关闭了流式编码,改用"capture-then-encode"路径——先逐帧截图,再编码为视频。更慢但更稳定,适合iframe/screenshot合成场景。

---

八、设计哲学的五个关键词

1. 本地优先(Local-First)

数据存在本地,不依赖云服务。你可以离线工作,可以用Git管理版本,不用担心隐私泄露。

2. 分镜思维(Scene-Based)

不是"时间轴+轨道"的传统剪辑逻辑,而是"分镜卡片+属性面板"的导演逻辑。每个分镜是一个独立的叙事单元。

3. 人在回路(Human-in-the-Loop)

AI负责"建议",人负责"决策"。脚本拆分有审核门,每个Scene可以独立调整,AI生成的东西都可以覆盖。

4. 可扩展(Pluggable)

Provider注册表让替换AI服务变得简单。今天用Gemini生图,明天可以切到SD,不改业务代码。

5. 成本可控(Cost-Effective)

  • Edge TTS:免费
  • Gemini Nano Banana:低成本图像生成
  • 本地运行:没有订阅费
  • 开源:代码可以自己改
---

九、局限与未来

当前局限

1. HyperFrames依赖:视频导出需要HyperFrames CLI,这不是开源组件。如果HyperFrames不公开或收费,导出功能会受限。 2. 动画模板有限:目前HTML模板主要是静态布局+简单动画(fade、rise、zoom)。复杂的MG动画需要手动编写HTML/CSS。 3. 视频生成未集成:目前只支持图片背景,不支持AI视频(如Runway、可灵)作为背景。 4. 桌面版打包:Electron桌面版已包含,但FFmpeg和HyperFrames仍需用户自行安装。

可能的扩展方向

1. 更多Provider:接入更多的TTS(如OpenAI TTS、ElevenLabs)、图像(Midjourney API、Leonardo)、视频(Runway、Pika) 2. 动画模板市场:让用户提交和分享自定义HTML模板 3. 协作功能:基于Git的版本控制 + 多人协作编辑 4. 插件系统:允许第三方开发插件扩展功能

---

十、总结

AI Video Studio 不是又一个"AI一键生成视频"的玩具,而是一个严肃的生产力工具。它的目标用户很明确:知识博主、演讲者、内容创作者——那些需要把"文章"变成"视频"的人。

它的架构设计有几个值得学习的地方:

1. 单一数据源(Plan JSON):前后端共享同一个强类型Schema,没有数据同步问题。 2. 时间轴自动解析:基于音频时长和文本长度自动计算时间,减少手动调整。 3. Web-to-Video管线:用HTML+CSS+GSAP做视频合成,充分利用Web生态。 4. Provider注册表:解耦AI服务,让切换和扩展变得容易。 5. AI审核门:人在回路中,避免黑盒生成。

如果你也在做AI视频工具,这个项目值得仔细研究。它的代码量不大(前端+后端约1万行左右),但架构清晰,设计用心。

---

参考

  • GitHub: https://github.com/WoyouWoyou/ai-video-studio
  • 夸克网盘: https://pan.quark.cn/s/3e62fff831e3(提取码: iycv)
  • 移动云盘: https://yun.139.com/shareweb/#/w/i/2v3EhsXDCvfn2(提取码: k75g)
#项目拆解 #AI视频 #开源工具 #视频工作台 #FastAPI #React #HyperFrames #内容创作

暂无表态
💬 讨论回复 (0)
推荐

🌟 智谱 GLM-5 已上线

我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。

🎁 领取 2000万 Tokens