davinci-resolve-mcp 2.120.0 → 2.121.0
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/install.py
CHANGED
|
@@ -37,7 +37,7 @@ from src.utils.update_check import (
|
|
|
37
37
|
|
|
38
38
|
# ─── Version ──────────────────────────────────────────────────────────────────
|
|
39
39
|
|
|
40
|
-
VERSION = "2.
|
|
40
|
+
VERSION = "2.121.0"
|
|
41
41
|
# Only hard floor: mcp[cli] requires Python 3.10+. There is no upper bound —
|
|
42
42
|
# Resolve's scripting bridge loads into newer interpreters on recent builds
|
|
43
43
|
# (Python 3.14 verified against Resolve Studio 20.3.2). Older Resolve builds
|
package/package.json
CHANGED
|
@@ -141,6 +141,16 @@ export function parseOTIO(otio, opts = {}) {
|
|
|
141
141
|
// First track of each kind keeps the bare letter (compat); higher tracks
|
|
142
142
|
// are numbered ('V2', 'A2', …).
|
|
143
143
|
const kind = isAudio ? (aNum === 1 ? 'A' : `A${aNum}`) : (vNum === 1 ? 'V' : `V${vNum}`);
|
|
144
|
+
// Track-level markers: marked_range is already in track (record) time.
|
|
145
|
+
for (const mk of track.markers || []) {
|
|
146
|
+
const mrStart = (mk.marked_range && mk.marked_range.start_time && mk.marked_range.start_time.value) || 0;
|
|
147
|
+
const mrRate = (mk.marked_range && mk.marked_range.start_time && mk.marked_range.start_time.rate) || opts.fps || 24;
|
|
148
|
+
events.push(evt({
|
|
149
|
+
index: idx++, track: 'MARKER', source: '',
|
|
150
|
+
recIn: mrStart, recOut: null,
|
|
151
|
+
name: mk.name || undefined, color: mk.color || undefined, fps: mrRate,
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
144
154
|
let rec = 0;
|
|
145
155
|
for (const child of track.children || []) {
|
|
146
156
|
const schema = child.OTIO_SCHEMA || '';
|
|
@@ -429,5 +439,20 @@ export function markerRoundtrip(markers, opts = {}) {
|
|
|
429
439
|
throw new Error(`marker_roundtrip: ${markers.length} in, ${decoded.length} out — round-trip dropped markers`);
|
|
430
440
|
const provenanceOk = decoded.every((m) => typeof m.provenance === 'string' && m.provenance.length);
|
|
431
441
|
if (markers.length && !provenanceOk) throw new Error('marker_roundtrip: a marker lost its provenance tag');
|
|
432
|
-
|
|
442
|
+
// Binary round-trip through the REAL Sm2SequenceLockableBlob codec
|
|
443
|
+
// (byte-exact vs a live export): provenance rides in customData, so an
|
|
444
|
+
// authored .drt carries it. Colors outside the measured 16 refuse there —
|
|
445
|
+
// markerRoundtrip normalizes to 'Blue' above, so this cannot throw for
|
|
446
|
+
// valid input; if it ever does, that IS the failed round-trip.
|
|
447
|
+
let blobRoundTrip = 'skipped (no markers)';
|
|
448
|
+
if (normalized.length) {
|
|
449
|
+
const { encodeTimelineMarkersBlob, decodeTimelineMarkersBlob } = require('../vendor/drp-format/timeline-markers-blob.js');
|
|
450
|
+
const back = decodeTimelineMarkersBlob(encodeTimelineMarkersBlob(normalized.map((m) => ({
|
|
451
|
+
frame: m.frame, color: m.color, name: m.name, note: m.note, customData: m.provenance,
|
|
452
|
+
}))));
|
|
453
|
+
if (back.length !== normalized.length) throw new Error(`marker_roundtrip: blob codec ${normalized.length} in, ${back.length} out`);
|
|
454
|
+
if (!back.every((m) => m.customData && m.customData.length)) throw new Error('marker_roundtrip: provenance lost in the blob codec');
|
|
455
|
+
blobRoundTrip = 'ok';
|
|
456
|
+
}
|
|
457
|
+
return { count: decoded.length, markers: decoded, provenanceOk, roundTrip: 'ok', blobRoundTrip };
|
|
433
458
|
}
|
|
@@ -338,9 +338,15 @@ function buildLockableBlobElement(markers, blobId, frameRate) {
|
|
|
338
338
|
]);
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
-
//
|
|
342
|
-
//
|
|
343
|
-
|
|
341
|
+
// Real Sm2SequenceLockableBlob encoding (byte-exact vs a live 19.1.3.7
|
|
342
|
+
// export; see timeline-markers-blob.js) — replaces the old simplified
|
|
343
|
+
// marker-encoder blob, whose bytes never matched a real export.
|
|
344
|
+
const { encodeTimelineMarkersBlob } = require('./timeline-markers-blob');
|
|
345
|
+
const fieldsBlobHex = encodeTimelineMarkersBlob(markers.map((m) => ({
|
|
346
|
+
frame: Number(m.frame) || 0,
|
|
347
|
+
color: m.color, name: m.name, note: m.note ?? m.description,
|
|
348
|
+
duration: m.duration, customData: m.customData,
|
|
349
|
+
}))).toString('hex');
|
|
344
350
|
|
|
345
351
|
return buildXmlElement('Sm2SequenceLockableBlob', { DbId: blobId }, [
|
|
346
352
|
buildXmlElement('FieldsBlob', {}, fieldsBlobHex),
|
package/src/granular/common.py
CHANGED
|
@@ -87,7 +87,7 @@ if not logging.getLogger().handlers:
|
|
|
87
87
|
handlers=[logging.StreamHandler()],
|
|
88
88
|
)
|
|
89
89
|
|
|
90
|
-
VERSION = "2.
|
|
90
|
+
VERSION = "2.121.0"
|
|
91
91
|
logger = logging.getLogger("davinci-resolve-mcp")
|
|
92
92
|
logger.info(f"Starting DaVinci Resolve MCP Server v{VERSION}")
|
|
93
93
|
logger.info(f"Detected platform: {get_platform()}")
|