AI-video-lifeplan-demo/.qoder/repowiki/zh/content/架构设计/视频渲染/数据契约.md

8.3 KiB
Raw Blame History

数据契约

**本文档中引用的文件** - [render-props-types.ts](file://frontend/src/render-props-types.ts) - [data_builder.py](file://backend/data_builder.py) - [mock-data.json](file://src/mock-data.json) - [mock-cashflow.json](file://src/mock-cashflow.json) - [Root.tsx](file://src/Root.tsx)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构概述
  5. 详细组件分析
  6. 依赖分析
  7. 性能考虑
  8. 故障排除指南
  9. 结论

简介

本文件详细描述了视频渲染系统的数据契约,重点是 render-props-types.ts 中定义的 RenderProps 接口及其 Zod 验证模式。该数据契约作为 Python 后端(数据生成器)与 Remotion 前端(视频渲染器)之间的通信桥梁,确保了 render_props.json 文件在运行时的类型安全。文档还结合 backend/data_builder.py 的输出结构,说明了如何同步维护前后端的数据模型。

项目结构

该项目采用前后端分离架构,前端使用 Remotion 框架进行视频渲染,后端使用 Python 生成渲染所需的数据。核心数据契约定义在 frontend/src/render-props-types.ts 中,而后端数据生成逻辑位于 backend/data_builder.py。

graph TB
subgraph "前端 (Remotion)"
A[render-props-types.ts] --> B[Root.tsx]
B --> C[CashFlowChart]
B --> D[LifePlanChart]
B --> E[DualChartView]
end
subgraph "后端 (Python)"
F[data_builder.py] --> G[FinancialSimulator]
G --> H[build_chart_data]
end
F --> |生成 render_props.json| A

图表来源

章节来源

核心组件

RenderProps 接口是整个系统的核心数据模型,它定义了渲染视频所需的所有数据结构,包括元信息、图表数据、脚本和资产引用。YearlySnapshot 和 CashFlowData 是构成财务模拟数据的基础类型,而 ScriptSegment 和 AssetCollection 则用于控制视频的叙事和媒体资源。

章节来源

架构概述

系统的数据流始于后端的 data_builder.py。FinancialSimulator 类根据用户输入的财务参数(如当前年龄、退休年龄、资产、收入和支出)模拟未来每年的财务状况,生成 YearlySnapshot 数据。然后,build_cashflow_data 函数将这些数据转换为更详细的 CashFlowData 格式。最终,build_chart_data 函数将这些数据组织成 render_props.json 的标准格式,供前端使用。

sequenceDiagram
participant Backend as "后端 (data_builder.py)"
participant Frontend as "前端 (Remotion)"
participant Data as "render_props.json"
Backend->>Backend : FinancialSimulator.simulate_timeline()
Backend->>Backend : build_cashflow_data()
Backend->>Backend : build_chart_data()
Backend->>Data : 生成 render_props.json
Data->>Frontend : 加载数据
Frontend->>Frontend : validateRenderProps() 验证
Frontend->>Frontend : 渲染视频

图表来源

详细组件分析

RenderProps 接口分析

RenderProps 接口是数据契约的顶层结构,它包含四个主要部分:meta、charts、script 和 assets。

classDiagram
    class RenderProps {
        +meta : Meta
        +charts : Charts
        +script : ScriptSegment[]
        +assets : AssetCollection
    }
    class Meta {
        +title : string
        +currencyUnit : string
        +duration : number
        +clientName? : string
        +generatedAt? : string
    }
    class Charts {
        +assetDepletion : AssetDepletionChartData
        +cashFlow : CashFlowChartData
    }
    class AssetDepletionChartData {
        +timeline : YearlySnapshot[]
    }
    class CashFlowChartData {
        +timeline : CashFlowData[]
    }
    class YearlySnapshot {
        +currencyUnit : string
        +startYear : number
    }
    class CashFlowData {
        +currencyUnit : string
    }
    RenderProps --> Meta
    RenderProps --> Charts
    Charts --> AssetDepletionChartData
    Charts --> CashFlowChartData
    AssetDepletionChartData --> YearlySnapshot
    CashFlowChartData --> CashFlowData

图表来源

核心数据类型分析

YearlySnapshot 和 CashFlowData 是系统中最核心的两个数据类型,它们分别代表了资产消耗和现金流的年度数据。

classDiagram
    class YearlySnapshot {
        +year : number
        +ages_rep : number
        +ages_spouse? : number
        +financials_income : number
        +financials_expenditure : number
        +financials_assetBalance : number
        +events? : string[]
        +isCritical? : boolean
    }
    class CashFlowData {
        +year : number
        +age : number
        +income_total : number
        +expenses_living : number
        +expenses_housing : number
        +expenses_education : number
        +expenses_tax : number
        +expenses_event : number
        +totalExpense? : number
        +netCashFlow? : number
        +assetBalance? : number
    }
    YearlySnapshot --> "1" AssetDepletionChartData : "包含"
    CashFlowData --> "1" CashFlowChartData : "包含"

图表来源

脚本与资产分析

ScriptSegment 定义了视频的叙事结构,而 AssetCollection 则管理了视频中使用的所有媒体资源。

classDiagram
class ScriptSegment {
+id : number
+text : string
+duration : number
+type : ScriptSegmentType
+assetUrl? : string
+chartSync? : ChartSync
}
class ChartSync {
+chartId : "assetDepletion" | "cashFlow"
+highlightYear? : number
+animationStart? : number
}
class AssetCollection {
+broll : Record<string, string>
+videoClips : VideoClipReference[]
+ttsAudio? : string
}
class VideoClipReference {
+id : string
+sourcePath : string
+startTime : number
+duration : number
+outputPath? : string
}
ScriptSegment --> ChartSync
AssetCollection --> VideoClipReference

图表来源

依赖分析

该系统的关键依赖是 zod 库,它用于在运行时验证 render_props.json 的数据结构。render-props-types.ts 中的 RenderPropsSchema 确保了从后端传来的数据符合预期的格式,防止了因数据错误导致的渲染失败。

graph TD
A[render-props-types.ts] --> B[zod]
B --> C[RenderPropsSchema]
C --> D[validateRenderProps]
C --> E[isRenderProps]
F[data_builder.py] --> A
A --> G[Root.tsx]

图表来源

章节来源

性能考虑

Zod 的运行时验证虽然增加了少量开销,但极大地提高了系统的健壮性。对于大型数据集,可以考虑在开发环境中进行严格验证,在生产环境中使用 isRenderProps 进行轻量级检查,以平衡安全性和性能。

故障排除指南

当视频渲染失败时,最常见的原因是 render_props.json 数据格式错误。应首先使用 validateRenderProps 函数检查数据的有效性。如果验证失败,Zod 会提供详细的错误信息,指出具体是哪个字段不符合预期。

章节来源

结论

该视频渲染系统的数据契约设计清晰,通过 TypeScript 接口和 Zod 模式实现了前后端之间的强类型通信。RenderProps 接口及其子类型构成了一个完整、可扩展的数据模型,能够支持复杂的财务模拟和视频叙事。通过 validateRenderProps 和 isRenderProps 辅助函数,系统在运行时具备了强大的数据验证能力,确保了渲染过程的稳定性和可靠性。