Files
oak-editor/docs/zh/project-file-reference.md
T
2026-01-05 16:22:26 +08:00

6.7 KiB
Raw Blame History

Oak Video Editor 项目文件参考手册(详细版)

本文档基于当前源代码实现,描述 Oak Video Editor 的 XML 项目文件格式,目标是足够详细以实现兼容读写器。

代码来源:app/node/project.cppapp/node/node.cppapp/node/value.*app/node/keyframe.*app/node/project/serializer/*

1. 根元素

<olive version="230220" url="/path/to/project.ove">
  ...
</olive>
  • version:序列化版本号(YYMMDD)。
  • url:可选的项目文件路径。

2. 项目容器

完整保存时,会有 project 容器:

<project>
  <project>...</project>
  <layout>...</layout>
</project>
  • 内层 <project>:项目数据。
  • <layout>:界面布局(MainWindowLayoutInfo::fromXml)。

3. 项目数据(Project::Save

<project version="1">
  <uuid>...</uuid>
  <plugins>...</plugins>
  <nodes>...</nodes>
  <settings>...</settings>
</project>

3.1 uuid

项目 UUIDQUuid 字符串)。

3.2 plugins

项目中使用的 OpenFX 插件列表,用于加载节点前补充插件搜索路径。

<plugins>
  <plugin id="com.vendor.Plugin" major="1" minor="2"
          bundle="/path/to/Plugin.ofx.bundle"
          file="/path/to/Plugin.ofx.bundle/Contents/MacOS/Plugin" />
</plugins>

属性:

  • idOFX 插件标识符(与节点 id 相同)。
  • major / minor:插件版本。
  • bundle:插件 bundle 目录路径(优先使用)。
  • file:插件二进制路径(备用)。

加载策略:

  • 若存在 <plugins>,先把 bundle(或 file)加入 OFX 搜索路径并扫描,然后注册插件节点,再进入 <nodes> 解析。

3.3 nodes

节点图,节点由 Node::Save() 写出:

<nodes version="1">
  <node version="1" id="node.id" ptr="123456">
    <label>...</label>
    <color>...</color>
    <input>...</input>
    <links>...</links>
    <connections>...</connections>
    <hints>...</hints>
    <context>...</context>
    <caches>...</caches>
    <custom>...</custom>
  </node>
</nodes>

关键属性:

  • id:节点类型标识。OpenFX 节点为插件标识符。
  • ptr:序列化指针 ID,用于恢复连接与位置。
  • version:当前为 1

3.4 settings

项目设置,键值对形式保存:

已知键:

  • cachesetting
  • customcachepath
  • colorconfigfilename
  • defaultinputcolorspace
  • colorreferencespace
  • root

4. 节点序列化(Node::Save / Node::Load

4.1 label

节点显示名。

4.2 color

节点覆盖颜色(整数索引)。

4.3 input

每个输入:

<input id="InputId">
  <primary>...</primary>
  <subelements count="N">
    <element>...</element>
  </subelements>
</input>
  • primary:主元素(element = -1)。
  • subelements:数组输入,count 为数组长度。

4.3.1 立即值结构(primary / element

<keyframing>0|1</keyframing>
<standard>
  <track>...</track>
</standard>
<keyframes>
  <track>
    <key ...>...</key>
  </track>
</keyframes>
<csinput>...</csinput>
<csdisplay>...</csdisplay>
<csview>...</csview>
<cslook>...</cslook>
  • keyframing:是否启用关键帧(仅在输入可关键帧时写出)。
  • standard:默认值(每条 track 一份)。
  • keyframes:仅当 keyframing=1 时写出。
  • cs*:仅用于 kColor,保存色彩管理信息。

4.3.2 Track 数量

NodeValue::get_number_of_keyframe_tracks() 决定:

类型 Track 数量
kVec2 2
kVec3 3
kVec4 4
kColor 4
kBezier 6
其他 1

4.3.3 标准值编码

NodeValue::ValueToString() 写出,NodeValue::StringToValue() 读入:

  • kVec2: x:y
  • kVec3: x:y:z
  • kVec4: x:y:z:w
  • kColor: r:g:b:a
  • kBezier: x:y:cp1x:cp1y:cp2x:cp2y
  • kRational: num/den
  • kInt: 整数文本
  • kBinary: Base64
  • kText / kFont / kFile / kCombo / kStrCombo: 纯文本
  • kTexture / kSamples / kNone: 无文本

特殊情况:

  • kVideoParams / kAudioParams 以子对象形式保存(见第 5/6 节)。
  • kSubtitleParams 在加载时被跳过(避免覆盖实际字幕数据)。

4.3.4 关键帧(NodeKeyframe::save

<key input="InputId" time="num/den" type="0" inhandlex="0" inhandley="0" outhandlex="0" outhandley="0">value</key>
  • input:输入 ID。
  • time:理性时间。
  • type:关键帧类型枚举值。
  • inhandlex / inhandley / outhandlex / outhandley:贝塞尔控制点。

文本值使用 NodeValue::ValueToString(data_type, value, true)

节点间的“块”链接:

<links>
  <link>ptr</link>
</links>

4.5 connections

输入/输出连接:

<connections>
  <connection input="InputId" element="-1">
    <output>ptr</output>
  </connection>
</connections>

4.6 hints(输入提示)

<hints>
  <hint input="InputId" element="-1" version="1">
    <types>
      <type>...</type>
    </types>
    <index>0</index>
    <tag>...</tag>
  </hint>
</hints>

4.7 context(节点位置)

<context>
  <node ptr="other_node_ptr">
    <x>0</x>
    <y>0</y>
    <expanded>0|1</expanded>
  </node>
</context>

4.8 caches

<caches>
  <audio>uuid</audio>
  <video>uuid</video>
  <thumb>uuid</thumb>
  <waveform>uuid</waveform>
</caches>

4.9 custom

节点自定义内容,默认实现为空;各子类可覆盖。

5. VideoParams

kVideoParams 输入以子对象保存:

<width>...</width>
<height>...</height>
<depth>...</depth>
<timebase>num/den</timebase>
<format>int</format>
<channelcount>int</channelcount>
<pixelaspectratio>num/den</pixelaspectratio>
<interlacing>int</interlacing>
<divider>int</divider>
<enabled>0|1</enabled>
<x>float</x>
<y>float</y>
<streamindex>int</streamindex>
<videotype>int</videotype>
<framerate>num/den</framerate>
<starttime>int64</starttime>
<duration>int64</duration>
<premultipliedalpha>0|1</premultipliedalpha>
<colorspace>string</colorspace>
<colorrange>int</colorrange>

6. AudioParams

kAudioParams 输入以子对象保存:

<samplerate>int</samplerate>
<channellayout>uint64</channellayout>
<format>string</format>
<enabled>0|1</enabled>
<streamindex>int</streamindex>
<duration>int64</duration>
<timebase>num/den</timebase>

7. 部分保存

序列化器支持写出部分数据:

  • <markers>
  • <keyframes>
  • <nodes>(子集)

8. OpenFX 插件兼容

  • OpenFX 节点 id 等于插件标识符。
  • <plugins> 记录插件路径,加载时会先扫描并注册插件节点。
  • 插件缺失时节点无法实例化并被跳过。

9. 版本兼容

  • 根元素 version 决定使用哪个序列化器。
  • 若缺少对应版本,会报 kProjectTooNewkProjectTooOld