- media color primaries/transfer tags now flow from the FFmpeg probe through VideoParams into Footage::get_colorspace_to_use(); precedence is user override > media tags > project default - export nclc tags derive from the output colorspace (PQ/HLG/BT.2020, P3, sRGB, Rec.601, Rec.709) instead of hardcoded BT.709 - new OCIO Color Grading (Log) node (lift/gamma/gain) and White Balance node (kelvin temperature + tint, HDR-safe) - LUT whitelist extended to 9 OCIO-supported formats - waveform scope gains an RGB parade mode (GPU and software paths) - tests updated for the new colorspace precedence
672 lines
22 KiB
Markdown
672 lines
22 KiB
Markdown
# Oak Video Editor Project File Reference / Oak 视频编辑器项目文件格式参考
|
||
|
||
This document describes Oak Video Editor's XML project format (`.ove`) as implemented in the current codebase. It is intended to be detailed enough to implement a compatible reader/writer.
|
||
|
||
本文件描述 Oak 视频编辑器当前代码库实现的 XML 项目格式(`.ove`),详细程度足以支持兼容的读写实现。
|
||
|
||
> Source of truth / 权威源码:`app/node/project.cpp`, `app/node/node.cpp`, `app/node/value.*`, `app/node/keyframe.*`, `app/node/project/serializer/*`, `app/node/project/footage/footage.cpp`, `app/node/output/viewer/viewer.cpp`, `app/node/output/track/track.cpp`, `app/node/group/group.cpp`, `app/window/mainwindow/mainwindowlayoutinfo.cpp`.
|
||
|
||
---
|
||
|
||
## 1. Root Document / 根文档
|
||
|
||
```xml
|
||
<olive version="230220" url="/path/to/project.ove">
|
||
...
|
||
</olive>
|
||
```
|
||
|
||
- `version`: serializer version in `YYMMDD` format. The latest serializer is `230220` (`ProjectSerializer230220`).
|
||
- `version`:序列化器版本,格式为 `YYMMDD`。当前最新为 `230220`(`ProjectSerializer230220`)。
|
||
- `url`: optional source path.
|
||
- `url`:可选的源文件路径。
|
||
|
||
---
|
||
|
||
## 2. Project Container / 项目容器
|
||
|
||
For full saves, the serializer writes a project container:
|
||
|
||
完整保存时,序列化器会写入一个项目容器:
|
||
|
||
```xml
|
||
<project>
|
||
<project>...</project> <!-- actual project data / 实际项目数据 -->
|
||
<layout>...</layout> <!-- UI layout / 用户界面布局 -->
|
||
</project>
|
||
```
|
||
|
||
See `ProjectSerializer230220::Save()` and `Load()` in `app/node/project/serializer/serializer230220.cpp`.
|
||
|
||
---
|
||
|
||
## 3. Project Data (`Project::Save` / `Project::Load`) / 项目数据
|
||
|
||
```xml
|
||
<project version="1">
|
||
<uuid>...</uuid>
|
||
<plugins>...</plugins>
|
||
<nodes>...</nodes>
|
||
<settings>...</settings>
|
||
</project>
|
||
```
|
||
|
||
### 3.1 `uuid`
|
||
- QUuid string identifying the project.
|
||
- 项目 UUID 字符串。
|
||
|
||
### 3.2 `plugins` / 插件列表
|
||
|
||
List of OpenFX plugins referenced by nodes. This block is loaded **before** `<nodes>` so that plugin nodes can be registered.
|
||
|
||
列出节点引用的 OpenFX 插件。该块在 `<nodes>` 之前加载,以便注册插件节点。
|
||
|
||
```xml
|
||
<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>
|
||
```
|
||
|
||
Attributes / 属性:
|
||
- `id`: OFX plugin identifier (matches node `id`).
|
||
- OFX 插件标识符(与节点 `id` 一致)。
|
||
- `major` / `minor`: OFX plugin version.
|
||
- OFX 插件版本。
|
||
- `bundle`: bundle directory path (preferred).
|
||
- 包目录路径(优先使用)。
|
||
- `file`: plugin binary path (fallback).
|
||
- 插件二进制路径(回退)。
|
||
|
||
Loading behavior / 加载行为:
|
||
- If `<plugins>` exists, each `bundle` (or `file` if `bundle` is empty) is added to the OFX plugin path, the cache scans the paths, and plugin nodes are registered before `<nodes>` is parsed.
|
||
- 如果存在 `<plugins>`,则把每个 `bundle`(若 `bundle` 为空则使用 `file`)加入 OFX 插件路径,扫描缓存,并在解析 `<nodes>` 前注册插件节点。
|
||
|
||
### 3.3 `nodes` / 节点图
|
||
|
||
The node graph. Each `<node>` is written by `Node::Save()` and read by `Node::Load()`.
|
||
|
||
节点图。每个 `<node>` 由 `Node::Save()` 写入、`Node::Load()` 读取。
|
||
|
||
```xml
|
||
<nodes version="1">
|
||
<node version="1" id="node.id" ptr="123456">
|
||
<label>Optional Label</label>
|
||
<color>3</color>
|
||
<input>...</input>
|
||
<links>...</links>
|
||
<connections>...</connections>
|
||
<hints>...</hints>
|
||
<context>...</context>
|
||
<caches>...</caches>
|
||
<custom>...</custom>
|
||
</node>
|
||
</nodes>
|
||
```
|
||
|
||
Attributes / 属性:
|
||
- `id`: node type identifier. For OpenFX nodes, this equals the OFX plugin identifier.
|
||
- 节点类型标识符。对于 OpenFX 节点,等于 OFX 插件标识符。
|
||
- `ptr`: numeric pointer ID used to resolve connections and context positions.
|
||
- 数字指针 ID,用于解析连接和上下文位置。
|
||
- `version`: currently `1`.
|
||
- 当前为 `1`。
|
||
|
||
### 3.4 `settings` / 项目设置
|
||
|
||
Project settings stored as key/value text elements.
|
||
|
||
以键值文本元素保存的项目设置。
|
||
|
||
Known keys / 已知键:
|
||
- `cachesetting`
|
||
- `customcachepath`
|
||
- `colorconfigfilename`
|
||
- `defaultinputcolorspace`
|
||
- `colorreferencespace`
|
||
- `root` — pointer id of the root `Folder` node, resolved after all nodes are loaded.
|
||
- `root`:根 `Folder` 节点的指针 ID,在所有节点加载完成后解析。
|
||
|
||
---
|
||
|
||
## 4. Node Serialization (`Node::Save` / `Node::Load`) / 节点序列化
|
||
|
||
### 4.1 `label`
|
||
User-visible node label.
|
||
用户可见的节点标签。
|
||
|
||
### 4.2 `color`
|
||
Override color index (integer), only written if not `-1`.
|
||
覆盖颜色索引(整数),只有不为 `-1` 时才写出。
|
||
|
||
### 4.3 `input` / 输入
|
||
|
||
Each input is serialized as:
|
||
|
||
每个输入序列化为:
|
||
|
||
```xml
|
||
<input id="InputId">
|
||
<primary>...</primary>
|
||
<subelements count="N">
|
||
<element>...</element>
|
||
</subelements>
|
||
</input>
|
||
```
|
||
|
||
- `primary`: element `-1` (the main input).
|
||
- `primary`:元素 `-1`(主输入)。
|
||
- `subelements`: array elements (if the input is an array). `count` is the array size.
|
||
- `subelements`:数组元素(如果输入是数组)。`count` 为数组大小。
|
||
|
||
#### 4.3.1 Immediate Values (`primary` / `element`) / 立即值
|
||
|
||
Each immediate block contains:
|
||
|
||
每个立即值块包含:
|
||
|
||
```xml
|
||
<keyframing>0|1</keyframing>
|
||
<standard>
|
||
<track>...</track>
|
||
...
|
||
</standard>
|
||
<keyframes>
|
||
<track>
|
||
<key ...>...</key>
|
||
</track>
|
||
</keyframes>
|
||
<csinput>...</csinput>
|
||
<csdisplay>...</csdisplay>
|
||
<csview>...</csview>
|
||
<cslook>...</cslook>
|
||
```
|
||
|
||
- `keyframing`: whether the input is keyframed (only written if the input is keyframable).
|
||
- `keyframing`:输入是否启用关键帧(仅当输入可关键帧化时写出)。
|
||
- `standard`: default/static values (one `<track>` per keyframe track).
|
||
- `standard`:默认值/静态值(每个关键帧轨道一个 `<track>`)。
|
||
- `keyframes`: only written if `keyframing` is true.
|
||
- `keyframes`:仅在 `keyframing` 为 true 时写出。
|
||
- `cs*`: only written for `kColor` inputs; stored as input properties `col_input`, `col_display`, `col_view`, `col_look`.
|
||
- `cs*`:仅对 `kColor` 输入写出;保存为输入属性 `col_input`、`col_display`、`col_view`、`col_look`。
|
||
|
||
#### 4.3.2 Track Count / 轨道数量
|
||
|
||
Track count is determined by `NodeValue::get_number_of_keyframe_tracks()`:
|
||
|
||
轨道数量由 `NodeValue::get_number_of_keyframe_tracks()` 决定:
|
||
|
||
| Type / 类型 | Tracks / 轨道数 |
|
||
| --- | --- |
|
||
| `kVec2` | 2 |
|
||
| `kVec3` | 3 |
|
||
| `kVec4` | 4 |
|
||
| `kColor` | 4 |
|
||
| `kBezier` | 6 |
|
||
| other / 其他 | 1 |
|
||
|
||
#### 4.3.3 Standard Value Encoding / 标准值编码
|
||
|
||
Values are written with `NodeValue::ValueToString()` and read with `NodeValue::StringToValue()`.
|
||
|
||
值通过 `NodeValue::ValueToString()` 写入,通过 `NodeValue::StringToValue()` 读取。
|
||
|
||
String encodings / 字符串编码:
|
||
- `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` (see `rational::toString()`)
|
||
- `kInt`: integer as text / 整数字符串
|
||
- `kBinary`: Base64
|
||
- `kText`, `kFont`, `kFile`, `kCombo`, `kStrCombo`: string
|
||
- `kTexture`, `kSamples`, `kNone`: no text / 无文本
|
||
|
||
Special cases / 特例:
|
||
- `kVideoParams` / `kAudioParams` are nested objects (see sections 5 and 6).
|
||
- `kVideoParams` / `kAudioParams` 为嵌套对象(见第 5、6 节)。
|
||
- `kSubtitleParams` is **skipped on load** to avoid overwriting subtitle data.
|
||
- `kSubtitleParams` 在加载时**被跳过**,以避免覆盖字幕数据。
|
||
|
||
#### 4.3.4 Keyframes (`NodeKeyframe::save` / `NodeKeyframe::load`) / 关键帧
|
||
|
||
```xml
|
||
<key input="InputId" time="num/den" type="0"
|
||
inhandlex="0" inhandley="0"
|
||
outhandlex="0" outhandley="0">value</key>
|
||
```
|
||
|
||
Attributes / 属性:
|
||
- `input`: input id.
|
||
- 输入 ID。
|
||
- `time`: rational time (`rational::toString()`).
|
||
- 有理数时间(`rational::toString()`)。
|
||
- `type`: integer enum `NodeKeyframe::Type` (`0` = linear, etc.).
|
||
- 整数枚举 `NodeKeyframe::Type`(`0` 为线性等)。
|
||
- `inhandlex`, `inhandley`, `outhandlex`, `outhandley`: bezier handle coordinates.
|
||
- 贝塞尔手柄坐标。
|
||
|
||
Text value uses `NodeValue::ValueToString(data_type, value, true)`.
|
||
文本值使用 `NodeValue::ValueToString(data_type, value, true)`。
|
||
|
||
### 4.4 `links` / 链接
|
||
|
||
Block-to-block link list (for timeline items):
|
||
|
||
块到块链接列表(用于时间线项目):
|
||
|
||
```xml
|
||
<links>
|
||
<link>ptr</link>
|
||
</links>
|
||
```
|
||
|
||
### 4.5 `connections` / 连接
|
||
|
||
Input/output connections:
|
||
|
||
输入/输出连接:
|
||
|
||
```xml
|
||
<connections>
|
||
<connection input="InputId" element="-1">
|
||
<output>ptr</output>
|
||
</connection>
|
||
</connections>
|
||
```
|
||
|
||
- `output` is the serialized pointer (`ptr`) of the output node.
|
||
- `output` 为输出节点的序列化指针(`ptr`)。
|
||
|
||
### 4.6 `hints` (Value Hints) / 值提示
|
||
|
||
Value hints are per-input UI hints stored by `Node::ValueHint::save()` / `load()`:
|
||
|
||
值提示是按输入保存的 UI 提示,由 `Node::ValueHint::save()` / `load()` 读写:
|
||
|
||
```xml
|
||
<hints>
|
||
<hint input="InputId" element="-1" version="1">
|
||
<types>
|
||
<type>0</type>
|
||
</types>
|
||
<index>0</index>
|
||
<tag>...</tag>
|
||
</hint>
|
||
</hints>
|
||
```
|
||
|
||
- `types`: list of allowed `NodeValue::Type` integers.
|
||
- `types`:允许的 `NodeValue::Type` 整数列表。
|
||
- `index`: hint index.
|
||
- `index`:提示索引。
|
||
- `tag`: hint tag string.
|
||
- `tag`:提示标签字符串。
|
||
|
||
### 4.7 `context` (Node positions in contexts) / 上下文中的节点位置
|
||
|
||
```xml
|
||
<context>
|
||
<node ptr="other_node_ptr">
|
||
<x>0</x>
|
||
<y>0</y>
|
||
<expanded>0|1</expanded>
|
||
</node>
|
||
</context>
|
||
```
|
||
|
||
- Stores the position and expanded state of other nodes inside this node's context (e.g. inside a NodeGroup).
|
||
- 保存其他节点在该节点上下文(例如 NodeGroup 内部)中的位置和展开状态。
|
||
|
||
### 4.8 `caches` / 缓存 UUID
|
||
|
||
Node cache UUIDs:
|
||
|
||
节点缓存 UUID:
|
||
|
||
```xml
|
||
<caches>
|
||
<audio>uuid</audio>
|
||
<video>uuid</video>
|
||
<thumb>uuid</thumb>
|
||
<waveform>uuid</waveform>
|
||
</caches>
|
||
```
|
||
|
||
### 4.9 `custom` / 自定义节点数据
|
||
|
||
Default `Node::SaveCustom()` writes nothing. Specific node subclasses may override.
|
||
|
||
默认 `Node::SaveCustom()` 不写任何内容。具体子类可重写。
|
||
|
||
---
|
||
|
||
## 5. Node-specific Custom Data / 节点专属自定义数据
|
||
|
||
### 5.1 `Footage` (`app/node/project/footage/footage.cpp`)
|
||
|
||
```xml
|
||
<custom>
|
||
<timestamp>1740000000</timestamp>
|
||
<proxy enabled="1" state="ready" stream="0" preset="1">/path/to/proxy.mp4</proxy>
|
||
<proxy enabled="1" state="ready" stream="0" preset="1" custom="1" pwidth="960" pheight="540" pcrf="20" ppreset="fast" pext="mov" paudio="0">/path/to/proxy.mov</proxy>
|
||
<sourcestarttime source="timecode">1/25</sourcestarttime>
|
||
<viewer>...</viewer>
|
||
</custom>
|
||
```
|
||
|
||
- `<timestamp>`: media modification timestamp (epoch milliseconds).
|
||
- `<timestamp>`:媒体修改时间戳(Unix 毫秒)。
|
||
- `<proxy>`: proxy media state.
|
||
- `<proxy>`:代理媒体状态。
|
||
- Attributes / 属性:
|
||
- `enabled`: `0` or `1`.
|
||
- `enabled`:`0` 或 `1`。
|
||
- `state`: string from `ProxyManager::ProxyStateToString()` (e.g. `missing`, `ready`, `generating`, `failed`).
|
||
- `state`:`ProxyManager::ProxyStateToString()` 返回的字符串(如 `missing`、`ready`、`generating`、`failed`)。
|
||
- `stream`: video stream index used for the proxy.
|
||
- `stream`:代理使用的视频流索引。
|
||
- `preset`: proxy preset version.
|
||
- `preset`:代理预设版本。
|
||
- `custom` (optional): `1` when the footage uses per-footage custom proxy parameters instead of the global settings.
|
||
- `custom`(可选):为 `1` 表示该素材使用独立的自定义代理参数,而不是全局设置。
|
||
- `pwidth`, `pheight` (optional, requires `custom="1"`): custom proxy dimensions.
|
||
- `pwidth`、`pheight`(可选,需 `custom="1"`):自定义代理分辨率。
|
||
- `pdivider` (optional): source resolution divider (`1` = use `pwidth`/`pheight`; `2`/`4`/`8` = fraction of the source resolution). Defaults to `1` when absent.
|
||
- `pdivider`(可选):源分辨率分频(`1` = 使用 `pwidth`/`pheight`;`2`/`4`/`8` = 源分辨率的几分之一)。缺省时为 `1`。
|
||
- `pcrf` (optional): custom x264 CRF value.
|
||
- `pcrf`(可选):自定义 x264 CRF 值。
|
||
- `ppreset` (optional): custom x264 preset name.
|
||
- `ppreset`(可选):自定义 x264 预设名称。
|
||
- `pext` (optional): custom proxy container extension (e.g. `mp4`, `mov`).
|
||
- `pext`(可选):自定义代理容器扩展名(如 `mp4`、`mov`)。
|
||
- `paudio` (optional): `1` if the proxy includes audio streams, `0` for video-only. Proxies generated with audio store the video stream at index 0 followed by the source audio streams in source order.
|
||
- `paudio`(可选):`1` 表示代理包含音频流,`0` 表示仅视频。包含音频的代理将视频流放在索引 0,其后按源顺序跟随音频流。
|
||
- Text content: proxy file path (may be empty if `enabled` is true but proxy is not yet generated).
|
||
- 文本内容:代理文件路径(如果 `enabled` 为 true 但代理尚未生成,则可能为空)。
|
||
- `<sourcestarttime>`: source start time offset.
|
||
- `<sourcestarttime>`:源起始时间偏移。
|
||
- `source` attribute: source identifier (e.g. `timecode`, `bwf_time_reference`, or `manual` when entered by the user).
|
||
- `source` 属性:源标识符(如 `timecode`、`bwf_time_reference`,或用户手动输入时的 `manual`)。
|
||
- Text: rational `numerator/denominator`.
|
||
- 文本:有理数 `numerator/denominator`。
|
||
- `<viewer>`: see `ViewerOutput` below.
|
||
- `<viewer>`:见下文 `ViewerOutput`。
|
||
|
||
### 5.2 `ViewerOutput` (`app/node/output/viewer/viewer.cpp`)
|
||
|
||
Used by `Footage`, `Sequence`, etc.
|
||
|
||
`Footage`、`Sequence` 等使用。
|
||
|
||
```xml
|
||
<viewer>
|
||
<workarea version="1">
|
||
<enabled>0|1</enabled>
|
||
<in>num/den</in>
|
||
<out>num/den</out>
|
||
</workarea>
|
||
<markers>
|
||
<marker name="Marker Name" in="num/den" out="num/den" color="0" />
|
||
</markers>
|
||
</viewer>
|
||
```
|
||
|
||
- `<workarea>`: render/export work area.
|
||
- `<workarea>`:渲染/导出工作区。
|
||
- `<markers>`: timeline markers.
|
||
- `<markers>`:时间线标记。
|
||
- Marker attributes / 标记属性:
|
||
- `name`: marker name.
|
||
- `name`:标记名称。
|
||
- `in` / `out`: rational time range.
|
||
- `in` / `out`:有理数时间范围。
|
||
- `color`: color index.
|
||
- `color`:颜色索引。
|
||
|
||
### 5.3 `Track` (`app/node/output/track/track.cpp`)
|
||
|
||
```xml
|
||
<custom>
|
||
<height>48</height>
|
||
</custom>
|
||
```
|
||
|
||
- `<height>`: track height in the timeline.
|
||
- `<height>`:时间线中轨道的显示高度。
|
||
|
||
### 5.4 `NodeGroup` (`app/node/group/group.cpp`)
|
||
|
||
```xml
|
||
<custom>
|
||
<inputpassthroughs>
|
||
<inputpassthrough>
|
||
<node>ptr</node>
|
||
<input>InputId</input>
|
||
<element>0</element>
|
||
<id>PassthroughId</id>
|
||
<name>Display Name</name>
|
||
<flags>0</flags>
|
||
<type>float</type>
|
||
<default>...</default>
|
||
<properties>
|
||
<property>
|
||
<key>...</key>
|
||
<value>...</value>
|
||
</property>
|
||
</properties>
|
||
</inputpassthrough>
|
||
</inputpassthroughs>
|
||
<outputpassthrough>ptr</outputpassthrough>
|
||
</custom>
|
||
```
|
||
|
||
- `<inputpassthrough>`: maps an inner node's input to a group-level passthrough input.
|
||
- `<inputpassthrough>`:将内部节点输入映射到组级别的透传输入。
|
||
- Child elements / 子元素:
|
||
- `<node>`: pointer id of the inner node.
|
||
- `<node>`:内部节点的指针 ID。
|
||
- `<input>`: inner input id.
|
||
- `<input>`:内部输入 ID。
|
||
- `<element>`: element index.
|
||
- `<element>`:元素索引。
|
||
- `<id>`: passthrough input id on the group.
|
||
- `<id>`:组上的透传输入 ID。
|
||
- `<name>`: display name.
|
||
- `<name>`:显示名称。
|
||
- `<flags>`: input flags (integer bitmask).
|
||
- `<flags>`:输入标志(整数位掩码)。
|
||
- `<type>`: `NodeValue` type name (see `NodeValue::GetDataTypeName()`).
|
||
- `<type>`:`NodeValue` 类型名称(见 `NodeValue::GetDataTypeName()`)。
|
||
- `<default>`: default value encoded with `NodeValue::ValueToString(type, ..., false)`.
|
||
- `<default>`:使用 `NodeValue::ValueToString(type, ..., false)` 编码的默认值。
|
||
- `<properties>`: arbitrary key/value property pairs.
|
||
- `<properties>`:任意键值属性对。
|
||
- `<outputpassthrough>`: pointer id of the node that provides the group's output.
|
||
- `<outputpassthrough>`:提供组输出的节点指针 ID。
|
||
|
||
---
|
||
|
||
## 6. `VideoParams` / 视频参数
|
||
|
||
Serialized inside `<standard><track>` for inputs of type `kVideoParams`.
|
||
|
||
在 `kVideoParams` 类型输入的 `<standard><track>` 中序列化。
|
||
|
||
```xml
|
||
<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>
|
||
<colorprimaries>int</colorprimaries>
|
||
<colortransfer>int</colortransfer>
|
||
```
|
||
|
||
- `format`: `PixelFormat::Format` integer (`U8`, `U10`, `U16`, `F16`, `F32`).
|
||
- `format`:`PixelFormat::Format` 整数(`U8`、`U10`、`U16`、`F16`、`F32`)。
|
||
- `interlacing`: `VideoParams::Interlacing` integer.
|
||
- `interlacing`:`VideoParams::Interlacing` 整数。
|
||
- `videotype`: `VideoParams::Type` integer.
|
||
- `videotype`:`VideoParams::Type` 整数。
|
||
- `colorrange`: `VideoParams::ColorRange` integer (`0` = limited, `1` = full).
|
||
- `colorrange`:`VideoParams::ColorRange` 整数(`0` 为 limited,`1` 为 full)。
|
||
- `colorprimaries`, `colortransfer`: raw FFmpeg `AVColorPrimaries` / `AVColorTransferCharacteristic` values reported by the media (`0` = unset, `2` = unspecified). Used to auto-detect the input colorspace when `colorspace` is empty.
|
||
- `colorprimaries`、`colortransfer`:媒体上报的 FFmpeg 原始 `AVColorPrimaries` / `AVColorTransferCharacteristic` 值(`0` 为未设置,`2` 为未指定)。当 `colorspace` 为空时用于自动检测输入色彩空间。
|
||
|
||
---
|
||
|
||
## 7. `AudioParams` / 音频参数
|
||
|
||
Serialized inside `<standard><track>` for inputs of type `kAudioParams`.
|
||
|
||
在 `kAudioParams` 类型输入的 `<standard><track>` 中序列化。
|
||
|
||
```xml
|
||
<samplerate>int</samplerate>
|
||
<channellayout>uint64</channellayout>
|
||
<format>string</format>
|
||
<enabled>0|1</enabled>
|
||
<streamindex>int</streamindex>
|
||
<duration>int64</duration>
|
||
<timebase>num/den</timebase>
|
||
```
|
||
|
||
- `format`: `SampleFormat::to_string()` value.
|
||
- `format`:`SampleFormat::to_string()` 值。
|
||
|
||
---
|
||
|
||
## 8. Main Window Layout (`MainWindowLayoutInfo`) / 主窗口布局
|
||
|
||
The `<layout>` element stores the state of the main window (open folders, sequences, panel data, and Qt window state).
|
||
|
||
`<layout>` 元素保存主窗口状态(打开的文件夹、序列、面板数据和 Qt 窗口状态)。
|
||
|
||
```xml
|
||
<layout version="1">
|
||
<folders>
|
||
<folder>ptr</folder>
|
||
</folders>
|
||
<timeline>
|
||
<sequence>ptr</sequence>
|
||
</timeline>
|
||
<viewers>
|
||
<viewer>ptr</viewer>
|
||
</viewers>
|
||
<data>
|
||
<panel id="PanelId">
|
||
<option name="key">value</option>
|
||
</panel>
|
||
</data>
|
||
<state>base64</state>
|
||
</layout>
|
||
```
|
||
|
||
- `<folders>`: pointer ids of open project folders.
|
||
- `<folders>`:打开的项目文件夹指针 ID。
|
||
- `<timeline>`: pointer ids of open sequences.
|
||
- `<timeline>`:打开的序列指针 ID。
|
||
- `<viewers>`: same as `<timeline>` in this implementation.
|
||
- `<viewers>`:当前实现与 `<timeline>` 相同。
|
||
- `<data>`: per-panel persistent data.
|
||
- `<data>`:每个面板的持久化数据。
|
||
- `<state>`: base64-encoded Qt window/toolbar/dock state.
|
||
- `<state>`:Base64 编码的 Qt 窗口/工具栏/停靠状态。
|
||
|
||
---
|
||
|
||
## 9. Partial Documents / 部分文档
|
||
|
||
`ProjectSerializer230220` can emit three kinds of partial documents for copy/paste and interchange:
|
||
|
||
`ProjectSerializer230220` 可输出三种部分文档,用于复制/粘贴和交换:
|
||
|
||
### 9.1 `markers`
|
||
|
||
```xml
|
||
<markers version="1">
|
||
<marker name="..." in="num/den" out="num/den" color="0" />
|
||
</markers>
|
||
```
|
||
|
||
### 9.2 `keyframes`
|
||
|
||
```xml
|
||
<keyframes version="1">
|
||
<node id="NodeId">
|
||
<input id="InputId">
|
||
<element id="0">
|
||
<track id="0">
|
||
<key ...>...</key>
|
||
</track>
|
||
</element>
|
||
</input>
|
||
</node>
|
||
</keyframes>
|
||
```
|
||
|
||
### 9.3 `nodes` / `timeline`
|
||
|
||
For copy/paste of nodes (`kOnlyNodes`) the root is `<nodes>`; for clip paste (`kOnlyClips`) the root is `<timeline>`.
|
||
|
||
复制/粘贴节点(`kOnlyNodes`)时根为 `<nodes>`;剪辑粘贴(`kOnlyClips`)时根为 `<timeline>`。
|
||
|
||
```xml
|
||
<nodes version="1">
|
||
<node id="NodeId" ptr="..." items="ptr1,ptr2">
|
||
...
|
||
</node>
|
||
<properties>
|
||
<node ptr="...">
|
||
<key>value</key>
|
||
</node>
|
||
</properties>
|
||
</nodes>
|
||
```
|
||
|
||
- `items`: comma-separated pointer ids of items that depend on this node; used to avoid duplicating shared dependencies.
|
||
- `items`:依赖该节点的项目指针 ID 逗号列表,用于避免重复共享依赖。
|
||
- `<properties>`: opaque string key/value pairs attached to nodes during copy/paste.
|
||
- `<properties>`:复制/粘贴时附加到节点的任意字符串键值对。
|
||
|
||
---
|
||
|
||
## 10. Versioning / 版本管理
|
||
|
||
- Root `<olive version="...">` selects the serializer.
|
||
- 根元素 `<olive version="...">` 选择序列化器。
|
||
- Newer files may be rejected with `kProjectTooNew` if no matching serializer exists.
|
||
- 如果没有匹配的序列化器,较新的文件可能以 `kProjectTooNew` 拒绝加载。
|
||
- Each major block (`project`, `nodes`, `workarea`, etc.) has its own internal `version` attribute for future expansion.
|
||
- 每个主要块(`project`、`nodes`、`workarea` 等)都有自己的内部 `version` 属性,便于未来扩展。
|
||
|
||
---
|
||
|
||
## 11. OpenFX Node Compatibility Notes / OpenFX 节点兼容性说明
|
||
|
||
- OpenFX nodes are identified by the OFX plugin identifier (`Plugin::getIdentifier()`).
|
||
- OpenFX 节点由 OFX 插件标识符(`Plugin::getIdentifier()`)标识。
|
||
- The `<plugins>` list ensures Oak Video Editor can locate external plugins before instantiating nodes.
|
||
- `<plugins>` 列表确保 Oak 在实例化节点前能够定位外部插件。
|
||
- If a plugin cannot be found at load time, the node cannot be instantiated and will be skipped.
|
||
- 如果加载时找不到插件,则无法实例化该节点,会被跳过。
|