@kolbo/kolbo-code-linux-arm64-musl 2.2.3 → 2.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/kolbo +0 -0
- package/package.json +1 -1
- package/skills/nle-xml-timeline/SKILL.md +362 -0
package/bin/kolbo
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nle-xml-timeline
|
|
3
|
+
description: Use when generating XMEML XML timeline files for import into DaVinci Resolve or Premiere Pro — from any source (AI-generated clips, local files, rendered outputs). Covers the exact structure DaVinci and Premiere require, path encoding, audio track format, and common failure modes like empty timelines or missing clips.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# NLE XML Timeline Generator
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
XMEML (v4) is the shared XML format used by Final Cut Pro 7, Premiere Pro, and DaVinci Resolve for timeline interchange. Generating it by hand is tricky — DaVinci especially is strict about structure. This skill captures every battle-tested detail needed to produce a working import on the first try.
|
|
11
|
+
|
|
12
|
+
**Golden rule:** Model your XML on a real Premiere Pro export. DaVinci reads Premiere-style XMEML reliably. Never invent structure.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Key Lessons (Learned the Hard Way)
|
|
17
|
+
|
|
18
|
+
| Issue | Root Cause | Fix |
|
|
19
|
+
|-------|-----------|-----|
|
|
20
|
+
| DaVinci imports empty timeline | Wrong structure — used `project>children` instead of flat `sequence` | Put `<sequence>` directly under `<xmeml>` |
|
|
21
|
+
| DaVinci ignores clips | Inline `<file>` blocks missing or using wrong id ref scheme | Full `<file>` block inline inside each `<clipitem>`, not separate library |
|
|
22
|
+
| Wrong frame count | Assumed 72 frames for 3s @ 24fps — clips were actually 73 | Always probe with `cv2` or `ffprobe` — never hardcode |
|
|
23
|
+
| Clips load offline | URL-encoded path used `%20` for spaces but DaVinci wanted `file://localhost/G%3a/` | Use `file://localhost/` + `%3a` for `:`, `%20` for spaces |
|
|
24
|
+
| Audio tracks missing | Used empty `<audio></audio>` block | Full audio `<track>` with `<clipitem>`, `<sourcetrack>`, Audio Levels filter |
|
|
25
|
+
| Wrong fps interpretation | `ntsc=TRUE` + `timebase=24` = 23.976, not 24 | Use `ntsc=FALSE` for true 24fps |
|
|
26
|
+
| Interlace misread | `fielddominance` not set | Always set `<fielddominance>none</fielddominance>` |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Required Structure (DaVinci + Premiere Compatible)
|
|
31
|
+
|
|
32
|
+
```xml
|
|
33
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
34
|
+
<!DOCTYPE xmeml>
|
|
35
|
+
<xmeml version="4">
|
|
36
|
+
<sequence id="sequence-1" explodedTracks="true"
|
|
37
|
+
TL.SQAudioVisibleBase="0" TL.SQVideoVisibleBase="0"
|
|
38
|
+
MZ.Sequence.PreviewFrameSizeHeight="1080"
|
|
39
|
+
MZ.Sequence.PreviewFrameSizeWidth="1920"
|
|
40
|
+
MZ.Sequence.VideoTimeDisplayFormat="100"
|
|
41
|
+
MZ.Sequence.AudioTimeDisplayFormat="200">
|
|
42
|
+
<uuid>your-unique-id</uuid>
|
|
43
|
+
<duration>TOTAL_FRAMES</duration>
|
|
44
|
+
<rate><timebase>24</timebase><ntsc>FALSE</ntsc></rate>
|
|
45
|
+
<name>My Timeline</name>
|
|
46
|
+
<media>
|
|
47
|
+
<video>
|
|
48
|
+
<format>...</format> <!-- REQUIRED: codec + dimensions -->
|
|
49
|
+
<track ...>
|
|
50
|
+
<clipitem id="clipitem-1">...</clipitem>
|
|
51
|
+
...
|
|
52
|
+
</track>
|
|
53
|
+
</video>
|
|
54
|
+
<audio>
|
|
55
|
+
<numOutputChannels>1</numOutputChannels>
|
|
56
|
+
<format>...</format>
|
|
57
|
+
<outputs>...</outputs>
|
|
58
|
+
<track ...> <!-- one track per audio file -->
|
|
59
|
+
<clipitem ...>...</clipitem>
|
|
60
|
+
</track>
|
|
61
|
+
</audio>
|
|
62
|
+
</media>
|
|
63
|
+
</sequence>
|
|
64
|
+
</xmeml>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Critical:** `<sequence>` is a direct child of `<xmeml>`. No `<project><children>` wrapper — that breaks DaVinci.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Video Clipitem Template
|
|
72
|
+
|
|
73
|
+
```xml
|
|
74
|
+
<clipitem id="clipitem-N">
|
|
75
|
+
<masterclipid>masterclip-N</masterclipid>
|
|
76
|
+
<name>CLIP_NAME</name>
|
|
77
|
+
<enabled>TRUE</enabled>
|
|
78
|
+
<duration>ACTUAL_FRAME_COUNT</duration> <!-- from ffprobe/cv2, NOT calculated -->
|
|
79
|
+
<rate><timebase>24</timebase><ntsc>FALSE</ntsc></rate>
|
|
80
|
+
<start>TIMELINE_IN_FRAME</start>
|
|
81
|
+
<end>TIMELINE_OUT_FRAME</end>
|
|
82
|
+
<in>0</in>
|
|
83
|
+
<out>72</out> <!-- source in/out -->
|
|
84
|
+
<alphatype>none</alphatype>
|
|
85
|
+
<pixelaspectratio>square</pixelaspectratio>
|
|
86
|
+
<anamorphic>FALSE</anamorphic>
|
|
87
|
+
<file id="file-N">
|
|
88
|
+
<name>filename.mp4</name>
|
|
89
|
+
<pathurl>file://localhost/G%3a/Path/To/filename.mp4</pathurl>
|
|
90
|
+
<rate><timebase>24</timebase><ntsc>FALSE</ntsc></rate>
|
|
91
|
+
<duration>ACTUAL_FRAME_COUNT</duration>
|
|
92
|
+
<timecode>
|
|
93
|
+
<rate><timebase>24</timebase><ntsc>FALSE</ntsc></rate>
|
|
94
|
+
<string>00:00:00:00</string>
|
|
95
|
+
<frame>0</frame>
|
|
96
|
+
<displayformat>NDF</displayformat>
|
|
97
|
+
</timecode>
|
|
98
|
+
<media>
|
|
99
|
+
<video>
|
|
100
|
+
<samplecharacteristics>
|
|
101
|
+
<rate><timebase>24</timebase><ntsc>FALSE</ntsc></rate>
|
|
102
|
+
<width>1920</width>
|
|
103
|
+
<height>1080</height>
|
|
104
|
+
<anamorphic>FALSE</anamorphic>
|
|
105
|
+
<pixelaspectratio>square</pixelaspectratio>
|
|
106
|
+
<fielddominance>none</fielddominance>
|
|
107
|
+
</samplecharacteristics>
|
|
108
|
+
</video>
|
|
109
|
+
<audio>
|
|
110
|
+
<samplecharacteristics>
|
|
111
|
+
<depth>16</depth>
|
|
112
|
+
<samplerate>44100</samplerate> <!-- match actual file -->
|
|
113
|
+
</samplecharacteristics>
|
|
114
|
+
<channelcount>1</channelcount>
|
|
115
|
+
<layout>stereo</layout>
|
|
116
|
+
<audiochannel><sourcechannel>1</sourcechannel><channellabel>left</channellabel></audiochannel>
|
|
117
|
+
</audio>
|
|
118
|
+
<audio>
|
|
119
|
+
<samplecharacteristics>
|
|
120
|
+
<depth>16</depth>
|
|
121
|
+
<samplerate>44100</samplerate>
|
|
122
|
+
</samplecharacteristics>
|
|
123
|
+
<channelcount>1</channelcount>
|
|
124
|
+
<layout>stereo</layout>
|
|
125
|
+
<audiochannel><sourcechannel>2</sourcechannel><channellabel>right</channellabel></audiochannel>
|
|
126
|
+
</audio>
|
|
127
|
+
</media>
|
|
128
|
+
</file>
|
|
129
|
+
<!-- Basic Motion + Distort filters (required for non-1920x1080 clips) -->
|
|
130
|
+
<filter>
|
|
131
|
+
<effect>
|
|
132
|
+
<name>Basic Motion</name><effectid>basic</effectid>
|
|
133
|
+
<effectcategory>motion</effectcategory><effecttype>motion</effecttype>
|
|
134
|
+
<mediatype>video</mediatype><pproBypass>false</pproBypass>
|
|
135
|
+
<parameter authoringApp="PremierePro">
|
|
136
|
+
<parameterid>scale</parameterid><name>Scale</name>
|
|
137
|
+
<valuemin>0</valuemin><valuemax>1000</valuemax><value>100</value>
|
|
138
|
+
</parameter>
|
|
139
|
+
</effect>
|
|
140
|
+
</filter>
|
|
141
|
+
<filter>
|
|
142
|
+
<effect>
|
|
143
|
+
<name>Distort</name><effectid>deformation</effectid>
|
|
144
|
+
<effectcategory>motion</effectcategory><effecttype>motion</effecttype>
|
|
145
|
+
<mediatype>video</mediatype>
|
|
146
|
+
<parameter authoringApp="PremierePro">
|
|
147
|
+
<parameterid>aspect</parameterid><name>Aspect</name>
|
|
148
|
+
<valuemin>-10000</valuemin><valuemax>10000</valuemax><value>9.99998</value>
|
|
149
|
+
</parameter>
|
|
150
|
+
</effect>
|
|
151
|
+
</filter>
|
|
152
|
+
<logginginfo>
|
|
153
|
+
<description></description><scene></scene><shottake></shottake>
|
|
154
|
+
<lognote></lognote><good></good>
|
|
155
|
+
<originalvideofilename></originalvideofilename>
|
|
156
|
+
<originalaudiofilename></originalaudiofilename>
|
|
157
|
+
</logginginfo>
|
|
158
|
+
<colorinfo><lut></lut><lut1></lut1><asc_sop></asc_sop><asc_sat></asc_sat><lut2></lut2></colorinfo>
|
|
159
|
+
</clipitem>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Video Format Block (inside `<video>`)
|
|
165
|
+
|
|
166
|
+
```xml
|
|
167
|
+
<format>
|
|
168
|
+
<samplecharacteristics>
|
|
169
|
+
<rate><timebase>24</timebase><ntsc>FALSE</ntsc></rate>
|
|
170
|
+
<codec>
|
|
171
|
+
<name>Apple ProRes 422</name>
|
|
172
|
+
<appspecificdata>
|
|
173
|
+
<appname>Final Cut Pro</appname>
|
|
174
|
+
<appmanufacturer>Apple Inc.</appmanufacturer>
|
|
175
|
+
<appversion>7.0</appversion>
|
|
176
|
+
<data>
|
|
177
|
+
<qtcodec>
|
|
178
|
+
<codecname>Apple ProRes 422</codecname>
|
|
179
|
+
<codectypecode>apcn</codectypecode>
|
|
180
|
+
<codecvendorcode>appl</codecvendorcode>
|
|
181
|
+
<spatialquality>1024</spatialquality>
|
|
182
|
+
<temporalquality>0</temporalquality>
|
|
183
|
+
<keyframerate>0</keyframerate>
|
|
184
|
+
<datarate>0</datarate>
|
|
185
|
+
</qtcodec>
|
|
186
|
+
</data>
|
|
187
|
+
</appspecificdata>
|
|
188
|
+
</codec>
|
|
189
|
+
<width>1920</width>
|
|
190
|
+
<height>1080</height>
|
|
191
|
+
<anamorphic>FALSE</anamorphic>
|
|
192
|
+
<pixelaspectratio>square</pixelaspectratio>
|
|
193
|
+
<fielddominance>none</fielddominance>
|
|
194
|
+
<colordepth>24</colordepth>
|
|
195
|
+
</samplecharacteristics>
|
|
196
|
+
</format>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Audio Track Template (narration / music)
|
|
202
|
+
|
|
203
|
+
```xml
|
|
204
|
+
<audio>
|
|
205
|
+
<numOutputChannels>1</numOutputChannels>
|
|
206
|
+
<format>
|
|
207
|
+
<samplecharacteristics>
|
|
208
|
+
<depth>16</depth>
|
|
209
|
+
<samplerate>48000</samplerate>
|
|
210
|
+
</samplecharacteristics>
|
|
211
|
+
</format>
|
|
212
|
+
<outputs>
|
|
213
|
+
<group><index>1</index><numchannels>1</numchannels><downmix>0</downmix><channel><index>1</index></channel></group>
|
|
214
|
+
<group><index>2</index><numchannels>1</numchannels><downmix>0</downmix><channel><index>2</index></channel></group>
|
|
215
|
+
</outputs>
|
|
216
|
+
<track TL.SQTrackAudioKeyframeStyle="0" TL.SQTrackShy="0"
|
|
217
|
+
TL.SQTrackExpandedHeight="41" TL.SQTrackExpanded="0"
|
|
218
|
+
MZ.TrackTargeted="1" PannerCurrentValue="0.5"
|
|
219
|
+
PannerName="Balance" currentExplodedTrackIndex="0"
|
|
220
|
+
totalExplodedTrackCount="1" premiereTrackType="Mono">
|
|
221
|
+
<clipitem id="clipitem-17" premiereChannelType="mono">
|
|
222
|
+
<masterclipid>masterclip-17</masterclipid>
|
|
223
|
+
<name>narration</name>
|
|
224
|
+
<enabled>TRUE</enabled>
|
|
225
|
+
<duration>11531</duration>
|
|
226
|
+
<rate><timebase>24</timebase><ntsc>FALSE</ntsc></rate>
|
|
227
|
+
<start>0</start>
|
|
228
|
+
<end>TOTAL_FRAMES</end>
|
|
229
|
+
<in>0</in><out>TOTAL_FRAMES</out>
|
|
230
|
+
<file id="file-17">
|
|
231
|
+
<name>narration.mp3</name>
|
|
232
|
+
<pathurl>file://localhost/G%3a/Path/To/narration.mp3</pathurl>
|
|
233
|
+
<rate><timebase>30</timebase><ntsc>TRUE</ntsc></rate> <!-- MP3 rate as Premiere detects -->
|
|
234
|
+
<duration>977</duration> <!-- frame count at that rate -->
|
|
235
|
+
<timecode>
|
|
236
|
+
<rate><timebase>30</timebase><ntsc>TRUE</ntsc></rate>
|
|
237
|
+
<string>00;00;00;00</string><frame>0</frame>
|
|
238
|
+
<displayformat>DF</displayformat>
|
|
239
|
+
</timecode>
|
|
240
|
+
<media>
|
|
241
|
+
<audio>
|
|
242
|
+
<samplecharacteristics><depth>16</depth><samplerate>44100</samplerate></samplecharacteristics>
|
|
243
|
+
<channelcount>1</channelcount>
|
|
244
|
+
<audiochannel><sourcechannel>1</sourcechannel></audiochannel>
|
|
245
|
+
</audio>
|
|
246
|
+
</media>
|
|
247
|
+
</file>
|
|
248
|
+
<sourcetrack><mediatype>audio</mediatype><trackindex>1</trackindex></sourcetrack>
|
|
249
|
+
<filter>
|
|
250
|
+
<effect>
|
|
251
|
+
<name>Audio Levels</name><effectid>audiolevels</effectid>
|
|
252
|
+
<effectcategory>audiolevels</effectcategory><effecttype>audiolevels</effecttype>
|
|
253
|
+
<mediatype>audio</mediatype><pproBypass>false</pproBypass>
|
|
254
|
+
<parameter authoringApp="PremierePro">
|
|
255
|
+
<parameterid>level</parameterid><name>Level</name>
|
|
256
|
+
<valuemin>0</valuemin><valuemax>3.98109</valuemax><value>1</value>
|
|
257
|
+
</parameter>
|
|
258
|
+
</effect>
|
|
259
|
+
</filter>
|
|
260
|
+
<logginginfo><description></description><scene></scene><shottake></shottake><lognote></lognote><good></good><originalvideofilename></originalvideofilename><originalaudiofilename></originalaudiofilename></logginginfo>
|
|
261
|
+
<colorinfo><lut></lut><lut1></lut1><asc_sop></asc_sop><asc_sat></asc_sat><lut2></lut2></colorinfo>
|
|
262
|
+
</clipitem>
|
|
263
|
+
<enabled>TRUE</enabled>
|
|
264
|
+
<locked>FALSE</locked>
|
|
265
|
+
<outputchannelindex>1</outputchannelindex>
|
|
266
|
+
</track>
|
|
267
|
+
</audio>
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Path URL Encoding Rules
|
|
273
|
+
|
|
274
|
+
| OS | Format |
|
|
275
|
+
|----|--------|
|
|
276
|
+
| Windows | `file://localhost/G%3a/My%20Folder/file.mp4` |
|
|
277
|
+
| Mac/Linux | `file://localhost/Users/name/folder/file.mp4` |
|
|
278
|
+
|
|
279
|
+
- Drive letter colon: `G:` → `G%3a`
|
|
280
|
+
- Spaces: `My Folder` → `My%20Folder`
|
|
281
|
+
- No other encoding needed for standard path chars
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Frame Rate Reference
|
|
286
|
+
|
|
287
|
+
| FPS | `timebase` | `ntsc` | `displayformat` |
|
|
288
|
+
|-----|-----------|--------|-----------------|
|
|
289
|
+
| 24 (true) | 24 | FALSE | NDF |
|
|
290
|
+
| 23.976 | 24 | TRUE | NDF |
|
|
291
|
+
| 29.97 | 30 | TRUE | DF |
|
|
292
|
+
| 30 (true) | 30 | FALSE | NDF |
|
|
293
|
+
| 25 | 25 | FALSE | NDF |
|
|
294
|
+
|
|
295
|
+
**MP3/AAC audio files** — Premiere detects them as `timebase=30, ntsc=TRUE` regardless of content. Use that in the `<file>` rate block for audio-only clipitems.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Python Generator Workflow
|
|
300
|
+
|
|
301
|
+
Always generate XML programmatically — never hand-edit large files.
|
|
302
|
+
|
|
303
|
+
```python
|
|
304
|
+
import cv2
|
|
305
|
+
|
|
306
|
+
def get_clip_meta(path):
|
|
307
|
+
cap = cv2.VideoCapture(path)
|
|
308
|
+
frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
|
309
|
+
fps = cap.get(cv2.CAP_PROP_FPS)
|
|
310
|
+
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
|
311
|
+
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
|
312
|
+
cap.release()
|
|
313
|
+
return frames, fps, w, h
|
|
314
|
+
|
|
315
|
+
# Use real metadata in XML — never assume frame count from duration × fps
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Write to a `build_xml.py` script alongside the output folder so it can be re-run if clip list changes.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Track Attributes (copy verbatim)
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
Video track:
|
|
326
|
+
TL.SQTrackShy="0" TL.SQTrackExpandedHeight="41" TL.SQTrackExpanded="0" MZ.TrackTargeted="1"
|
|
327
|
+
|
|
328
|
+
Audio track:
|
|
329
|
+
TL.SQTrackAudioKeyframeStyle="0" TL.SQTrackShy="0" TL.SQTrackExpandedHeight="41"
|
|
330
|
+
TL.SQTrackExpanded="0" MZ.TrackTargeted="1" PannerCurrentValue="0.5"
|
|
331
|
+
PannerName="Balance" currentExplodedTrackIndex="0" totalExplodedTrackCount="1"
|
|
332
|
+
premiereTrackType="Mono"
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## DaVinci Import Steps
|
|
338
|
+
|
|
339
|
+
1. Set project frame rate **before** importing (can't change after media is in)
|
|
340
|
+
2. **File → Import Timeline** (NOT "Media from XML" — that only imports clips)
|
|
341
|
+
3. On the dialog: uncheck "Automatically import source clips" if paths might not resolve
|
|
342
|
+
4. If clips show offline: right-click timeline → Relink Media → point to folder
|
|
343
|
+
|
|
344
|
+
## Premiere Import Steps
|
|
345
|
+
|
|
346
|
+
1. **File → Import** (or drag XML into Project panel)
|
|
347
|
+
2. Accept sequence settings dialog
|
|
348
|
+
3. Offline clips → right-click → Link Media
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## Common Mistakes
|
|
353
|
+
|
|
354
|
+
| Mistake | Symptom | Fix |
|
|
355
|
+
|---------|---------|-----|
|
|
356
|
+
| `project > children` wrapper | DaVinci: empty timeline | Remove wrapper, `<sequence>` directly under `<xmeml>` |
|
|
357
|
+
| Empty `<audio></audio>` | No audio tracks in timeline | Full track + clipitem + file + filter structure |
|
|
358
|
+
| Hardcoded 72 frames per clip | Wrong clip lengths / gaps | Always probe with cv2/ffprobe |
|
|
359
|
+
| `ntsc=TRUE` on 24fps | Resolve treats as 23.976 | Use `ntsc=FALSE` for true 24 |
|
|
360
|
+
| Missing `<format>` block in video | Premiere fails to read | Always include format with codec data |
|
|
361
|
+
| Missing motion filters | Non-1080p clips look stretched | Include Basic Motion + Distort filters |
|
|
362
|
+
| Missing `<logginginfo>` / `<colorinfo>` | Premiere warnings on import | Include empty blocks |
|