premiere-cli 0.2.0__py3-none-any.whl
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.
- premiere_cli/__init__.py +11 -0
- premiere_cli/cli.py +3664 -0
- premiere_cli/log.py +66 -0
- premiere_cli/panel/.debug +8 -0
- premiere_cli/panel/CSXS/manifest.xml +52 -0
- premiere_cli/panel/css/style.css +53 -0
- premiere_cli/panel/host/commands/add-adjustment-layer.jsx +190 -0
- premiere_cli/panel/host/commands/add-audio-keyframes.jsx +176 -0
- premiere_cli/panel/host/commands/add-custom-metadata-field.jsx +63 -0
- premiere_cli/panel/host/commands/add-keyframe.jsx +181 -0
- premiere_cli/panel/host/commands/add-marker-to-project-item.jsx +194 -0
- premiere_cli/panel/host/commands/add-marker.jsx +129 -0
- premiere_cli/panel/host/commands/add-text-overlay.jsx +101 -0
- premiere_cli/panel/host/commands/add-to-render-queue.jsx +120 -0
- premiere_cli/panel/host/commands/add-to-timeline.jsx +300 -0
- premiere_cli/panel/host/commands/add-track.jsx +188 -0
- premiere_cli/panel/host/commands/add-transition.jsx +134 -0
- premiere_cli/panel/host/commands/adjust-audio-levels.jsx +132 -0
- premiere_cli/panel/host/commands/apply-audio-effect.jsx +118 -0
- premiere_cli/panel/host/commands/apply-effect.jsx +122 -0
- premiere_cli/panel/host/commands/apply-lut.jsx +107 -0
- premiere_cli/panel/host/commands/attach-custom-property.jsx +66 -0
- premiere_cli/panel/host/commands/auto-reframe-sequence.jsx +124 -0
- premiere_cli/panel/host/commands/batch-add-transitions.jsx +158 -0
- premiere_cli/panel/host/commands/batch-apply-effect.jsx +182 -0
- premiere_cli/panel/host/commands/batch-rename-clips.jsx +170 -0
- premiere_cli/panel/host/commands/batch-set-clips-enabled.jsx +145 -0
- premiere_cli/panel/host/commands/clear-item-in-out.jsx +117 -0
- premiere_cli/panel/host/commands/clear-sequence-in-out.jsx +100 -0
- premiere_cli/panel/host/commands/close-all-source-clips.jsx +32 -0
- premiere_cli/panel/host/commands/close-sequence.jsx +80 -0
- premiere_cli/panel/host/commands/close-source-monitor.jsx +32 -0
- premiere_cli/panel/host/commands/color-correct.jsx +164 -0
- premiere_cli/panel/host/commands/copy-effect-values.jsx +183 -0
- premiere_cli/panel/host/commands/copy-effects-between-clips.jsx +234 -0
- premiere_cli/panel/host/commands/create-bars-and-tone.jsx +152 -0
- premiere_cli/panel/host/commands/create-bin.jsx +76 -0
- premiere_cli/panel/host/commands/create-caption-track.jsx +159 -0
- premiere_cli/panel/host/commands/create-sequence-from-clips.jsx +170 -0
- premiere_cli/panel/host/commands/create-sequence-from-preset.jsx +90 -0
- premiere_cli/panel/host/commands/create-sequence.jsx +166 -0
- premiere_cli/panel/host/commands/create-smart-bin.jsx +80 -0
- premiere_cli/panel/host/commands/create-subclip.jsx +248 -0
- premiere_cli/panel/host/commands/create-subsequence.jsx +136 -0
- premiere_cli/panel/host/commands/debug-qe-inspect.jsx +248 -0
- premiere_cli/panel/host/commands/debug-qe-try-mutate.jsx +305 -0
- premiere_cli/panel/host/commands/delete-marker.jsx +178 -0
- premiere_cli/panel/host/commands/deselect-all-clips.jsx +98 -0
- premiere_cli/panel/host/commands/detach-proxy.jsx +116 -0
- premiere_cli/panel/host/commands/duplicate-clip.jsx +140 -0
- premiere_cli/panel/host/commands/duplicate-sequence.jsx +150 -0
- premiere_cli/panel/host/commands/encode-file.jsx +86 -0
- premiere_cli/panel/host/commands/encode-project-item.jsx +145 -0
- premiere_cli/panel/host/commands/export-aaf.jsx +77 -0
- premiere_cli/panel/host/commands/export-fcp-xml.jsx +65 -0
- premiere_cli/panel/host/commands/export-frame.jsx +381 -0
- premiere_cli/panel/host/commands/export-omf.jsx +95 -0
- premiere_cli/panel/host/commands/export-sequence-as-project.jsx +65 -0
- premiere_cli/panel/host/commands/export-sequence.jsx +100 -0
- premiere_cli/panel/host/commands/extract-audio-track.jsx +181 -0
- premiere_cli/panel/host/commands/extract-selection.jsx +113 -0
- premiere_cli/panel/host/commands/find-items-by-media-path.jsx +112 -0
- premiere_cli/panel/host/commands/freeze-frame.jsx +215 -0
- premiere_cli/panel/host/commands/get-active-sequence.jsx +103 -0
- premiere_cli/panel/host/commands/get-all-project-paths.jsx +72 -0
- premiere_cli/panel/host/commands/get-bin-contents.jsx +176 -0
- premiere_cli/panel/host/commands/get-clip-adjustment-layer.jsx +83 -0
- premiere_cli/panel/host/commands/get-clip-at-playhead.jsx +99 -0
- premiere_cli/panel/host/commands/get-clip-at-position.jsx +120 -0
- premiere_cli/panel/host/commands/get-clip-links.jsx +135 -0
- premiere_cli/panel/host/commands/get-clip-markers.jsx +144 -0
- premiere_cli/panel/host/commands/get-clip-speed.jsx +69 -0
- premiere_cli/panel/host/commands/get-color-label.jsx +89 -0
- premiere_cli/panel/host/commands/get-color-space.jsx +99 -0
- premiere_cli/panel/host/commands/get-duplicate-media.jsx +78 -0
- premiere_cli/panel/host/commands/get-effect-properties.jsx +129 -0
- premiere_cli/panel/host/commands/get-encoder-presets.jsx +131 -0
- premiere_cli/panel/host/commands/get-export-file-extension.jsx +56 -0
- premiere_cli/panel/host/commands/get-footage-interpretation.jsx +113 -0
- premiere_cli/panel/host/commands/get-full-clip-info.jsx +162 -0
- premiere_cli/panel/host/commands/get-full-project-overview.jsx +193 -0
- premiere_cli/panel/host/commands/get-full-sequence-info.jsx +184 -0
- premiere_cli/panel/host/commands/get-graphics-white-luminance.jsx +31 -0
- premiere_cli/panel/host/commands/get-insertion-bin.jsx +35 -0
- premiere_cli/panel/host/commands/get-item-metadata.jsx +94 -0
- premiere_cli/panel/host/commands/get-keyframes.jsx +158 -0
- premiere_cli/panel/host/commands/get-mogrt-component.jsx +111 -0
- premiere_cli/panel/host/commands/get-next-edit-point.jsx +131 -0
- premiere_cli/panel/host/commands/get-offline-media.jsx +67 -0
- premiere_cli/panel/host/commands/get-open-projects.jsx +50 -0
- premiere_cli/panel/host/commands/get-premiere-state.jsx +164 -0
- premiere_cli/panel/host/commands/get-project-info.jsx +63 -0
- premiere_cli/panel/host/commands/get-project-item-info.jsx +247 -0
- premiere_cli/panel/host/commands/get-project-panel-metadata.jsx +30 -0
- premiere_cli/panel/host/commands/get-qe-clip-info.jsx +198 -0
- premiere_cli/panel/host/commands/get-render-queue-status.jsx +35 -0
- premiere_cli/panel/host/commands/get-sequence-count.jsx +24 -0
- premiere_cli/panel/host/commands/get-sequence-in-out.jsx +76 -0
- premiere_cli/panel/host/commands/get-sequence-markers-by-type.jsx +89 -0
- premiere_cli/panel/host/commands/get-source-monitor-info.jsx +34 -0
- premiere_cli/panel/host/commands/get-source-monitor-position.jsx +30 -0
- premiere_cli/panel/host/commands/get-target-tracks.jsx +76 -0
- premiere_cli/panel/host/commands/get-timeline-gaps.jsx +124 -0
- premiere_cli/panel/host/commands/get-timeline-summary.jsx +154 -0
- premiere_cli/panel/host/commands/get-total-clip-count.jsx +67 -0
- premiere_cli/panel/host/commands/get-track-info.jsx +117 -0
- premiere_cli/panel/host/commands/get-unused-media.jsx +99 -0
- premiere_cli/panel/host/commands/get-used-media-report.jsx +125 -0
- premiere_cli/panel/host/commands/get-value-at-time.jsx +135 -0
- premiere_cli/panel/host/commands/get-version-info.jsx +33 -0
- premiere_cli/panel/host/commands/get-work-area.jsx +52 -0
- premiere_cli/panel/host/commands/get-workspaces.jsx +29 -0
- premiere_cli/panel/host/commands/get-xmp-metadata.jsx +107 -0
- premiere_cli/panel/host/commands/import-ae-comps.jsx +129 -0
- premiere_cli/panel/host/commands/import-fcp-xml.jsx +103 -0
- premiere_cli/panel/host/commands/import-folder.jsx +193 -0
- premiere_cli/panel/host/commands/import-image-sequence.jsx +171 -0
- premiere_cli/panel/host/commands/import-media.jsx +217 -0
- premiere_cli/panel/host/commands/import-mogrt-from-library.jsx +105 -0
- premiere_cli/panel/host/commands/import-mogrt.jsx +111 -0
- premiere_cli/panel/host/commands/import-sequences-from-project.jsx +80 -0
- premiere_cli/panel/host/commands/insert-from-source.jsx +162 -0
- premiere_cli/panel/host/commands/inspect-dom-object.jsx +162 -0
- premiere_cli/panel/host/commands/invert-selection.jsx +114 -0
- premiere_cli/panel/host/commands/is-work-area-enabled.jsx +88 -0
- premiere_cli/panel/host/commands/lift-selection.jsx +106 -0
- premiere_cli/panel/host/commands/link-selection.jsx +111 -0
- premiere_cli/panel/host/commands/list-available-audio-effects.jsx +33 -0
- premiere_cli/panel/host/commands/list-available-audio-transitions.jsx +35 -0
- premiere_cli/panel/host/commands/list-available-effects.jsx +33 -0
- premiere_cli/panel/host/commands/list-available-transitions.jsx +74 -0
- premiere_cli/panel/host/commands/list-markers.jsx +69 -0
- premiere_cli/panel/host/commands/list-project-items.jsx +105 -0
- premiere_cli/panel/host/commands/lock-track.jsx +114 -0
- premiere_cli/panel/host/commands/manage-proxies.jsx +176 -0
- premiere_cli/panel/host/commands/match-frame.jsx +141 -0
- premiere_cli/panel/host/commands/move-clip-to-track.jsx +220 -0
- premiere_cli/panel/host/commands/move-clip.jsx +97 -0
- premiere_cli/panel/host/commands/move-items-to-bin.jsx +194 -0
- premiere_cli/panel/host/commands/move-playhead-to-edit.jsx +174 -0
- premiere_cli/panel/host/commands/move-playhead.jsx +137 -0
- premiere_cli/panel/host/commands/nest-clips.jsx +179 -0
- premiere_cli/panel/host/commands/open-in-source.jsx +117 -0
- premiere_cli/panel/host/commands/open-project.jsx +61 -0
- premiere_cli/panel/host/commands/overwrite-clip-at.jsx +350 -0
- premiere_cli/panel/host/commands/overwrite-from-source.jsx +150 -0
- premiere_cli/panel/host/commands/play-source-monitor.jsx +36 -0
- premiere_cli/panel/host/commands/play-timeline.jsx +24 -0
- premiere_cli/panel/host/commands/razor-all-tracks.jsx +171 -0
- premiere_cli/panel/host/commands/redo.jsx +69 -0
- premiere_cli/panel/host/commands/refresh-media.jsx +101 -0
- premiere_cli/panel/host/commands/relink-media.jsx +132 -0
- premiere_cli/panel/host/commands/remove-all-effects.jsx +114 -0
- premiere_cli/panel/host/commands/remove-effect-by-name.jsx +143 -0
- premiere_cli/panel/host/commands/remove-effect.jsx +122 -0
- premiere_cli/panel/host/commands/remove-from-timeline.jsx +93 -0
- premiere_cli/panel/host/commands/remove-keyframe-range.jsx +173 -0
- premiere_cli/panel/host/commands/remove-keyframe.jsx +192 -0
- premiere_cli/panel/host/commands/remove-selected-clips.jsx +126 -0
- premiere_cli/panel/host/commands/remove-track-intervals.jsx +254 -0
- premiere_cli/panel/host/commands/remove-transition.jsx +164 -0
- premiere_cli/panel/host/commands/rename-bin.jsx +88 -0
- premiere_cli/panel/host/commands/rename-clip.jsx +127 -0
- premiere_cli/panel/host/commands/rename-project-item.jsx +111 -0
- premiere_cli/panel/host/commands/rename-track.jsx +84 -0
- premiere_cli/panel/host/commands/replace-clip-media.jsx +140 -0
- premiere_cli/panel/host/commands/replace-clip.jsx +188 -0
- premiere_cli/panel/host/commands/reverse-clip.jsx +187 -0
- premiere_cli/panel/host/commands/ripple-delete-clip.jsx +156 -0
- premiere_cli/panel/host/commands/roll-edit.jsx +162 -0
- premiere_cli/panel/host/commands/save-project-as.jsx +55 -0
- premiere_cli/panel/host/commands/save-project.jsx +57 -0
- premiere_cli/panel/host/commands/scene-edit-detection.jsx +128 -0
- premiere_cli/panel/host/commands/search-project-items.jsx +180 -0
- premiere_cli/panel/host/commands/select-all-clips.jsx +107 -0
- premiere_cli/panel/host/commands/select-clips-by-color.jsx +142 -0
- premiere_cli/panel/host/commands/select-clips-by-name.jsx +133 -0
- premiere_cli/panel/host/commands/select-clips-in-range.jsx +133 -0
- premiere_cli/panel/host/commands/select-disabled-clips.jsx +127 -0
- premiere_cli/panel/host/commands/select-project-item.jsx +115 -0
- premiere_cli/panel/host/commands/set-active-project.jsx +184 -0
- premiere_cli/panel/host/commands/set-active-sequence.jsx +87 -0
- premiere_cli/panel/host/commands/set-all-tracks-targeted.jsx +112 -0
- premiere_cli/panel/host/commands/set-anti-alias-quality.jsx +125 -0
- premiere_cli/panel/host/commands/set-blend-mode.jsx +111 -0
- premiere_cli/panel/host/commands/set-clip-anchor-point.jsx +102 -0
- premiere_cli/panel/host/commands/set-clip-enabled.jsx +127 -0
- premiere_cli/panel/host/commands/set-clip-opacity.jsx +102 -0
- premiere_cli/panel/host/commands/set-clip-pan.jsx +107 -0
- premiere_cli/panel/host/commands/set-clip-position.jsx +103 -0
- premiere_cli/panel/host/commands/set-clip-properties.jsx +221 -0
- premiere_cli/panel/host/commands/set-clip-rotation.jsx +102 -0
- premiere_cli/panel/host/commands/set-clip-scale.jsx +102 -0
- premiere_cli/panel/host/commands/set-clip-selection.jsx +144 -0
- premiere_cli/panel/host/commands/set-clip-speed.jsx +160 -0
- premiere_cli/panel/host/commands/set-clip-volume.jsx +128 -0
- premiere_cli/panel/host/commands/set-color-label.jsx +123 -0
- premiere_cli/panel/host/commands/set-color-value.jsx +155 -0
- premiere_cli/panel/host/commands/set-effect-property.jsx +124 -0
- premiere_cli/panel/host/commands/set-footage-interpretation.jsx +173 -0
- premiere_cli/panel/host/commands/set-frame-blend.jsx +145 -0
- premiere_cli/panel/host/commands/set-graphics-white-luminance.jsx +73 -0
- premiere_cli/panel/host/commands/set-item-in-out.jsx +180 -0
- premiere_cli/panel/host/commands/set-item-metadata.jsx +134 -0
- premiere_cli/panel/host/commands/set-item-offline.jsx +109 -0
- premiere_cli/panel/host/commands/set-item-start-time.jsx +139 -0
- premiere_cli/panel/host/commands/set-keyframe-interpolation.jsx +186 -0
- premiere_cli/panel/host/commands/set-override-frame-rate.jsx +123 -0
- premiere_cli/panel/host/commands/set-override-pixel-aspect-ratio.jsx +129 -0
- premiere_cli/panel/host/commands/set-poster-frame.jsx +192 -0
- premiere_cli/panel/host/commands/set-project-panel-metadata.jsx +69 -0
- premiere_cli/panel/host/commands/set-scale-to-frame-size.jsx +101 -0
- premiere_cli/panel/host/commands/set-scale-width-height.jsx +140 -0
- premiere_cli/panel/host/commands/set-sequence-in-out.jsx +65 -0
- premiere_cli/panel/host/commands/set-sequence-settings.jsx +184 -0
- premiere_cli/panel/host/commands/set-source-in-out.jsx +98 -0
- premiere_cli/panel/host/commands/set-target-track.jsx +91 -0
- premiere_cli/panel/host/commands/set-time-interpolation.jsx +141 -0
- premiere_cli/panel/host/commands/set-track-mute.jsx +91 -0
- premiere_cli/panel/host/commands/set-track-visibility.jsx +94 -0
- premiere_cli/panel/host/commands/set-transcode-on-ingest.jsx +78 -0
- premiere_cli/panel/host/commands/set-uniform-scale.jsx +104 -0
- premiere_cli/panel/host/commands/set-work-area.jsx +76 -0
- premiere_cli/panel/host/commands/set-workspace.jsx +35 -0
- premiere_cli/panel/host/commands/set-xmp-metadata.jsx +157 -0
- premiere_cli/panel/host/commands/slide-edit.jsx +162 -0
- premiere_cli/panel/host/commands/slip-edit.jsx +167 -0
- premiere_cli/panel/host/commands/split-clip.jsx +144 -0
- premiere_cli/panel/host/commands/stabilize-clip.jsx +139 -0
- premiere_cli/panel/host/commands/stop-playback.jsx +23 -0
- premiere_cli/panel/host/commands/trim-clip.jsx +111 -0
- premiere_cli/panel/host/commands/undo.jsx +114 -0
- premiere_cli/panel/host/commands/unlink-selection.jsx +106 -0
- premiere_cli/panel/host/commands/unnest-sequence.jsx +207 -0
- premiere_cli/panel/host/commands/update-marker.jsx +120 -0
- premiere_cli/panel/host/index.jsx +1227 -0
- premiere_cli/panel/host/presets/default-4k-25fps.sqpreset +63 -0
- premiere_cli/panel/index.html +16 -0
- premiere_cli/panel/js/cs-interface.js +11 -0
- premiere_cli/panel/js/main.js +409 -0
- premiere_cli/panel_install.py +220 -0
- premiere_cli-0.2.0.dist-info/METADATA +127 -0
- premiere_cli-0.2.0.dist-info/RECORD +247 -0
- premiere_cli-0.2.0.dist-info/WHEEL +5 -0
- premiere_cli-0.2.0.dist-info/entry_points.txt +3 -0
- premiere_cli-0.2.0.dist-info/licenses/LICENSE +428 -0
- premiere_cli-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// Command: set-active-project → ppb_setActiveProject
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (TICKS_PER_SECOND,
|
|
4
|
+
// ensureQEEnabled, findSequenceByName, ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Switches which currently-OPEN project (app.projects) is the active one
|
|
7
|
+
// (app.project). DESIGNED BUT NOT YET LIVE-VERIFIED: no reference repo we
|
|
8
|
+
// studied (see PREMIERE_API_NOTES.md) has a multi-open-project activation
|
|
9
|
+
// tool to copy — none of hetpatel/leancoderkavy/ayushozha's code touches
|
|
10
|
+
// app.projects at all, only the single app.project. The activation
|
|
11
|
+
// mechanism on this Premiere build is therefore genuinely uncertain: three
|
|
12
|
+
// candidate methods are tried in order, and success is verified AFTER each
|
|
13
|
+
// one by checking that app.project.path actually changed to the target's
|
|
14
|
+
// path — never by trusting a method's return value (same distrust pattern
|
|
15
|
+
// as export-frame.jsx's exportFramePNG guesses).
|
|
16
|
+
//
|
|
17
|
+
// Mutation caveats:
|
|
18
|
+
// - app.openDocument() is documented (PREMIERE_API_NOTES.md) as an
|
|
19
|
+
// "open project" call; its behavior when the target is ALREADY open is
|
|
20
|
+
// unconfirmed — it may simply foreground the existing project, or it
|
|
21
|
+
// may pop a dialog, or (worst case) re-open a second instance. This is
|
|
22
|
+
// a fallback guess, not a verified-safe operation.
|
|
23
|
+
// - The direct-assignment attempt (`app.project = target`) is a bare
|
|
24
|
+
// guess with no supporting reference anywhere in the three MCP repos
|
|
25
|
+
// studied — kept last, after the two better-attested attempts.
|
|
26
|
+
// - Live-test this against a real multi-project-open Premiere session
|
|
27
|
+
// before relying on it in an unattended workflow.
|
|
28
|
+
|
|
29
|
+
function ppb_setActiveProject(argsJson) {
|
|
30
|
+
try {
|
|
31
|
+
var args;
|
|
32
|
+
try {
|
|
33
|
+
args = JSON.parse(argsJson);
|
|
34
|
+
} catch (e) {
|
|
35
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
var hasName = !!(args.name && typeof args.name === "string");
|
|
39
|
+
var hasPath = !!(args.path && typeof args.path === "string");
|
|
40
|
+
if (!hasName && !hasPath) {
|
|
41
|
+
return JSON.stringify({ ok: false, error: "at least one of name or path is required" });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!app.projects || app.projects.numProjects === 0) {
|
|
45
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
var byPath = null;
|
|
49
|
+
var byName = null;
|
|
50
|
+
var availableProjects = [];
|
|
51
|
+
|
|
52
|
+
for (var i = 0; i < app.projects.numProjects; i++) {
|
|
53
|
+
var p = app.projects[i];
|
|
54
|
+
var pName = null;
|
|
55
|
+
var pPath = null;
|
|
56
|
+
try { pName = p.name; } catch (e) { pName = null; }
|
|
57
|
+
try { pPath = p.path; } catch (e) { pPath = null; }
|
|
58
|
+
|
|
59
|
+
if (pName !== null) {
|
|
60
|
+
availableProjects.push(pName);
|
|
61
|
+
}
|
|
62
|
+
if (hasPath && pPath !== null && pPath === args.path) {
|
|
63
|
+
byPath = p;
|
|
64
|
+
}
|
|
65
|
+
if (hasName && pName !== null && pName === args.name) {
|
|
66
|
+
byName = p;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var target = null;
|
|
71
|
+
if (hasName && hasPath) {
|
|
72
|
+
if (!byPath || !byName || byPath !== byName) {
|
|
73
|
+
return JSON.stringify({
|
|
74
|
+
ok: false,
|
|
75
|
+
error: "name and path did not resolve to the same open project",
|
|
76
|
+
availableProjects: availableProjects
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
target = byPath;
|
|
80
|
+
} else if (hasPath) {
|
|
81
|
+
target = byPath;
|
|
82
|
+
} else {
|
|
83
|
+
target = byName;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!target) {
|
|
87
|
+
var missingDesc = "";
|
|
88
|
+
if (hasName) { missingDesc += " name \"" + args.name + "\""; }
|
|
89
|
+
if (hasPath) { missingDesc += " path \"" + args.path + "\""; }
|
|
90
|
+
return JSON.stringify({
|
|
91
|
+
ok: false,
|
|
92
|
+
error: "no open project matched" + missingDesc,
|
|
93
|
+
availableProjects: availableProjects
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
var targetName = null;
|
|
98
|
+
var targetPath = null;
|
|
99
|
+
try { targetName = target.name; } catch (e) { targetName = null; }
|
|
100
|
+
try { targetPath = target.path; } catch (e) { targetPath = null; }
|
|
101
|
+
|
|
102
|
+
var currentPath = null;
|
|
103
|
+
try { currentPath = app.project ? app.project.path : null; } catch (e) { currentPath = null; }
|
|
104
|
+
|
|
105
|
+
if (targetPath !== null && currentPath !== null && targetPath === currentPath) {
|
|
106
|
+
return JSON.stringify({
|
|
107
|
+
ok: true,
|
|
108
|
+
result: { activated: { name: targetName, path: targetPath }, alreadyActive: true }
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function isNowActive() {
|
|
113
|
+
var curPath = null;
|
|
114
|
+
try { curPath = app.project ? app.project.path : null; } catch (e) { curPath = null; }
|
|
115
|
+
return targetPath !== null && curPath === targetPath;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
var attempts = [];
|
|
119
|
+
|
|
120
|
+
// --- Attempt 1: targetProject.activate(), if this build exposes it.
|
|
121
|
+
if (typeof target.activate === "function") {
|
|
122
|
+
try {
|
|
123
|
+
target.activate();
|
|
124
|
+
var success1 = isNowActive();
|
|
125
|
+
attempts.push({ method: "activate", success: success1 });
|
|
126
|
+
if (success1) {
|
|
127
|
+
return JSON.stringify({
|
|
128
|
+
ok: true,
|
|
129
|
+
result: { activated: { name: targetName, path: targetPath }, attempts: attempts }
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
} catch (e) {
|
|
133
|
+
attempts.push({ method: "activate", success: false, error: e.toString() });
|
|
134
|
+
}
|
|
135
|
+
} else {
|
|
136
|
+
attempts.push({ method: "activate", success: false, error: "target.activate is not a function on this Premiere build" });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// --- Attempt 2: app.openDocument(targetPath) — documented to open/
|
|
140
|
+
// foreground a project; on an already-open project its behavior is an
|
|
141
|
+
// unconfirmed fallback guess (see header comment).
|
|
142
|
+
if (targetPath !== null) {
|
|
143
|
+
try {
|
|
144
|
+
app.openDocument(targetPath);
|
|
145
|
+
var success2 = isNowActive();
|
|
146
|
+
attempts.push({ method: "openDocument", success: success2 });
|
|
147
|
+
if (success2) {
|
|
148
|
+
return JSON.stringify({
|
|
149
|
+
ok: true,
|
|
150
|
+
result: { activated: { name: targetName, path: targetPath }, attempts: attempts }
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
} catch (e) {
|
|
154
|
+
attempts.push({ method: "openDocument", success: false, error: e.toString() });
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
attempts.push({ method: "openDocument", success: false, error: "target project has no readable path" });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// --- Attempt 3: direct property assignment — a bare guess with no
|
|
161
|
+
// supporting reference in any studied repo, tried last.
|
|
162
|
+
try {
|
|
163
|
+
app.project = target;
|
|
164
|
+
var success3 = isNowActive();
|
|
165
|
+
attempts.push({ method: "directAssign", success: success3 });
|
|
166
|
+
if (success3) {
|
|
167
|
+
return JSON.stringify({
|
|
168
|
+
ok: true,
|
|
169
|
+
result: { activated: { name: targetName, path: targetPath }, attempts: attempts }
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
} catch (e) {
|
|
173
|
+
attempts.push({ method: "directAssign", success: false, error: e.toString() });
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return JSON.stringify({
|
|
177
|
+
ok: false,
|
|
178
|
+
error: "could not activate project \"" + (targetName || targetPath) + "\" with any known method",
|
|
179
|
+
attempts: attempts
|
|
180
|
+
});
|
|
181
|
+
} catch (e) {
|
|
182
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Command: set-active-sequence → ppb_setActiveSequence
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Ported from leancoderkavy/premiere-pro-mcp's project.ts
|
|
7
|
+
// set_active_sequence. Per PREMIERE_API_NOTES.md's Sequences table,
|
|
8
|
+
// activation has two documented forms — assignment
|
|
9
|
+
// (app.project.activeSequence = seq) and app.project.openSequence(seq.
|
|
10
|
+
// sequenceID) — both are tried in order (assignment first, matching the
|
|
11
|
+
// reference tool), each verified independently by re-reading
|
|
12
|
+
// app.project.activeSequence.name afterward rather than trusting either
|
|
13
|
+
// call's return value.
|
|
14
|
+
|
|
15
|
+
function ppb_setActiveSequence(argsJson) {
|
|
16
|
+
try {
|
|
17
|
+
var args;
|
|
18
|
+
try {
|
|
19
|
+
args = JSON.parse(argsJson);
|
|
20
|
+
} catch (e) {
|
|
21
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!args.sequenceName || typeof args.sequenceName !== "string") {
|
|
25
|
+
return JSON.stringify({ ok: false, error: "sequenceName is required" });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!app.project) {
|
|
29
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
var seq = findSequenceByName(args.sequenceName);
|
|
33
|
+
if (!seq) {
|
|
34
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" found in the project" });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function isNowActive() {
|
|
38
|
+
try {
|
|
39
|
+
return app.project.activeSequence && app.project.activeSequence.name === args.sequenceName;
|
|
40
|
+
} catch (e) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
var attempts = [];
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
app.project.activeSequence = seq;
|
|
49
|
+
var success1 = isNowActive();
|
|
50
|
+
attempts.push({ method: "activeSequenceAssign", success: success1 });
|
|
51
|
+
if (success1) {
|
|
52
|
+
return JSON.stringify({
|
|
53
|
+
ok: true,
|
|
54
|
+
result: { name: seq.name, sequenceID: seq.sequenceID, attempts: attempts }
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
} catch (e) {
|
|
58
|
+
attempts.push({ method: "activeSequenceAssign", success: false, error: e.toString() });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (typeof app.project.openSequence === "function") {
|
|
62
|
+
try {
|
|
63
|
+
app.project.openSequence(seq.sequenceID);
|
|
64
|
+
var success2 = isNowActive();
|
|
65
|
+
attempts.push({ method: "openSequence", success: success2 });
|
|
66
|
+
if (success2) {
|
|
67
|
+
return JSON.stringify({
|
|
68
|
+
ok: true,
|
|
69
|
+
result: { name: seq.name, sequenceID: seq.sequenceID, attempts: attempts }
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
} catch (e) {
|
|
73
|
+
attempts.push({ method: "openSequence", success: false, error: e.toString() });
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
attempts.push({ method: "openSequence", success: false, error: "app.project.openSequence is not a function on this Premiere build" });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return JSON.stringify({
|
|
80
|
+
ok: false,
|
|
81
|
+
error: "could not make sequence \"" + args.sequenceName + "\" active with any known method",
|
|
82
|
+
attempts: attempts
|
|
83
|
+
});
|
|
84
|
+
} catch (e) {
|
|
85
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Command: set-all-tracks-targeted → ppb_setAllTracksTargeted
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Standard-DOM mutation. Ported from leancoderkavy's premiere-pro-mcp
|
|
7
|
+
// `set_all_tracks_targeted` tool (track-targeting.ts): loops every track
|
|
8
|
+
// (optionally filtered to one trackType) and calls setTargeted(targeted,
|
|
9
|
+
// isVideoBool). Verified with a per-track isTargeted() read-back summary
|
|
10
|
+
// rather than trusting the mutation calls' own (lack of) return values.
|
|
11
|
+
function ppb_setAllTracksTargeted(argsJson) {
|
|
12
|
+
try {
|
|
13
|
+
var args;
|
|
14
|
+
try {
|
|
15
|
+
args = JSON.parse(argsJson);
|
|
16
|
+
} catch (e) {
|
|
17
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (typeof args.targeted !== "boolean") {
|
|
21
|
+
return JSON.stringify({ ok: false, error: "targeted must be a boolean" });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var trackType = args.trackType || "both";
|
|
25
|
+
if (trackType !== "video" && trackType !== "audio" && trackType !== "both") {
|
|
26
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\", \"audio\", or \"both\"" });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!app.project) {
|
|
30
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
var seq = null;
|
|
34
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
35
|
+
seq = findSequenceByName(args.sequenceName);
|
|
36
|
+
if (!seq) {
|
|
37
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
seq = app.project.activeSequence;
|
|
41
|
+
if (!seq) {
|
|
42
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
var video = [];
|
|
47
|
+
var audio = [];
|
|
48
|
+
var affected = 0;
|
|
49
|
+
|
|
50
|
+
if (trackType !== "audio") {
|
|
51
|
+
for (var v = 0; v < seq.videoTracks.numTracks; v++) {
|
|
52
|
+
var vTrack = seq.videoTracks[v];
|
|
53
|
+
var vEntry = { index: v, name: null, requested: args.targeted, isTargeted: null, error: null };
|
|
54
|
+
try { vEntry.name = vTrack.name; } catch (e) { vEntry.name = null; }
|
|
55
|
+
try {
|
|
56
|
+
vTrack.setTargeted(args.targeted, true);
|
|
57
|
+
affected++;
|
|
58
|
+
} catch (e) {
|
|
59
|
+
vEntry.error = e.toString();
|
|
60
|
+
}
|
|
61
|
+
try { vEntry.isTargeted = vTrack.isTargeted(); } catch (e) { vEntry.isTargeted = null; }
|
|
62
|
+
video.push(vEntry);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (trackType !== "video") {
|
|
67
|
+
for (var a = 0; a < seq.audioTracks.numTracks; a++) {
|
|
68
|
+
var aTrack = seq.audioTracks[a];
|
|
69
|
+
var aEntry = { index: a, name: null, requested: args.targeted, isTargeted: null, error: null };
|
|
70
|
+
try { aEntry.name = aTrack.name; } catch (e) { aEntry.name = null; }
|
|
71
|
+
try {
|
|
72
|
+
aTrack.setTargeted(args.targeted, false);
|
|
73
|
+
affected++;
|
|
74
|
+
} catch (e) {
|
|
75
|
+
aEntry.error = e.toString();
|
|
76
|
+
}
|
|
77
|
+
try { aEntry.isTargeted = aTrack.isTargeted(); } catch (e) { aEntry.isTargeted = null; }
|
|
78
|
+
audio.push(aEntry);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var mismatches = [];
|
|
83
|
+
var i;
|
|
84
|
+
for (i = 0; i < video.length; i++) {
|
|
85
|
+
if (video[i].isTargeted !== null && video[i].isTargeted !== args.targeted) {
|
|
86
|
+
mismatches.push("video[" + video[i].index + "]");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
for (i = 0; i < audio.length; i++) {
|
|
90
|
+
if (audio[i].isTargeted !== null && audio[i].isTargeted !== args.targeted) {
|
|
91
|
+
mismatches.push("audio[" + audio[i].index + "]");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
var result = {
|
|
96
|
+
sequenceName: seq.name,
|
|
97
|
+
trackType: trackType,
|
|
98
|
+
requestedTargeted: args.targeted,
|
|
99
|
+
tracksAffected: affected,
|
|
100
|
+
video: video,
|
|
101
|
+
audio: audio
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
if (mismatches.length > 0) {
|
|
105
|
+
result.warning = "the following tracks did not read back the requested targeted state: " + mismatches.join(", ");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return JSON.stringify({ ok: true, result: result });
|
|
109
|
+
} catch (e) {
|
|
110
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// Command: set-anti-alias-quality → ppb_setAntiAliasQuality
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// findClipComponent, setComponentProperty, ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Standard-DOM only — no QE needed. Ported from leancoderkavy's
|
|
7
|
+
// premiere-pro-mcp `set_anti_alias_quality` tool (track-targeting.ts),
|
|
8
|
+
// addressed here by trackType/trackIndex/clipIndex (same convention as
|
|
9
|
+
// get-full-clip-info) instead of node_id.
|
|
10
|
+
//
|
|
11
|
+
// **API UNCERTAIN**: no property named anything like "Anti-Alias" or
|
|
12
|
+
// "Anti-Alias Quality" is documented for the Motion component in
|
|
13
|
+
// PREMIERE_API_NOTES.md, and the reference tool itself only probes two
|
|
14
|
+
// loosely-related displayNames ("Anti-flicker Filter",
|
|
15
|
+
// "Use Composition's Shutter Angle") — neither is really an anti-alias
|
|
16
|
+
// control. This command probes a short list of plausible displayNames on
|
|
17
|
+
// the Motion component and returns an honest "not found on this Premiere
|
|
18
|
+
// build" error (naming every name tried) if none exist, rather than
|
|
19
|
+
// silently mutating an unrelated property. Mutating IF a match is found —
|
|
20
|
+
// undo is non-functional on this build, so previousValue in the result is
|
|
21
|
+
// the caller's only restoration path.
|
|
22
|
+
|
|
23
|
+
var SET_ANTI_ALIAS_QUALITY_CANDIDATE_NAMES = [
|
|
24
|
+
"Anti-flicker Filter",
|
|
25
|
+
"Anti-aliasing Quality",
|
|
26
|
+
"Anti-Alias Quality",
|
|
27
|
+
"Antialias Quality",
|
|
28
|
+
"Use Composition's Shutter Angle"
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
function ppb_setAntiAliasQuality(argsJson) {
|
|
32
|
+
try {
|
|
33
|
+
var args;
|
|
34
|
+
try {
|
|
35
|
+
args = JSON.parse(argsJson);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (args.trackType !== "video" && args.trackType !== "audio") {
|
|
41
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
|
|
42
|
+
}
|
|
43
|
+
if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
|
|
44
|
+
return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
|
|
45
|
+
}
|
|
46
|
+
if (typeof args.clipIndex !== "number" || args.clipIndex < 0 || Math.floor(args.clipIndex) !== args.clipIndex) {
|
|
47
|
+
return JSON.stringify({ ok: false, error: "clipIndex must be a non-negative integer" });
|
|
48
|
+
}
|
|
49
|
+
if (typeof args.amount !== "number" || args.amount < 0 || args.amount > 1) {
|
|
50
|
+
return JSON.stringify({ ok: false, error: "amount must be a number between 0 and 1" });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!app.project) {
|
|
54
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
var seq = null;
|
|
58
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
59
|
+
seq = findSequenceByName(args.sequenceName);
|
|
60
|
+
if (!seq) {
|
|
61
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
seq = app.project.activeSequence;
|
|
65
|
+
if (!seq) {
|
|
66
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var trackCollection = args.trackType === "video" ? seq.videoTracks : seq.audioTracks;
|
|
71
|
+
var numTracks = trackCollection.numTracks;
|
|
72
|
+
if (args.trackIndex >= numTracks) {
|
|
73
|
+
return JSON.stringify({
|
|
74
|
+
ok: false,
|
|
75
|
+
error: "trackIndex " + args.trackIndex + " is out of range — sequence has " + numTracks + " " + args.trackType + " track(s)"
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
var track = trackCollection[args.trackIndex];
|
|
80
|
+
var numClips = track.clips.numItems;
|
|
81
|
+
if (args.clipIndex >= numClips) {
|
|
82
|
+
return JSON.stringify({
|
|
83
|
+
ok: false,
|
|
84
|
+
error: "clipIndex " + args.clipIndex + " is out of range — track " + args.trackIndex + " has " + numClips + " clip(s)"
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
var clip = track.clips[args.clipIndex];
|
|
89
|
+
var clipName = null;
|
|
90
|
+
try { clipName = clip.name; } catch (e) { clipName = null; }
|
|
91
|
+
|
|
92
|
+
var motion = findClipComponent(clip, ["AE.ADBE Motion"], ["Motion"]);
|
|
93
|
+
if (!motion) {
|
|
94
|
+
return JSON.stringify({ ok: false, error: "Motion component not found on clip" });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Live-discovered 2026-07-17: the boolean form throws "Illegal
|
|
98
|
+
// Parameter type" — Motion's real property here is the NUMERIC
|
|
99
|
+
// "Anti-flicker Filter" (0..1 amount).
|
|
100
|
+
var setResult = setComponentProperty(motion, SET_ANTI_ALIAS_QUALITY_CANDIDATE_NAMES, args.amount);
|
|
101
|
+
if (!setResult.found) {
|
|
102
|
+
return JSON.stringify({
|
|
103
|
+
ok: false,
|
|
104
|
+
error: "no anti-alias-quality-like property exists on the Motion component on this Premiere build (tried: " + SET_ANTI_ALIAS_QUALITY_CANDIDATE_NAMES.join(", ") + ")"
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return JSON.stringify({
|
|
109
|
+
ok: true,
|
|
110
|
+
result: {
|
|
111
|
+
sequenceName: seq.name,
|
|
112
|
+
trackType: args.trackType,
|
|
113
|
+
trackIndex: args.trackIndex,
|
|
114
|
+
clipIndex: args.clipIndex,
|
|
115
|
+
clipName: clipName,
|
|
116
|
+
previousValue: setResult.previousValue,
|
|
117
|
+
requestedValue: setResult.requestedValue,
|
|
118
|
+
newValue: setResult.newValue,
|
|
119
|
+
verified: setResult.verified
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
} catch (e) {
|
|
123
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// Command: set-blend-mode → ppb_setBlendMode
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// findClipComponent, setComponentProperty, ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Standard-DOM only — no QE needed. Ported from leancoderkavy's
|
|
7
|
+
// premiere-pro-mcp `set_blend_mode` tool (clipboard.ts), addressed here by
|
|
8
|
+
// trackType/trackIndex/clipIndex (same convention as get-full-clip-info)
|
|
9
|
+
// instead of node_id. Sets the Opacity component's Blend Mode property.
|
|
10
|
+
//
|
|
11
|
+
// **API UNCERTAIN**: per PREMIERE_API_NOTES.md, Blend Mode is an int enum
|
|
12
|
+
// (1=Normal...22 or 27=Luminosity — the reference repos disagree on the
|
|
13
|
+
// map size/order), and that mapping is version-dependent across Premiere
|
|
14
|
+
// builds. This command takes and returns the RAW integer only — it does
|
|
15
|
+
// NOT attempt a name→int mapping table of its own (unlike the reference
|
|
16
|
+
// tool, which hardcodes one) since we have no way to verify it against
|
|
17
|
+
// this Premiere build. Callers are responsible for picking the right int
|
|
18
|
+
// for their build; previousValue/newValue in the result are the only
|
|
19
|
+
// reliable calibration signal available. Mutating — undo is non-functional
|
|
20
|
+
// on this build, so previousValue is the caller's only restoration path.
|
|
21
|
+
|
|
22
|
+
function ppb_setBlendMode(argsJson) {
|
|
23
|
+
try {
|
|
24
|
+
var args;
|
|
25
|
+
try {
|
|
26
|
+
args = JSON.parse(argsJson);
|
|
27
|
+
} catch (e) {
|
|
28
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (args.trackType !== "video" && args.trackType !== "audio") {
|
|
32
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
|
|
33
|
+
}
|
|
34
|
+
if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
|
|
35
|
+
return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
|
|
36
|
+
}
|
|
37
|
+
if (typeof args.clipIndex !== "number" || args.clipIndex < 0 || Math.floor(args.clipIndex) !== args.clipIndex) {
|
|
38
|
+
return JSON.stringify({ ok: false, error: "clipIndex must be a non-negative integer" });
|
|
39
|
+
}
|
|
40
|
+
if (typeof args.blendMode !== "number" || Math.floor(args.blendMode) !== args.blendMode) {
|
|
41
|
+
return JSON.stringify({ ok: false, error: "blendMode must be an integer (Blend Mode enum value — version-dependent, see command header comment)" });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!app.project) {
|
|
45
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
var seq = null;
|
|
49
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
50
|
+
seq = findSequenceByName(args.sequenceName);
|
|
51
|
+
if (!seq) {
|
|
52
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
seq = app.project.activeSequence;
|
|
56
|
+
if (!seq) {
|
|
57
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var trackCollection = args.trackType === "video" ? seq.videoTracks : seq.audioTracks;
|
|
62
|
+
var numTracks = trackCollection.numTracks;
|
|
63
|
+
if (args.trackIndex >= numTracks) {
|
|
64
|
+
return JSON.stringify({
|
|
65
|
+
ok: false,
|
|
66
|
+
error: "trackIndex " + args.trackIndex + " is out of range — sequence has " + numTracks + " " + args.trackType + " track(s)"
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var track = trackCollection[args.trackIndex];
|
|
71
|
+
var numClips = track.clips.numItems;
|
|
72
|
+
if (args.clipIndex >= numClips) {
|
|
73
|
+
return JSON.stringify({
|
|
74
|
+
ok: false,
|
|
75
|
+
error: "clipIndex " + args.clipIndex + " is out of range — track " + args.trackIndex + " has " + numClips + " clip(s)"
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
var clip = track.clips[args.clipIndex];
|
|
80
|
+
var clipName = null;
|
|
81
|
+
try { clipName = clip.name; } catch (e) { clipName = null; }
|
|
82
|
+
|
|
83
|
+
var opacityComp = findClipComponent(clip, ["AE.ADBE Opacity"], ["Opacity"]);
|
|
84
|
+
if (!opacityComp) {
|
|
85
|
+
return JSON.stringify({ ok: false, error: "Opacity component not found on clip" });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
var setResult = setComponentProperty(opacityComp, ["Blend Mode"], args.blendMode);
|
|
89
|
+
if (!setResult.found) {
|
|
90
|
+
return JSON.stringify({ ok: false, error: "Blend Mode property not found on the Opacity component" });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return JSON.stringify({
|
|
94
|
+
ok: true,
|
|
95
|
+
result: {
|
|
96
|
+
sequenceName: seq.name,
|
|
97
|
+
trackType: args.trackType,
|
|
98
|
+
trackIndex: args.trackIndex,
|
|
99
|
+
clipIndex: args.clipIndex,
|
|
100
|
+
clipName: clipName,
|
|
101
|
+
previousValue: setResult.previousValue,
|
|
102
|
+
requestedValue: setResult.requestedValue,
|
|
103
|
+
newValue: setResult.newValue,
|
|
104
|
+
verified: setResult.verified,
|
|
105
|
+
note: "Blend Mode enum mapping is version-dependent across Premiere builds — this raw int is not name-mapped by this command."
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
} catch (e) {
|
|
109
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
110
|
+
}
|
|
111
|
+
}
|