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,171 @@
|
|
|
1
|
+
|
|
2
|
+
// seconds -> "HH:MM:SS:FF" — the razor argument form PROVEN working on
|
|
3
|
+
// this build (remove-track-intervals live-validated it); the ticksString
|
|
4
|
+
// form silently no-ops (live-tested 2026-07-17).
|
|
5
|
+
function ppbRazorAll_secondsToQeTimecode(seconds, fps) {
|
|
6
|
+
var totalFrames = Math.round(seconds * fps);
|
|
7
|
+
var ff = totalFrames % Math.round(fps);
|
|
8
|
+
var totalSeconds = Math.floor(totalFrames / Math.round(fps));
|
|
9
|
+
var ss = totalSeconds % 60;
|
|
10
|
+
var totalMinutes = Math.floor(totalSeconds / 60);
|
|
11
|
+
var mm = totalMinutes % 60;
|
|
12
|
+
var hh = Math.floor(totalMinutes / 60);
|
|
13
|
+
function pad2(n) { return (n < 10 ? "0" : "") + n; }
|
|
14
|
+
return pad2(hh) + ":" + pad2(mm) + ":" + pad2(ss) + ":" + pad2(ff);
|
|
15
|
+
}
|
|
16
|
+
// Command: razor-all-tracks → ppb_razorAllTracks
|
|
17
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
18
|
+
// same global ExtendScript context — shared helpers (ensureQEEnabled,
|
|
19
|
+
// findSequenceByName, TICKS_PER_SECOND, activateSequenceForQE, ...) are
|
|
20
|
+
// already defined there.
|
|
21
|
+
//
|
|
22
|
+
// Ported from leancoderkavy/premiere-pro-mcp's track-targeting.ts
|
|
23
|
+
// razor_all_tracks. Razors (splits) every video+audio track at a given
|
|
24
|
+
// time (defaults to the sequence's own playhead if `seconds` is omitted)
|
|
25
|
+
// via QE `track.razor(ticksString)` — same razor mechanism as
|
|
26
|
+
// remove-track-intervals, but applied to every track instead of one.
|
|
27
|
+
// Destructive-ish: a razor cut cannot be undone (undo is non-functional on
|
|
28
|
+
// this build per README.md), and callers should not run this against real
|
|
29
|
+
// footage without first duplicating the sequence.
|
|
30
|
+
//
|
|
31
|
+
// Verification: per-track clip-item-COUNT before/after (via the QE
|
|
32
|
+
// track's numItems) rather than trusting razor()'s own return value —
|
|
33
|
+
// same "never trust the call's return value" rule as every other QE
|
|
34
|
+
// command in this panel.
|
|
35
|
+
function ppb_razorAllTracks(argsJson) {
|
|
36
|
+
try {
|
|
37
|
+
var args;
|
|
38
|
+
try {
|
|
39
|
+
args = JSON.parse(argsJson);
|
|
40
|
+
} catch (e) {
|
|
41
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
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
|
+
try {
|
|
62
|
+
ensureQEEnabled();
|
|
63
|
+
activateSequenceForQE(seq);
|
|
64
|
+
} catch (e) {
|
|
65
|
+
return JSON.stringify({ ok: false, error: "app.enableQE()/sequence activation failed: " + e.toString() });
|
|
66
|
+
}
|
|
67
|
+
if (typeof qe === "undefined" || !qe.project) {
|
|
68
|
+
return JSON.stringify({ ok: false, error: "QE DOM not available after enableQE()" });
|
|
69
|
+
}
|
|
70
|
+
var qeSeq = qe.project.getActiveSequence();
|
|
71
|
+
if (!qeSeq) {
|
|
72
|
+
return JSON.stringify({ ok: false, error: "qe.project.getActiveSequence() returned nothing after activating the sequence" });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
var atSeconds;
|
|
76
|
+
if (typeof args.seconds === "number" && !isNaN(args.seconds)) {
|
|
77
|
+
atSeconds = args.seconds;
|
|
78
|
+
} else {
|
|
79
|
+
try {
|
|
80
|
+
atSeconds = seq.getPlayerPosition().seconds;
|
|
81
|
+
} catch (e) {
|
|
82
|
+
return JSON.stringify({ ok: false, error: "seconds was omitted and the playhead position could not be read: " + e.toString() });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
var ticksString = String(Math.round(atSeconds * TICKS_PER_SECOND));
|
|
86
|
+
var fps = getSequenceFps(seq);
|
|
87
|
+
var qeTimecode = ppbRazorAll_secondsToQeTimecode(args.seconds, fps);
|
|
88
|
+
|
|
89
|
+
var perTrack = [];
|
|
90
|
+
var totalRazored = 0;
|
|
91
|
+
|
|
92
|
+
var numVideoTracks = 0;
|
|
93
|
+
try { numVideoTracks = qeSeq.numVideoTracks; } catch (e) { numVideoTracks = 0; }
|
|
94
|
+
for (var v = 0; v < numVideoTracks; v++) {
|
|
95
|
+
var vTrack = null;
|
|
96
|
+
try { vTrack = qeSeq.getVideoTrackAt(v); } catch (e) { vTrack = null; }
|
|
97
|
+
if (!vTrack) {
|
|
98
|
+
perTrack.push({ trackType: "video", trackIndex: v, error: "QE track lookup failed" });
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
var vBefore = null;
|
|
102
|
+
try { vBefore = vTrack.numItems; } catch (e) { vBefore = null; }
|
|
103
|
+
var vRazorError = null;
|
|
104
|
+
try {
|
|
105
|
+
vTrack.razor(qeTimecode);
|
|
106
|
+
} catch (e) {
|
|
107
|
+
vRazorError = e.toString();
|
|
108
|
+
}
|
|
109
|
+
var vAfter = null;
|
|
110
|
+
try { vAfter = vTrack.numItems; } catch (e) { vAfter = null; }
|
|
111
|
+
var vChanged = vBefore !== null && vAfter !== null && vAfter > vBefore;
|
|
112
|
+
if (vChanged) {
|
|
113
|
+
totalRazored++;
|
|
114
|
+
}
|
|
115
|
+
perTrack.push({
|
|
116
|
+
trackType: "video",
|
|
117
|
+
trackIndex: v,
|
|
118
|
+
itemCountBefore: vBefore,
|
|
119
|
+
itemCountAfter: vAfter,
|
|
120
|
+
razored: vChanged,
|
|
121
|
+
error: vRazorError
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
var numAudioTracks = 0;
|
|
126
|
+
try { numAudioTracks = qeSeq.numAudioTracks; } catch (e) { numAudioTracks = 0; }
|
|
127
|
+
for (var a = 0; a < numAudioTracks; a++) {
|
|
128
|
+
var aTrack = null;
|
|
129
|
+
try { aTrack = qeSeq.getAudioTrackAt(a); } catch (e) { aTrack = null; }
|
|
130
|
+
if (!aTrack) {
|
|
131
|
+
perTrack.push({ trackType: "audio", trackIndex: a, error: "QE track lookup failed" });
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
var aBefore = null;
|
|
135
|
+
try { aBefore = aTrack.numItems; } catch (e) { aBefore = null; }
|
|
136
|
+
var aRazorError = null;
|
|
137
|
+
try {
|
|
138
|
+
aTrack.razor(qeTimecode);
|
|
139
|
+
} catch (e) {
|
|
140
|
+
aRazorError = e.toString();
|
|
141
|
+
}
|
|
142
|
+
var aAfter = null;
|
|
143
|
+
try { aAfter = aTrack.numItems; } catch (e) { aAfter = null; }
|
|
144
|
+
var aChanged = aBefore !== null && aAfter !== null && aAfter > aBefore;
|
|
145
|
+
if (aChanged) {
|
|
146
|
+
totalRazored++;
|
|
147
|
+
}
|
|
148
|
+
perTrack.push({
|
|
149
|
+
trackType: "audio",
|
|
150
|
+
trackIndex: a,
|
|
151
|
+
itemCountBefore: aBefore,
|
|
152
|
+
itemCountAfter: aAfter,
|
|
153
|
+
razored: aChanged,
|
|
154
|
+
error: aRazorError
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return JSON.stringify({
|
|
159
|
+
ok: true,
|
|
160
|
+
result: {
|
|
161
|
+
sequenceName: seq.name,
|
|
162
|
+
atSeconds: atSeconds,
|
|
163
|
+
tracksAttempted: perTrack.length,
|
|
164
|
+
tracksRazored: totalRazored,
|
|
165
|
+
tracks: perTrack
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
} catch (e) {
|
|
169
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Command: redo → ppb_redo
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (ensureQEEnabled, ...)
|
|
4
|
+
// are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// REWRITTEN 2026-07-17 after the probe session (see BUILD_FINDINGS.md
|
|
7
|
+
// corrections): qe.project.redo() WORKS on this build — live-verified
|
|
8
|
+
// re-applying an undone setSpeed, with qe.project.undoStackIndex()
|
|
9
|
+
// (an int-returning function) incrementing on a real redo. That index
|
|
10
|
+
// is the verification primitive; app.project.redo() does not exist here.
|
|
11
|
+
|
|
12
|
+
function ppb_redo(argsJson) {
|
|
13
|
+
try {
|
|
14
|
+
if (!app.project) {
|
|
15
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
ensureQEEnabled();
|
|
20
|
+
} catch (e) {
|
|
21
|
+
return JSON.stringify({ ok: false, error: "app.enableQE() failed: " + e.toString() });
|
|
22
|
+
}
|
|
23
|
+
if (typeof qe === "undefined" || !qe.project || typeof qe.project.redo !== "function") {
|
|
24
|
+
return JSON.stringify({ ok: false, error: "qe.project.redo is not available on this Premiere build" });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function readStackIndex() {
|
|
28
|
+
try {
|
|
29
|
+
if (typeof qe.project.undoStackIndex === "function") {
|
|
30
|
+
return qe.project.undoStackIndex();
|
|
31
|
+
}
|
|
32
|
+
} catch (e2) {
|
|
33
|
+
// fall through
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
var indexBefore = readStackIndex();
|
|
39
|
+
try {
|
|
40
|
+
qe.project.redo();
|
|
41
|
+
} catch (e3) {
|
|
42
|
+
return JSON.stringify({ ok: false, error: "qe.project.redo() threw: " + e3.toString() });
|
|
43
|
+
}
|
|
44
|
+
var indexAfter = readStackIndex();
|
|
45
|
+
|
|
46
|
+
var verified = null;
|
|
47
|
+
if (indexBefore !== null && indexAfter !== null) {
|
|
48
|
+
verified = indexAfter > indexBefore;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return JSON.stringify({
|
|
52
|
+
ok: true,
|
|
53
|
+
result: {
|
|
54
|
+
redone: verified !== false,
|
|
55
|
+
verified: verified,
|
|
56
|
+
method: "qe.project.redo",
|
|
57
|
+
undoStackIndexBefore: indexBefore,
|
|
58
|
+
undoStackIndexAfter: indexAfter,
|
|
59
|
+
note: verified === null
|
|
60
|
+
? "undoStackIndex() unavailable — this only confirms the call did not throw"
|
|
61
|
+
: (verified
|
|
62
|
+
? "verified via qe.project.undoStackIndex() incrementing"
|
|
63
|
+
: "the stack index did not move — there was nothing to redo")
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
} catch (e) {
|
|
67
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Command: refresh-media → ppb_refreshMedia
|
|
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
|
+
// are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Ports the reference project's media.ts refresh_media tool. Item
|
|
7
|
+
// resolution by nodeId/name uses children-presence recursion (NOT an
|
|
8
|
+
// isBin() gate), per get-project-item-info.jsx's live-debugged finding.
|
|
9
|
+
// item.refreshMedia() has no confirmed getter to detect a real content
|
|
10
|
+
// change, so success here only confirms the call didn't throw — the same
|
|
11
|
+
// honesty pattern as select-project-item's "called: true" result.
|
|
12
|
+
|
|
13
|
+
function ppbRefreshMedia_findByNodeId(item, nodeId, depth) {
|
|
14
|
+
if (depth > 32) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
if (item.nodeId === nodeId) {
|
|
19
|
+
return item;
|
|
20
|
+
}
|
|
21
|
+
} catch (e) {
|
|
22
|
+
// fall through
|
|
23
|
+
}
|
|
24
|
+
if (item.children && item.children.numItems > 0) {
|
|
25
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
26
|
+
var found = ppbRefreshMedia_findByNodeId(item.children[i], nodeId, depth + 1);
|
|
27
|
+
if (found) {
|
|
28
|
+
return found;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function ppbRefreshMedia_findByName(item, name, depth) {
|
|
36
|
+
if (depth > 32) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
if (item.name === name) {
|
|
41
|
+
return item;
|
|
42
|
+
}
|
|
43
|
+
} catch (e) {
|
|
44
|
+
// fall through
|
|
45
|
+
}
|
|
46
|
+
if (item.children && item.children.numItems > 0) {
|
|
47
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
48
|
+
var found = ppbRefreshMedia_findByName(item.children[i], name, depth + 1);
|
|
49
|
+
if (found) {
|
|
50
|
+
return found;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function ppb_refreshMedia(argsJson) {
|
|
58
|
+
try {
|
|
59
|
+
var args;
|
|
60
|
+
try {
|
|
61
|
+
args = JSON.parse(argsJson);
|
|
62
|
+
} catch (e) {
|
|
63
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
var hasNodeId = typeof args.nodeId === "string" && args.nodeId.length > 0;
|
|
67
|
+
var hasName = typeof args.name === "string" && args.name.length > 0;
|
|
68
|
+
if (!hasNodeId && !hasName) {
|
|
69
|
+
return JSON.stringify({ ok: false, error: "either nodeId or name is required" });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!app.project) {
|
|
73
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var item = hasNodeId
|
|
77
|
+
? ppbRefreshMedia_findByNodeId(app.project.rootItem, args.nodeId, 0)
|
|
78
|
+
: ppbRefreshMedia_findByName(app.project.rootItem, args.name, 0);
|
|
79
|
+
if (!item) {
|
|
80
|
+
return JSON.stringify({ ok: false, error: "no project item found matching the given nodeId/name" });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
item.refreshMedia();
|
|
85
|
+
} catch (e) {
|
|
86
|
+
return JSON.stringify({ ok: false, error: "refreshMedia() failed: " + e.toString() });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return JSON.stringify({
|
|
90
|
+
ok: true,
|
|
91
|
+
result: {
|
|
92
|
+
nodeId: item.nodeId,
|
|
93
|
+
name: item.name,
|
|
94
|
+
called: true,
|
|
95
|
+
note: "refreshMedia() has no confirmed getter to detect a content change — this only confirms the call didn't throw"
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
} catch (e) {
|
|
99
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Command: relink-media → ppb_relinkMedia
|
|
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
|
+
// are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Ports the reference project's media.ts relink_media tool. Item
|
|
7
|
+
// resolution by nodeId/name uses children-presence recursion (NOT an
|
|
8
|
+
// isBin() gate), per get-project-item-info.jsx's live-debugged finding
|
|
9
|
+
// that the ROOT item's type is ROOT, not BIN. Checks canChangeMediaPath()
|
|
10
|
+
// first, then calls item.changeMediaPath(newPath, true) per
|
|
11
|
+
// PREMIERE_API_NOTES.md, verified via a getMediaPath() read-back against
|
|
12
|
+
// the requested path.
|
|
13
|
+
|
|
14
|
+
function ppbRelinkMedia_findByNodeId(item, nodeId, depth) {
|
|
15
|
+
if (depth > 32) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
if (item.nodeId === nodeId) {
|
|
20
|
+
return item;
|
|
21
|
+
}
|
|
22
|
+
} catch (e) {
|
|
23
|
+
// fall through
|
|
24
|
+
}
|
|
25
|
+
if (item.children && item.children.numItems > 0) {
|
|
26
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
27
|
+
var found = ppbRelinkMedia_findByNodeId(item.children[i], nodeId, depth + 1);
|
|
28
|
+
if (found) {
|
|
29
|
+
return found;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function ppbRelinkMedia_findByName(item, name, depth) {
|
|
37
|
+
if (depth > 32) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
if (item.name === name) {
|
|
42
|
+
return item;
|
|
43
|
+
}
|
|
44
|
+
} catch (e) {
|
|
45
|
+
// fall through
|
|
46
|
+
}
|
|
47
|
+
if (item.children && item.children.numItems > 0) {
|
|
48
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
49
|
+
var found = ppbRelinkMedia_findByName(item.children[i], name, depth + 1);
|
|
50
|
+
if (found) {
|
|
51
|
+
return found;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function ppbRelinkMedia_resolveItem(args) {
|
|
59
|
+
if (args.nodeId) {
|
|
60
|
+
return ppbRelinkMedia_findByNodeId(app.project.rootItem, args.nodeId, 0);
|
|
61
|
+
}
|
|
62
|
+
return ppbRelinkMedia_findByName(app.project.rootItem, args.name, 0);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function ppb_relinkMedia(argsJson) {
|
|
66
|
+
try {
|
|
67
|
+
var args;
|
|
68
|
+
try {
|
|
69
|
+
args = JSON.parse(argsJson);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var hasNodeId = typeof args.nodeId === "string" && args.nodeId.length > 0;
|
|
75
|
+
var hasName = typeof args.name === "string" && args.name.length > 0;
|
|
76
|
+
if (!hasNodeId && !hasName) {
|
|
77
|
+
return JSON.stringify({ ok: false, error: "either nodeId or name is required" });
|
|
78
|
+
}
|
|
79
|
+
if (!args.newPath || typeof args.newPath !== "string") {
|
|
80
|
+
return JSON.stringify({ ok: false, error: "newPath is required" });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!app.project) {
|
|
84
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
var item = ppbRelinkMedia_resolveItem({ nodeId: hasNodeId ? args.nodeId : null, name: hasNodeId ? null : args.name });
|
|
88
|
+
if (!item) {
|
|
89
|
+
return JSON.stringify({ ok: false, error: "no project item found matching the given nodeId/name" });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
var canChange = null;
|
|
93
|
+
try { canChange = item.canChangeMediaPath(); } catch (e) { canChange = null; }
|
|
94
|
+
if (canChange === false) {
|
|
95
|
+
return JSON.stringify({
|
|
96
|
+
ok: false,
|
|
97
|
+
error: "canChangeMediaPath() returned false — this item's media path cannot be changed",
|
|
98
|
+
nodeId: item.nodeId,
|
|
99
|
+
name: item.name
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
var previousValue = null;
|
|
104
|
+
try { previousValue = item.getMediaPath(); } catch (e) { previousValue = null; }
|
|
105
|
+
|
|
106
|
+
var callResult = null;
|
|
107
|
+
try {
|
|
108
|
+
callResult = item.changeMediaPath(args.newPath, true);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
return JSON.stringify({ ok: false, error: "changeMediaPath() failed: " + e.toString() });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
var newValue = null;
|
|
114
|
+
try { newValue = item.getMediaPath(); } catch (e) { newValue = null; }
|
|
115
|
+
|
|
116
|
+
return JSON.stringify({
|
|
117
|
+
ok: true,
|
|
118
|
+
result: {
|
|
119
|
+
nodeId: item.nodeId,
|
|
120
|
+
name: item.name,
|
|
121
|
+
canChangeMediaPath: canChange,
|
|
122
|
+
callResult: callResult,
|
|
123
|
+
previousValue: previousValue,
|
|
124
|
+
requestedValue: args.newPath,
|
|
125
|
+
newValue: newValue,
|
|
126
|
+
verified: newValue === args.newPath
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
} catch (e) {
|
|
130
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Command: remove-all-effects → ppb_removeAllEffects
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// ensureQEEnabled, activateSequenceForQE, resolveTimelineClip,
|
|
5
|
+
// resolveQeClip, serializeClipComponents, ...) are already defined there.
|
|
6
|
+
//
|
|
7
|
+
// QE-only: qeClip.removeEffects() — per PREMIERE_API_NOTES.md, this strips
|
|
8
|
+
// ALL applied effects from a clip in one call, but the built-in components
|
|
9
|
+
// (Motion/Opacity/Volume/Panner) survive per QE semantics and are NOT
|
|
10
|
+
// removed. Verified by reading standard-DOM clip.components before/after —
|
|
11
|
+
// the count should drop to (at most) the built-in baseline, never to zero
|
|
12
|
+
// on a normal clip.
|
|
13
|
+
function ppb_removeAllEffects(argsJson) {
|
|
14
|
+
try {
|
|
15
|
+
var args;
|
|
16
|
+
try {
|
|
17
|
+
args = JSON.parse(argsJson);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (args.trackType !== "video" && args.trackType !== "audio") {
|
|
23
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
|
|
24
|
+
}
|
|
25
|
+
if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
|
|
26
|
+
return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
|
|
27
|
+
}
|
|
28
|
+
if (typeof args.clipIndex !== "number" || args.clipIndex < 0 || Math.floor(args.clipIndex) !== args.clipIndex) {
|
|
29
|
+
return JSON.stringify({ ok: false, error: "clipIndex must be a non-negative integer" });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!app.project) {
|
|
33
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
var seq = null;
|
|
37
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
38
|
+
seq = findSequenceByName(args.sequenceName);
|
|
39
|
+
if (!seq) {
|
|
40
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
seq = app.project.activeSequence;
|
|
44
|
+
if (!seq) {
|
|
45
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
var resolvedClip = resolveTimelineClip(seq, args.trackType, args.trackIndex, args.clipIndex);
|
|
50
|
+
if (resolvedClip.error) {
|
|
51
|
+
return JSON.stringify({ ok: false, error: resolvedClip.error });
|
|
52
|
+
}
|
|
53
|
+
var clip = resolvedClip.clip;
|
|
54
|
+
var clipName = null;
|
|
55
|
+
try { clipName = clip.name; } catch (e) { clipName = null; }
|
|
56
|
+
|
|
57
|
+
var previousComponents = serializeClipComponents(clip);
|
|
58
|
+
var previousCount = previousComponents.length;
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
ensureQEEnabled();
|
|
62
|
+
activateSequenceForQE(seq);
|
|
63
|
+
} catch (e) {
|
|
64
|
+
return JSON.stringify({ ok: false, error: "app.enableQE()/sequence activation failed: " + e.toString() });
|
|
65
|
+
}
|
|
66
|
+
if (typeof qe === "undefined" || !qe.project) {
|
|
67
|
+
return JSON.stringify({ ok: false, error: "QE DOM not available after enableQE()" });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var qeSeq;
|
|
71
|
+
try {
|
|
72
|
+
qeSeq = qe.project.getActiveSequence();
|
|
73
|
+
} catch (e) {
|
|
74
|
+
return JSON.stringify({ ok: false, error: "qe.project.getActiveSequence() failed: " + e.toString() });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
var qeResolved = resolveQeClip(qeSeq, args.trackType, args.trackIndex, args.clipIndex);
|
|
78
|
+
if (qeResolved.error) {
|
|
79
|
+
return JSON.stringify({ ok: false, error: qeResolved.error });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
qeResolved.qeClip.removeEffects();
|
|
84
|
+
} catch (e) {
|
|
85
|
+
return JSON.stringify({ ok: false, error: "qeClip.removeEffects() failed: " + e.toString() });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
var newComponents = serializeClipComponents(clip);
|
|
89
|
+
var newCount = newComponents.length;
|
|
90
|
+
var removedCount = previousCount - newCount;
|
|
91
|
+
var verified = removedCount > 0;
|
|
92
|
+
|
|
93
|
+
var result = {
|
|
94
|
+
sequenceName: seq.name,
|
|
95
|
+
trackType: args.trackType,
|
|
96
|
+
trackIndex: args.trackIndex,
|
|
97
|
+
clipIndex: args.clipIndex,
|
|
98
|
+
clipName: clipName,
|
|
99
|
+
verified: verified,
|
|
100
|
+
removedCount: removedCount,
|
|
101
|
+
previousComponentCount: previousCount,
|
|
102
|
+
newComponentCount: newCount,
|
|
103
|
+
previousComponents: previousComponents,
|
|
104
|
+
remainingComponents: newComponents
|
|
105
|
+
};
|
|
106
|
+
if (!verified) {
|
|
107
|
+
result.note = "qeClip.removeEffects() did not throw, but components.numItems did not drop — either the clip had no removable (non-built-in) effects applied, or removeEffects() is non-functional on this build.";
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return JSON.stringify({ ok: true, result: result });
|
|
111
|
+
} catch (e) {
|
|
112
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
113
|
+
}
|
|
114
|
+
}
|