03-data-contracts

数据契约

article-slide-video 的稳定性来自文件契约。每个阶段只消费上游明确产物,并把自己的产物写回输出目录。

voiceover.md

来源:voiceover-editor

用途:冻结后的唯一口播文本来源。

格式要求:

  • Markdown 文件。
  • 不带 frontmatter。
  • 第一行为不参与朗读的 H1 标题。
  • 后续正文使用自然段。
  • 不包含未经确认的新事实。

关键约束:后续阶段不得直接回到原文重新解释内容。需要改内容时,必须先修改并重新冻结 voiceover.md。

narration-plan.json

来源:slide-narration-planner

用途:定义页面、口播片段和页面停顿。

典型结构:

{
  "schema_version": 1,
  "title": "标题",
  "slides": [
    {
      "slide_id": "slide-01",
      "segments": [
        {
          "segment_id": "slide-01-segment-01",
          "text": "这一页的口播正文。",
          "break_after": 0.4
        }
      ]
    }
  ]
}

字段约束:

  • schema_version 固定为 1。
  • slides 必须是非空数组。
  • slide_id 唯一,格式匹配 ^slide-[a-z0-9][a-z0-9_-]*$。
  • segment_id 唯一。
  • text 不能为空。
  • break_after 范围为 0 到 0.5 秒。

设计含义:它既是分页计划,也是后续 deck 和 TTS 的对齐基准。

deck-manifest.json

来源:HTML 幻灯片生成器,例如 frontend-slides。

用途:告诉视频交付阶段如何加载 HTML、画布尺寸是多少、有哪些页面需要渲染。

标准结构:

{
  "schema_version": 1,
  "generator": "frontend-slides",
  "entry": "deck.html",
  "canvas": { "width": 1920, "height": 1080 },
  "slides": [
    { "slide_id": "slide-01", "settle_ms": 250 }
  ]
}

字段约束:

  • entry 必须是非空相对路径。
  • entry 解析 .. 和软链接后仍必须位于 manifest 所在目录内。
  • entry 必须指向 HTML 文件。
  • canvas 默认使用 1920×1080。
  • slide_id 必须与 narration-plan.json 完全一致。
  • settle_ms 表示切页后截图前等待布局稳定的时间,默认通常为 250 毫秒。

设计含义:视频渲染器只读 manifest 和浏览器桥接,不依赖生成器内部实现。

tts-manifest.json

来源:bytedance-tts

用途:记录完整音频、采样率、总时长、每段口播在时间线中的位置。

典型结构:

{
  "schema_version": 1,
  "audio": {
    "path": "voiceover.wav",
    "sample_rate": 24000,
    "duration": 12.34
  },
  "slides": [
    {
      "slide_id": "slide-01",
      "segments": [
        {
          "segment_id": "slide-01-segment-01",
          "text": "这一页的口播正文。",
          "start": 0.0,
          "audio_duration": 2.8,
          "break_after": 0.4,
          "end": 3.2
        }
      ]
    }
  ],
  "usage": { "text_words": 42 }
}

字段含义:

  • audio.path 指向完整音频文件。
  • audio.duration 是包含静音停顿后的总时长。
  • start 是片段在完整时间线中的开始时间。
  • audio_duration 是 TTS 实际发声时长。
  • break_after 是片段后的静音停顿。
  • end 是发声加停顿后的结束时间。

设计含义:视频合成、字幕生成和 QA 抽帧都以这条实际音频时间线为准。

delivery-report.json

来源:slide-video-delivery

用途:记录最终媒体参数、逐片段 QA 帧和人工视觉检查状态。

典型字段:

{
  "schema_version": 1,
  "video": "/absolute/path/final-subtitled.mp4",
  "expected_duration": 12.34,
  "actual_duration": 12.33,
  "resolution": { "width": 1920, "height": 1080 },
  "has_video": true,
  "has_audio": true,
  "checked_segments": 4,
  "segments": [
    {
      "segment_id": "slide-01-segment-01",
      "slide_id": "slide-01",
      "timestamp": 1.4,
      "frame": "segment-001-slide-01.png",
      "visual_status": "passed"
    }
  ],
  "cover_landscape_status": "passed",
  "cover_portrait_status": "passed",
  "subtitle_status": "passed"
}

设计含义:交付完成不是“脚本跑完”,而是所有机器可校验项和人工视觉项都完成并标记为 passed。

Comments

Popular posts from this blog

How to turn off Sass warning prompts in Nuxt.js projects

Configuring SSH Access to a Docker Container via an Alternative Port

Quickly Set Up a Cloud Database Using MongoDB Atlas