@synthetic-ai/premiere-mcp 2.1.0 → 2.3.0-dev.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/CHANGELOG.md +135 -123
- package/LICENSE +21 -21
- package/README.md +242 -242
- package/cep-plugin/.debug +8 -8
- package/cep-plugin/CSInterface.js +92 -92
- package/cep-plugin/host.jsx +7 -7
- package/cep-plugin/index.html +472 -472
- package/cep-plugin/main.js +6 -0
- package/cep-plugin/premiere.jsx +24947 -24947
- package/dist/bridge/script-builder.js +378 -378
- package/dist/index.js +103 -4
- package/dist/license.js +38 -0
- package/dist/server.js +60 -60
- package/dist/tools/advanced.js +357 -357
- package/dist/tools/audio-advanced.js +1049 -1049
- package/dist/tools/audio.js +42 -42
- package/dist/tools/captions.js +27 -27
- package/dist/tools/clipboard.js +214 -214
- package/dist/tools/color-advanced.js +253 -253
- package/dist/tools/discovery.js +291 -291
- package/dist/tools/effects.js +285 -285
- package/dist/tools/export-presets.js +206 -206
- package/dist/tools/export.js +255 -255
- package/dist/tools/health.js +10 -10
- package/dist/tools/inspection.js +885 -885
- package/dist/tools/keyframes.js +369 -369
- package/dist/tools/markers.js +89 -89
- package/dist/tools/media.js +178 -178
- package/dist/tools/metadata.js +94 -94
- package/dist/tools/multicam.js +50 -50
- package/dist/tools/playback.js +15 -15
- package/dist/tools/playhead.js +95 -95
- package/dist/tools/project-manager.js +21 -21
- package/dist/tools/project.js +149 -149
- package/dist/tools/scripting.js +319 -319
- package/dist/tools/selection.js +202 -202
- package/dist/tools/sequence-advanced.js +379 -379
- package/dist/tools/sequence-settings.js +564 -564
- package/dist/tools/sequence.js +167 -167
- package/dist/tools/source-monitor.js +68 -68
- package/dist/tools/text.js +58 -58
- package/dist/tools/timeline.js +312 -312
- package/dist/tools/track-management.js +446 -446
- package/dist/tools/track-targeting.js +635 -635
- package/dist/tools/tracks.js +87 -87
- package/dist/tools/transitions-motion.js +174 -174
- package/dist/tools/transitions.js +111 -111
- package/dist/tools/utility.js +606 -606
- package/dist/tools/workspace.js +29 -29
- package/package.json +66 -66
- package/scripts/build-chat-dmg.sh +210 -210
- package/scripts/build-chat-zip.sh +291 -291
- package/scripts/install-cep-windows.ps1 +99 -99
- package/scripts/install-cep.sh +66 -66
- package/scripts/install-chat-plugin.bat +67 -67
- package/scripts/install-chat-plugin.sh +85 -85
- package/scripts/install-windows.bat +95 -95
- package/scripts/package.mjs +254 -254
package/dist/tools/audio.js
CHANGED
|
@@ -19,20 +19,20 @@ export function getAudioTools(bridgeOptions) {
|
|
|
19
19
|
required: ["node_id", "level_db"],
|
|
20
20
|
},
|
|
21
21
|
handler: async (args) => {
|
|
22
|
-
const script = buildToolScript(`
|
|
23
|
-
var result = __findClip("${escapeForExtendScript(args.node_id)}");
|
|
24
|
-
if (!result) return __error("Clip not found");
|
|
25
|
-
|
|
26
|
-
var clip = result.clip;
|
|
27
|
-
// Find the Volume component via locale-independent helper
|
|
28
|
-
var volComp = __findIntrinsic(clip, "volume");
|
|
29
|
-
if (!volComp) return __error("Could not find Volume component on clip");
|
|
30
|
-
|
|
31
|
-
var levelProp = __findProp(volComp, ["Level", "Volume", "Nivel"]);
|
|
32
|
-
if (!levelProp) return __error("Could not find Volume/Level property on clip");
|
|
33
|
-
|
|
34
|
-
levelProp.setValue(${args.level_db}, true);
|
|
35
|
-
return __result({ adjusted: true, clipName: clip.name, levelDb: ${args.level_db} });
|
|
22
|
+
const script = buildToolScript(`
|
|
23
|
+
var result = __findClip("${escapeForExtendScript(args.node_id)}");
|
|
24
|
+
if (!result) return __error("Clip not found");
|
|
25
|
+
|
|
26
|
+
var clip = result.clip;
|
|
27
|
+
// Find the Volume component via locale-independent helper
|
|
28
|
+
var volComp = __findIntrinsic(clip, "volume");
|
|
29
|
+
if (!volComp) return __error("Could not find Volume component on clip");
|
|
30
|
+
|
|
31
|
+
var levelProp = __findProp(volComp, ["Level", "Volume", "Nivel"]);
|
|
32
|
+
if (!levelProp) return __error("Could not find Volume/Level property on clip");
|
|
33
|
+
|
|
34
|
+
levelProp.setValue(${args.level_db}, true);
|
|
35
|
+
return __result({ adjusted: true, clipName: clip.name, levelDb: ${args.level_db} });
|
|
36
36
|
`);
|
|
37
37
|
return sendCommand(script, bridgeOptions);
|
|
38
38
|
},
|
|
@@ -63,26 +63,26 @@ export function getAudioTools(bridgeOptions) {
|
|
|
63
63
|
},
|
|
64
64
|
handler: async (args) => {
|
|
65
65
|
const keyframeCode = args.keyframes
|
|
66
|
-
.map((kf) => `
|
|
67
|
-
var kfT = new Time(); kfT.ticks = String(__secondsToTicks(${kf.time_seconds}));
|
|
68
|
-
levelProp.addKey(kfT);
|
|
66
|
+
.map((kf) => `
|
|
67
|
+
var kfT = new Time(); kfT.ticks = String(__secondsToTicks(${kf.time_seconds}));
|
|
68
|
+
levelProp.addKey(kfT);
|
|
69
69
|
levelProp.setValueAtKey(kfT, ${kf.level_db});`)
|
|
70
70
|
.join("\n");
|
|
71
|
-
const script = buildToolScript(`
|
|
72
|
-
var result = __findClip("${escapeForExtendScript(args.node_id)}");
|
|
73
|
-
if (!result) return __error("Clip not found");
|
|
74
|
-
|
|
75
|
-
var clip = result.clip;
|
|
76
|
-
var volComp = __findIntrinsic(clip, "volume");
|
|
77
|
-
if (!volComp) return __error("Could not find audio Volume component");
|
|
78
|
-
var levelProp = __findProp(volComp, ["Level", "Volume", "Nivel"]);
|
|
79
|
-
|
|
80
|
-
if (!levelProp) return __error("Could not find audio Level property");
|
|
81
|
-
|
|
82
|
-
levelProp.setTimeVarying(true);
|
|
83
|
-
${keyframeCode}
|
|
84
|
-
|
|
85
|
-
return __result({ keyframesAdded: ${args.keyframes.length}, clipName: clip.name });
|
|
71
|
+
const script = buildToolScript(`
|
|
72
|
+
var result = __findClip("${escapeForExtendScript(args.node_id)}");
|
|
73
|
+
if (!result) return __error("Clip not found");
|
|
74
|
+
|
|
75
|
+
var clip = result.clip;
|
|
76
|
+
var volComp = __findIntrinsic(clip, "volume");
|
|
77
|
+
if (!volComp) return __error("Could not find audio Volume component");
|
|
78
|
+
var levelProp = __findProp(volComp, ["Level", "Volume", "Nivel"]);
|
|
79
|
+
|
|
80
|
+
if (!levelProp) return __error("Could not find audio Level property");
|
|
81
|
+
|
|
82
|
+
levelProp.setTimeVarying(true);
|
|
83
|
+
${keyframeCode}
|
|
84
|
+
|
|
85
|
+
return __result({ keyframesAdded: ${args.keyframes.length}, clipName: clip.name });
|
|
86
86
|
`);
|
|
87
87
|
return sendCommand(script, bridgeOptions);
|
|
88
88
|
},
|
|
@@ -104,16 +104,16 @@ export function getAudioTools(bridgeOptions) {
|
|
|
104
104
|
required: ["track_index", "muted"],
|
|
105
105
|
},
|
|
106
106
|
handler: async (args) => {
|
|
107
|
-
const script = buildToolScript(`
|
|
108
|
-
var seq = app.project.activeSequence;
|
|
109
|
-
if (!seq) return __error("No active sequence");
|
|
110
|
-
|
|
111
|
-
if (${args.track_index} >= seq.audioTracks.numTracks) return __error("Track index out of range");
|
|
112
|
-
|
|
113
|
-
var track = seq.audioTracks[${args.track_index}];
|
|
114
|
-
track.setMute(${args.muted ? 1 : 0});
|
|
115
|
-
|
|
116
|
-
return __result({ trackIndex: ${args.track_index}, muted: ${args.muted}, trackName: track.name });
|
|
107
|
+
const script = buildToolScript(`
|
|
108
|
+
var seq = app.project.activeSequence;
|
|
109
|
+
if (!seq) return __error("No active sequence");
|
|
110
|
+
|
|
111
|
+
if (${args.track_index} >= seq.audioTracks.numTracks) return __error("Track index out of range");
|
|
112
|
+
|
|
113
|
+
var track = seq.audioTracks[${args.track_index}];
|
|
114
|
+
track.setMute(${args.muted ? 1 : 0});
|
|
115
|
+
|
|
116
|
+
return __result({ trackIndex: ${args.track_index}, muted: ${args.muted}, trackName: track.name });
|
|
117
117
|
`);
|
|
118
118
|
return sendCommand(script, bridgeOptions);
|
|
119
119
|
},
|
package/dist/tools/captions.js
CHANGED
|
@@ -37,33 +37,33 @@ export function getCaptionTools(bridgeOptions) {
|
|
|
37
37
|
};
|
|
38
38
|
const formatKey = args.caption_format || "subtitle";
|
|
39
39
|
const formatEntry = formatMap[formatKey] || formatMap["subtitle"];
|
|
40
|
-
const script = buildToolScript(`
|
|
41
|
-
var seq = app.project.activeSequence;
|
|
42
|
-
if (!seq) return __error("No active sequence");
|
|
43
|
-
|
|
44
|
-
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
|
|
45
|
-
if (!item) return __error("Caption item not found: ${escapeForExtendScript(args.item_id)}");
|
|
46
|
-
|
|
47
|
-
// Resolve the caption format constant defensively. The Sequence.CAPTION_FORMAT_*
|
|
48
|
-
// constants may be undefined depending on the Premiere version, so fall back to
|
|
49
|
-
// the known numeric value if the constant cannot be read.
|
|
50
|
-
var captionFormat = ${formatEntry.fallback};
|
|
51
|
-
try {
|
|
52
|
-
if (typeof Sequence !== "undefined" && Sequence && typeof Sequence.${formatEntry.constant} !== "undefined") {
|
|
53
|
-
captionFormat = Sequence.${formatEntry.constant};
|
|
54
|
-
}
|
|
55
|
-
} catch (eFmt) {
|
|
56
|
-
captionFormat = ${formatEntry.fallback};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// createCaptionTrack may return undefined on success, so treat only a thrown
|
|
60
|
-
// error as a real failure.
|
|
61
|
-
try {
|
|
62
|
-
seq.createCaptionTrack(item, ${startSeconds}, captionFormat);
|
|
63
|
-
} catch (eCreate) {
|
|
64
|
-
return __error("Failed to create caption track: " + eCreate.toString());
|
|
65
|
-
}
|
|
66
|
-
return __result({ created: true, item: item.name, startSeconds: ${startSeconds}, format: "${formatKey}" });
|
|
40
|
+
const script = buildToolScript(`
|
|
41
|
+
var seq = app.project.activeSequence;
|
|
42
|
+
if (!seq) return __error("No active sequence");
|
|
43
|
+
|
|
44
|
+
var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
|
|
45
|
+
if (!item) return __error("Caption item not found: ${escapeForExtendScript(args.item_id)}");
|
|
46
|
+
|
|
47
|
+
// Resolve the caption format constant defensively. The Sequence.CAPTION_FORMAT_*
|
|
48
|
+
// constants may be undefined depending on the Premiere version, so fall back to
|
|
49
|
+
// the known numeric value if the constant cannot be read.
|
|
50
|
+
var captionFormat = ${formatEntry.fallback};
|
|
51
|
+
try {
|
|
52
|
+
if (typeof Sequence !== "undefined" && Sequence && typeof Sequence.${formatEntry.constant} !== "undefined") {
|
|
53
|
+
captionFormat = Sequence.${formatEntry.constant};
|
|
54
|
+
}
|
|
55
|
+
} catch (eFmt) {
|
|
56
|
+
captionFormat = ${formatEntry.fallback};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// createCaptionTrack may return undefined on success, so treat only a thrown
|
|
60
|
+
// error as a real failure.
|
|
61
|
+
try {
|
|
62
|
+
seq.createCaptionTrack(item, ${startSeconds}, captionFormat);
|
|
63
|
+
} catch (eCreate) {
|
|
64
|
+
return __error("Failed to create caption track: " + eCreate.toString());
|
|
65
|
+
}
|
|
66
|
+
return __result({ created: true, item: item.name, startSeconds: ${startSeconds}, format: "${formatKey}" });
|
|
67
67
|
`);
|
|
68
68
|
return sendCommand(script, bridgeOptions);
|
|
69
69
|
},
|
package/dist/tools/clipboard.js
CHANGED
|
@@ -23,57 +23,57 @@ export function getClipboardTools(bridgeOptions) {
|
|
|
23
23
|
required: ["source_node_id", "target_node_id"],
|
|
24
24
|
},
|
|
25
25
|
handler: async (args) => {
|
|
26
|
-
const script = buildToolScript(`
|
|
27
|
-
app.enableQE();
|
|
28
|
-
var srcResult = __findClip("${escapeForExtendScript(args.source_node_id)}");
|
|
29
|
-
if (!srcResult) return __error("Source clip not found");
|
|
30
|
-
var tgtResult = __findClip("${escapeForExtendScript(args.target_node_id)}");
|
|
31
|
-
if (!tgtResult) return __error("Target clip not found");
|
|
32
|
-
|
|
33
|
-
var src = srcResult.clip;
|
|
34
|
-
var tgt = tgtResult.clip;
|
|
35
|
-
var copied = 0;
|
|
36
|
-
var effectFilter = ${args.effect_name ? `"${escapeForExtendScript(args.effect_name)}"` : "null"};
|
|
37
|
-
var intrinsic = ["Motion", "Opacity", "Time Remapping", "Volume", "Channel Volume", "Panner"];
|
|
38
|
-
|
|
39
|
-
// Use QE to copy effects by name
|
|
40
|
-
var qeSeq = qe.project.getActiveSequence();
|
|
41
|
-
var tgtTrackType = tgtResult.trackType;
|
|
42
|
-
var tgtTrack = tgtTrackType === "video"
|
|
43
|
-
? qeSeq.getVideoTrackAt(tgtResult.trackIndex)
|
|
44
|
-
: qeSeq.getAudioTrackAt(tgtResult.trackIndex);
|
|
45
|
-
var qeTgtClip = tgtTrack.getItemAt(tgtResult.clipIndex);
|
|
46
|
-
|
|
47
|
-
for (var i = 0; i < src.components.numItems; i++) {
|
|
48
|
-
var comp = src.components[i];
|
|
49
|
-
var name = comp.displayName;
|
|
50
|
-
|
|
51
|
-
if (effectFilter && name !== effectFilter) continue;
|
|
52
|
-
if (!effectFilter) {
|
|
53
|
-
var skip = false;
|
|
54
|
-
for (var k = 0; k < intrinsic.length; k++) {
|
|
55
|
-
if (name === intrinsic[k]) { skip = true; break; }
|
|
56
|
-
}
|
|
57
|
-
if (skip) continue;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Apply effect via QE
|
|
61
|
-
try {
|
|
62
|
-
var qeEffect = tgtTrackType === "video"
|
|
63
|
-
? qe.project.getVideoEffectByName(name)
|
|
64
|
-
: qe.project.getAudioEffectByName(name);
|
|
65
|
-
if (qeEffect) {
|
|
66
|
-
if (tgtTrackType === "video") {
|
|
67
|
-
qeTgtClip.addVideoEffect(qeEffect);
|
|
68
|
-
} else {
|
|
69
|
-
qeTgtClip.addAudioEffect(qeEffect);
|
|
70
|
-
}
|
|
71
|
-
copied++;
|
|
72
|
-
}
|
|
73
|
-
} catch(e) {}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return __result({ copiedEffects: copied, source: src.name, target: tgt.name });
|
|
26
|
+
const script = buildToolScript(`
|
|
27
|
+
app.enableQE();
|
|
28
|
+
var srcResult = __findClip("${escapeForExtendScript(args.source_node_id)}");
|
|
29
|
+
if (!srcResult) return __error("Source clip not found");
|
|
30
|
+
var tgtResult = __findClip("${escapeForExtendScript(args.target_node_id)}");
|
|
31
|
+
if (!tgtResult) return __error("Target clip not found");
|
|
32
|
+
|
|
33
|
+
var src = srcResult.clip;
|
|
34
|
+
var tgt = tgtResult.clip;
|
|
35
|
+
var copied = 0;
|
|
36
|
+
var effectFilter = ${args.effect_name ? `"${escapeForExtendScript(args.effect_name)}"` : "null"};
|
|
37
|
+
var intrinsic = ["Motion", "Opacity", "Time Remapping", "Volume", "Channel Volume", "Panner"];
|
|
38
|
+
|
|
39
|
+
// Use QE to copy effects by name
|
|
40
|
+
var qeSeq = qe.project.getActiveSequence();
|
|
41
|
+
var tgtTrackType = tgtResult.trackType;
|
|
42
|
+
var tgtTrack = tgtTrackType === "video"
|
|
43
|
+
? qeSeq.getVideoTrackAt(tgtResult.trackIndex)
|
|
44
|
+
: qeSeq.getAudioTrackAt(tgtResult.trackIndex);
|
|
45
|
+
var qeTgtClip = tgtTrack.getItemAt(tgtResult.clipIndex);
|
|
46
|
+
|
|
47
|
+
for (var i = 0; i < src.components.numItems; i++) {
|
|
48
|
+
var comp = src.components[i];
|
|
49
|
+
var name = comp.displayName;
|
|
50
|
+
|
|
51
|
+
if (effectFilter && name !== effectFilter) continue;
|
|
52
|
+
if (!effectFilter) {
|
|
53
|
+
var skip = false;
|
|
54
|
+
for (var k = 0; k < intrinsic.length; k++) {
|
|
55
|
+
if (name === intrinsic[k]) { skip = true; break; }
|
|
56
|
+
}
|
|
57
|
+
if (skip) continue;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Apply effect via QE
|
|
61
|
+
try {
|
|
62
|
+
var qeEffect = tgtTrackType === "video"
|
|
63
|
+
? qe.project.getVideoEffectByName(name)
|
|
64
|
+
: qe.project.getAudioEffectByName(name);
|
|
65
|
+
if (qeEffect) {
|
|
66
|
+
if (tgtTrackType === "video") {
|
|
67
|
+
qeTgtClip.addVideoEffect(qeEffect);
|
|
68
|
+
} else {
|
|
69
|
+
qeTgtClip.addAudioEffect(qeEffect);
|
|
70
|
+
}
|
|
71
|
+
copied++;
|
|
72
|
+
}
|
|
73
|
+
} catch(e) {}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return __result({ copiedEffects: copied, source: src.name, target: tgt.name });
|
|
77
77
|
`);
|
|
78
78
|
return sendCommand(script, bridgeOptions);
|
|
79
79
|
},
|
|
@@ -99,46 +99,46 @@ export function getClipboardTools(bridgeOptions) {
|
|
|
99
99
|
required: ["source_node_id", "target_node_id", "effect_name"],
|
|
100
100
|
},
|
|
101
101
|
handler: async (args) => {
|
|
102
|
-
const script = buildToolScript(`
|
|
103
|
-
var srcResult = __findClip("${escapeForExtendScript(args.source_node_id)}");
|
|
104
|
-
if (!srcResult) return __error("Source clip not found");
|
|
105
|
-
var tgtResult = __findClip("${escapeForExtendScript(args.target_node_id)}");
|
|
106
|
-
if (!tgtResult) return __error("Target clip not found");
|
|
107
|
-
|
|
108
|
-
var srcComp = null;
|
|
109
|
-
var tgtComp = null;
|
|
110
|
-
for (var i = 0; i < srcResult.clip.components.numItems; i++) {
|
|
111
|
-
if (srcResult.clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}") {
|
|
112
|
-
srcComp = srcResult.clip.components[i];
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
if (!srcComp) return __error("Effect not found on source clip: ${escapeForExtendScript(args.effect_name)}");
|
|
117
|
-
|
|
118
|
-
for (var i = 0; i < tgtResult.clip.components.numItems; i++) {
|
|
119
|
-
if (tgtResult.clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}") {
|
|
120
|
-
tgtComp = tgtResult.clip.components[i];
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (!tgtComp) return __error("Effect not found on target clip: ${escapeForExtendScript(args.effect_name)}");
|
|
125
|
-
|
|
126
|
-
var copied = 0;
|
|
127
|
-
for (var p = 0; p < srcComp.properties.numItems; p++) {
|
|
128
|
-
var srcProp = srcComp.properties[p];
|
|
129
|
-
for (var q = 0; q < tgtComp.properties.numItems; q++) {
|
|
130
|
-
if (tgtComp.properties[q].displayName === srcProp.displayName) {
|
|
131
|
-
try {
|
|
132
|
-
var val = srcProp.getValue(0, 0);
|
|
133
|
-
tgtComp.properties[q].setValue(val, true);
|
|
134
|
-
copied++;
|
|
135
|
-
} catch(e) {}
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return __result({ copiedProperties: copied, effect: "${escapeForExtendScript(args.effect_name)}" });
|
|
102
|
+
const script = buildToolScript(`
|
|
103
|
+
var srcResult = __findClip("${escapeForExtendScript(args.source_node_id)}");
|
|
104
|
+
if (!srcResult) return __error("Source clip not found");
|
|
105
|
+
var tgtResult = __findClip("${escapeForExtendScript(args.target_node_id)}");
|
|
106
|
+
if (!tgtResult) return __error("Target clip not found");
|
|
107
|
+
|
|
108
|
+
var srcComp = null;
|
|
109
|
+
var tgtComp = null;
|
|
110
|
+
for (var i = 0; i < srcResult.clip.components.numItems; i++) {
|
|
111
|
+
if (srcResult.clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}") {
|
|
112
|
+
srcComp = srcResult.clip.components[i];
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (!srcComp) return __error("Effect not found on source clip: ${escapeForExtendScript(args.effect_name)}");
|
|
117
|
+
|
|
118
|
+
for (var i = 0; i < tgtResult.clip.components.numItems; i++) {
|
|
119
|
+
if (tgtResult.clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}") {
|
|
120
|
+
tgtComp = tgtResult.clip.components[i];
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (!tgtComp) return __error("Effect not found on target clip: ${escapeForExtendScript(args.effect_name)}");
|
|
125
|
+
|
|
126
|
+
var copied = 0;
|
|
127
|
+
for (var p = 0; p < srcComp.properties.numItems; p++) {
|
|
128
|
+
var srcProp = srcComp.properties[p];
|
|
129
|
+
for (var q = 0; q < tgtComp.properties.numItems; q++) {
|
|
130
|
+
if (tgtComp.properties[q].displayName === srcProp.displayName) {
|
|
131
|
+
try {
|
|
132
|
+
var val = srcProp.getValue(0, 0);
|
|
133
|
+
tgtComp.properties[q].setValue(val, true);
|
|
134
|
+
copied++;
|
|
135
|
+
} catch(e) {}
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return __result({ copiedProperties: copied, effect: "${escapeForExtendScript(args.effect_name)}" });
|
|
142
142
|
`);
|
|
143
143
|
return sendCommand(script, bridgeOptions);
|
|
144
144
|
},
|
|
@@ -160,26 +160,26 @@ export function getClipboardTools(bridgeOptions) {
|
|
|
160
160
|
required: ["clip_node_id", "new_item_id"],
|
|
161
161
|
},
|
|
162
162
|
handler: async (args) => {
|
|
163
|
-
const script = buildToolScript(`
|
|
164
|
-
var clipResult = __findClip("${escapeForExtendScript(args.clip_node_id)}");
|
|
165
|
-
if (!clipResult) return __error("Clip not found");
|
|
166
|
-
var newItem = __findProjectItem("${escapeForExtendScript(args.new_item_id)}");
|
|
167
|
-
if (!newItem) return __error("New project item not found: ${escapeForExtendScript(args.new_item_id)}");
|
|
168
|
-
|
|
169
|
-
var clip = clipResult.clip;
|
|
170
|
-
var seq = app.project.activeSequence;
|
|
171
|
-
var startTicks = clip.start.ticks.toString();
|
|
172
|
-
var trackType = clipResult.trackType;
|
|
173
|
-
var trackIndex = clipResult.trackIndex;
|
|
174
|
-
|
|
175
|
-
// Overwrite at the same position with new media
|
|
176
|
-
if (trackType === "video") {
|
|
177
|
-
seq.overwriteClip(newItem, startTicks, trackIndex, -1);
|
|
178
|
-
} else {
|
|
179
|
-
seq.overwriteClip(newItem, startTicks, -1, trackIndex);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return __result({ replaced: true, clipName: clip.name, newSource: newItem.name });
|
|
163
|
+
const script = buildToolScript(`
|
|
164
|
+
var clipResult = __findClip("${escapeForExtendScript(args.clip_node_id)}");
|
|
165
|
+
if (!clipResult) return __error("Clip not found");
|
|
166
|
+
var newItem = __findProjectItem("${escapeForExtendScript(args.new_item_id)}");
|
|
167
|
+
if (!newItem) return __error("New project item not found: ${escapeForExtendScript(args.new_item_id)}");
|
|
168
|
+
|
|
169
|
+
var clip = clipResult.clip;
|
|
170
|
+
var seq = app.project.activeSequence;
|
|
171
|
+
var startTicks = clip.start.ticks.toString();
|
|
172
|
+
var trackType = clipResult.trackType;
|
|
173
|
+
var trackIndex = clipResult.trackIndex;
|
|
174
|
+
|
|
175
|
+
// Overwrite at the same position with new media
|
|
176
|
+
if (trackType === "video") {
|
|
177
|
+
seq.overwriteClip(newItem, startTicks, trackIndex, -1);
|
|
178
|
+
} else {
|
|
179
|
+
seq.overwriteClip(newItem, startTicks, -1, trackIndex);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return __result({ replaced: true, clipName: clip.name, newSource: newItem.name });
|
|
183
183
|
`);
|
|
184
184
|
return sendCommand(script, bridgeOptions);
|
|
185
185
|
},
|
|
@@ -211,66 +211,66 @@ export function getClipboardTools(bridgeOptions) {
|
|
|
211
211
|
required: ["effect_name", "target"],
|
|
212
212
|
},
|
|
213
213
|
handler: async (args) => {
|
|
214
|
-
const script = buildToolScript(`
|
|
215
|
-
app.enableQE();
|
|
216
|
-
var seq = app.project.activeSequence;
|
|
217
|
-
if (!seq) return __error("No active sequence");
|
|
218
|
-
var qeSeq = qe.project.getActiveSequence();
|
|
219
|
-
|
|
220
|
-
var effectName = "${escapeForExtendScript(args.effect_name)}";
|
|
221
|
-
var qeEffect = qe.project.getVideoEffectByName(effectName);
|
|
222
|
-
var isAudio = false;
|
|
223
|
-
if (!qeEffect) {
|
|
224
|
-
qeEffect = qe.project.getAudioEffectByName(effectName);
|
|
225
|
-
isAudio = true;
|
|
226
|
-
}
|
|
227
|
-
if (!qeEffect) return __error("Effect not found: " + effectName);
|
|
228
|
-
|
|
229
|
-
var applied = 0;
|
|
230
|
-
var target = "${args.target}";
|
|
231
|
-
|
|
232
|
-
function applyToClip(trackIdx, clipIdx, trackType) {
|
|
233
|
-
try {
|
|
234
|
-
var qeTrack = trackType === "video" ? qeSeq.getVideoTrackAt(trackIdx) : qeSeq.getAudioTrackAt(trackIdx);
|
|
235
|
-
var qeClip = qeTrack.getItemAt(clipIdx);
|
|
236
|
-
if (isAudio || trackType === "audio") {
|
|
237
|
-
qeClip.addAudioEffect(qeEffect);
|
|
238
|
-
} else {
|
|
239
|
-
qeClip.addVideoEffect(qeEffect);
|
|
240
|
-
}
|
|
241
|
-
applied++;
|
|
242
|
-
} catch(e) {}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (target === "selected") {
|
|
246
|
-
for (var t = 0; t < seq.videoTracks.numTracks; t++) {
|
|
247
|
-
for (var c = 0; c < seq.videoTracks[t].clips.numItems; c++) {
|
|
248
|
-
if (seq.videoTracks[t].clips[c].isSelected()) applyToClip(t, c, "video");
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
for (var t = 0; t < seq.audioTracks.numTracks; t++) {
|
|
252
|
-
for (var c = 0; c < seq.audioTracks[t].clips.numItems; c++) {
|
|
253
|
-
if (seq.audioTracks[t].clips[c].isSelected()) applyToClip(t, c, "audio");
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
} else if (target === "track") {
|
|
257
|
-
var tt = "${args.track_type || "video"}";
|
|
258
|
-
var ti = ${args.track_index ?? 0};
|
|
259
|
-
var tracks = tt === "video" ? seq.videoTracks : seq.audioTracks;
|
|
260
|
-
if (ti >= tracks.numTracks) return __error("Track index out of range");
|
|
261
|
-
for (var c = 0; c < tracks[ti].clips.numItems; c++) {
|
|
262
|
-
applyToClip(ti, c, tt);
|
|
263
|
-
}
|
|
264
|
-
} else {
|
|
265
|
-
for (var t = 0; t < seq.videoTracks.numTracks; t++) {
|
|
266
|
-
for (var c = 0; c < seq.videoTracks[t].clips.numItems; c++) applyToClip(t, c, "video");
|
|
267
|
-
}
|
|
268
|
-
for (var t = 0; t < seq.audioTracks.numTracks; t++) {
|
|
269
|
-
for (var c = 0; c < seq.audioTracks[t].clips.numItems; c++) applyToClip(t, c, "audio");
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return __result({ applied: applied, effect: effectName, target: target });
|
|
214
|
+
const script = buildToolScript(`
|
|
215
|
+
app.enableQE();
|
|
216
|
+
var seq = app.project.activeSequence;
|
|
217
|
+
if (!seq) return __error("No active sequence");
|
|
218
|
+
var qeSeq = qe.project.getActiveSequence();
|
|
219
|
+
|
|
220
|
+
var effectName = "${escapeForExtendScript(args.effect_name)}";
|
|
221
|
+
var qeEffect = qe.project.getVideoEffectByName(effectName);
|
|
222
|
+
var isAudio = false;
|
|
223
|
+
if (!qeEffect) {
|
|
224
|
+
qeEffect = qe.project.getAudioEffectByName(effectName);
|
|
225
|
+
isAudio = true;
|
|
226
|
+
}
|
|
227
|
+
if (!qeEffect) return __error("Effect not found: " + effectName);
|
|
228
|
+
|
|
229
|
+
var applied = 0;
|
|
230
|
+
var target = "${args.target}";
|
|
231
|
+
|
|
232
|
+
function applyToClip(trackIdx, clipIdx, trackType) {
|
|
233
|
+
try {
|
|
234
|
+
var qeTrack = trackType === "video" ? qeSeq.getVideoTrackAt(trackIdx) : qeSeq.getAudioTrackAt(trackIdx);
|
|
235
|
+
var qeClip = qeTrack.getItemAt(clipIdx);
|
|
236
|
+
if (isAudio || trackType === "audio") {
|
|
237
|
+
qeClip.addAudioEffect(qeEffect);
|
|
238
|
+
} else {
|
|
239
|
+
qeClip.addVideoEffect(qeEffect);
|
|
240
|
+
}
|
|
241
|
+
applied++;
|
|
242
|
+
} catch(e) {}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (target === "selected") {
|
|
246
|
+
for (var t = 0; t < seq.videoTracks.numTracks; t++) {
|
|
247
|
+
for (var c = 0; c < seq.videoTracks[t].clips.numItems; c++) {
|
|
248
|
+
if (seq.videoTracks[t].clips[c].isSelected()) applyToClip(t, c, "video");
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
for (var t = 0; t < seq.audioTracks.numTracks; t++) {
|
|
252
|
+
for (var c = 0; c < seq.audioTracks[t].clips.numItems; c++) {
|
|
253
|
+
if (seq.audioTracks[t].clips[c].isSelected()) applyToClip(t, c, "audio");
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
} else if (target === "track") {
|
|
257
|
+
var tt = "${args.track_type || "video"}";
|
|
258
|
+
var ti = ${args.track_index ?? 0};
|
|
259
|
+
var tracks = tt === "video" ? seq.videoTracks : seq.audioTracks;
|
|
260
|
+
if (ti >= tracks.numTracks) return __error("Track index out of range");
|
|
261
|
+
for (var c = 0; c < tracks[ti].clips.numItems; c++) {
|
|
262
|
+
applyToClip(ti, c, tt);
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
for (var t = 0; t < seq.videoTracks.numTracks; t++) {
|
|
266
|
+
for (var c = 0; c < seq.videoTracks[t].clips.numItems; c++) applyToClip(t, c, "video");
|
|
267
|
+
}
|
|
268
|
+
for (var t = 0; t < seq.audioTracks.numTracks; t++) {
|
|
269
|
+
for (var c = 0; c < seq.audioTracks[t].clips.numItems; c++) applyToClip(t, c, "audio");
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return __result({ applied: applied, effect: effectName, target: target });
|
|
274
274
|
`);
|
|
275
275
|
return sendCommand(script, bridgeOptions);
|
|
276
276
|
},
|
|
@@ -292,22 +292,22 @@ export function getClipboardTools(bridgeOptions) {
|
|
|
292
292
|
required: ["node_id", "effect_name"],
|
|
293
293
|
},
|
|
294
294
|
handler: async (args) => {
|
|
295
|
-
const script = buildToolScript(`
|
|
296
|
-
var result = __findClip("${escapeForExtendScript(args.node_id)}");
|
|
297
|
-
if (!result) return __error("Clip not found");
|
|
298
|
-
|
|
299
|
-
var clip = result.clip;
|
|
300
|
-
var removed = 0;
|
|
301
|
-
// Iterate backwards to avoid index issues when removing
|
|
302
|
-
for (var i = clip.components.numItems - 1; i >= 0; i--) {
|
|
303
|
-
if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}") {
|
|
304
|
-
clip.components[i].remove();
|
|
305
|
-
removed++;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
if (removed === 0) return __error("Effect not found: ${escapeForExtendScript(args.effect_name)}");
|
|
310
|
-
return __result({ removed: removed, effect: "${escapeForExtendScript(args.effect_name)}", clip: clip.name });
|
|
295
|
+
const script = buildToolScript(`
|
|
296
|
+
var result = __findClip("${escapeForExtendScript(args.node_id)}");
|
|
297
|
+
if (!result) return __error("Clip not found");
|
|
298
|
+
|
|
299
|
+
var clip = result.clip;
|
|
300
|
+
var removed = 0;
|
|
301
|
+
// Iterate backwards to avoid index issues when removing
|
|
302
|
+
for (var i = clip.components.numItems - 1; i >= 0; i--) {
|
|
303
|
+
if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}") {
|
|
304
|
+
clip.components[i].remove();
|
|
305
|
+
removed++;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (removed === 0) return __error("Effect not found: ${escapeForExtendScript(args.effect_name)}");
|
|
310
|
+
return __result({ removed: removed, effect: "${escapeForExtendScript(args.effect_name)}", clip: clip.name });
|
|
311
311
|
`);
|
|
312
312
|
return sendCommand(script, bridgeOptions);
|
|
313
313
|
},
|
|
@@ -345,33 +345,33 @@ export function getClipboardTools(bridgeOptions) {
|
|
|
345
345
|
"Hue": 24, "Saturation": 25, "Color": 26, "Luminosity": 27
|
|
346
346
|
};
|
|
347
347
|
const modeValue = blendModeMap[args.blend_mode] ?? 1;
|
|
348
|
-
const script = buildToolScript(`
|
|
349
|
-
var result = __findClip("${escapeForExtendScript(args.node_id)}");
|
|
350
|
-
if (!result) return __error("Clip not found");
|
|
351
|
-
|
|
352
|
-
var clip = result.clip;
|
|
353
|
-
var comp = __findIntrinsic(clip, "opacity");
|
|
354
|
-
if (!comp) return __error("Could not find Opacity component on clip");
|
|
355
|
-
|
|
356
|
-
var prop = __findProp(comp, ["Blend Mode", "Modo de fusión", "Mischmodus"]);
|
|
357
|
-
if (!prop) return __error("Could not find Blend Mode property on Opacity component");
|
|
358
|
-
|
|
359
|
-
var applied = false;
|
|
360
|
-
var note = "Blend mode enum ordering can vary by Premiere version/locale; if the visual result is wrong, the numeric mapping may differ for this version.";
|
|
361
|
-
try {
|
|
362
|
-
prop.setValue(${modeValue}, true);
|
|
363
|
-
applied = true;
|
|
364
|
-
} catch(e) {
|
|
365
|
-
note = "setValue failed: " + e.toString() + ". " + note;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
return __result({
|
|
369
|
-
blendMode: "${escapeForExtendScript(args.blend_mode)}",
|
|
370
|
-
enumValue: ${modeValue},
|
|
371
|
-
applied: applied,
|
|
372
|
-
note: note,
|
|
373
|
-
clip: clip.name
|
|
374
|
-
});
|
|
348
|
+
const script = buildToolScript(`
|
|
349
|
+
var result = __findClip("${escapeForExtendScript(args.node_id)}");
|
|
350
|
+
if (!result) return __error("Clip not found");
|
|
351
|
+
|
|
352
|
+
var clip = result.clip;
|
|
353
|
+
var comp = __findIntrinsic(clip, "opacity");
|
|
354
|
+
if (!comp) return __error("Could not find Opacity component on clip");
|
|
355
|
+
|
|
356
|
+
var prop = __findProp(comp, ["Blend Mode", "Modo de fusión", "Mischmodus"]);
|
|
357
|
+
if (!prop) return __error("Could not find Blend Mode property on Opacity component");
|
|
358
|
+
|
|
359
|
+
var applied = false;
|
|
360
|
+
var note = "Blend mode enum ordering can vary by Premiere version/locale; if the visual result is wrong, the numeric mapping may differ for this version.";
|
|
361
|
+
try {
|
|
362
|
+
prop.setValue(${modeValue}, true);
|
|
363
|
+
applied = true;
|
|
364
|
+
} catch(e) {
|
|
365
|
+
note = "setValue failed: " + e.toString() + ". " + note;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return __result({
|
|
369
|
+
blendMode: "${escapeForExtendScript(args.blend_mode)}",
|
|
370
|
+
enumValue: ${modeValue},
|
|
371
|
+
applied: applied,
|
|
372
|
+
note: note,
|
|
373
|
+
clip: clip.name
|
|
374
|
+
});
|
|
375
375
|
`);
|
|
376
376
|
return sendCommand(script, bridgeOptions);
|
|
377
377
|
},
|