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,137 @@
|
|
|
1
|
+
// Command: move-playhead → ppb_movePlayhead
|
|
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
|
+
// findSequenceByName, getSequenceFps, timecodeToSeconds, ...) are already
|
|
5
|
+
// defined there.
|
|
6
|
+
|
|
7
|
+
// Moves the given (or active) sequence's playhead to a target time, given
|
|
8
|
+
// as either a "MM:SS:FF" timecode or a raw seconds value. Reuses the exact
|
|
9
|
+
// playhead-move pattern from ppb_exportFrame (host/commands/export-frame.jsx)
|
|
10
|
+
// — ticksString first, a Time-object fallback, collecting a positionAttempts
|
|
11
|
+
// array of {form, success, error?} — which is live-confirmed working on
|
|
12
|
+
// this Premiere build. Unlike export-frame, there is nothing to restore
|
|
13
|
+
// afterward: moving the playhead IS the point of this command.
|
|
14
|
+
function ppb_movePlayhead(argsJson) {
|
|
15
|
+
try {
|
|
16
|
+
var args;
|
|
17
|
+
try {
|
|
18
|
+
args = JSON.parse(argsJson);
|
|
19
|
+
} catch (e) {
|
|
20
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var hasTimecode = args.timecode !== undefined && args.timecode !== null;
|
|
24
|
+
var hasSeconds = args.seconds !== undefined && args.seconds !== null;
|
|
25
|
+
|
|
26
|
+
if (hasTimecode === hasSeconds) {
|
|
27
|
+
return JSON.stringify({ ok: false, error: "exactly one of timecode or seconds must be provided" });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (hasTimecode) {
|
|
31
|
+
var timecodeRe = /^\d{2,3}:\d{2}:\d{2}$/;
|
|
32
|
+
if (typeof args.timecode !== "string" || !timecodeRe.test(args.timecode)) {
|
|
33
|
+
return JSON.stringify({ ok: false, error: "timecode must be a \"MM:SS:FF\" string" });
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
if (typeof args.seconds !== "number" || isNaN(args.seconds) || args.seconds < 0) {
|
|
37
|
+
return JSON.stringify({ ok: false, error: "seconds must be a non-negative number" });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!app.project) {
|
|
42
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
var seq = null;
|
|
46
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
47
|
+
seq = findSequenceByName(args.sequenceName);
|
|
48
|
+
if (!seq) {
|
|
49
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
seq = app.project.activeSequence;
|
|
53
|
+
if (!seq) {
|
|
54
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Moving the playhead implies the user wants to see it — make the
|
|
59
|
+
// resolved sequence the active one if it isn't already (same approach
|
|
60
|
+
// as ppb_removeTrackIntervals / ppb_exportFrame). No QE DOM needed here.
|
|
61
|
+
if (app.project.activeSequence !== seq) {
|
|
62
|
+
app.project.activeSequence = seq;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
var timeSeconds;
|
|
66
|
+
if (hasTimecode) {
|
|
67
|
+
var fps = getSequenceFps(seq);
|
|
68
|
+
timeSeconds = timecodeToSeconds(args.timecode, fps);
|
|
69
|
+
} else {
|
|
70
|
+
timeSeconds = args.seconds;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
var positionAttempts = [];
|
|
74
|
+
var ticksString = String(Math.round(timeSeconds * TICKS_PER_SECOND));
|
|
75
|
+
var timeObj = null;
|
|
76
|
+
try {
|
|
77
|
+
timeObj = new Time();
|
|
78
|
+
timeObj.seconds = timeSeconds;
|
|
79
|
+
} catch (e) {
|
|
80
|
+
timeObj = null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
var positionSet = false;
|
|
84
|
+
try {
|
|
85
|
+
seq.setPlayerPosition(ticksString);
|
|
86
|
+
positionAttempts.push({ form: "ticksString", success: true });
|
|
87
|
+
positionSet = true;
|
|
88
|
+
} catch (e) {
|
|
89
|
+
positionAttempts.push({ form: "ticksString", success: false, error: e.toString() });
|
|
90
|
+
}
|
|
91
|
+
if (!positionSet && timeObj !== null) {
|
|
92
|
+
try {
|
|
93
|
+
seq.setPlayerPosition(timeObj);
|
|
94
|
+
positionAttempts.push({ form: "TimeObject", success: true });
|
|
95
|
+
positionSet = true;
|
|
96
|
+
} catch (e) {
|
|
97
|
+
positionAttempts.push({ form: "TimeObject", success: false, error: e.toString() });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!positionSet) {
|
|
102
|
+
return JSON.stringify({
|
|
103
|
+
ok: false,
|
|
104
|
+
error: "could not move the playhead to the requested time with any known argument form (ticks string, Time object)",
|
|
105
|
+
attempts: positionAttempts
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
var playheadSeconds = null;
|
|
110
|
+
try {
|
|
111
|
+
var currentPosition = seq.getPlayerPosition();
|
|
112
|
+
if (currentPosition !== null && typeof currentPosition !== "undefined") {
|
|
113
|
+
if (typeof currentPosition.seconds === "number") {
|
|
114
|
+
playheadSeconds = currentPosition.seconds;
|
|
115
|
+
} else {
|
|
116
|
+
playheadSeconds = Number(currentPosition.ticks) / TICKS_PER_SECOND;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
} catch (e) {
|
|
120
|
+
playheadSeconds = null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
var result = {
|
|
124
|
+
sequenceName: seq.name,
|
|
125
|
+
requestedSeconds: timeSeconds,
|
|
126
|
+
playheadSeconds: playheadSeconds,
|
|
127
|
+
attempts: positionAttempts
|
|
128
|
+
};
|
|
129
|
+
if (hasTimecode) {
|
|
130
|
+
result.timecode = args.timecode;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return JSON.stringify({ ok: true, result: result });
|
|
134
|
+
} catch (e) {
|
|
135
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// Command: nest-clips → ppb_nestClips
|
|
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 utility.ts nest_clips.
|
|
7
|
+
// Nests the CURRENTLY SELECTED clips into a new nested sequence via
|
|
8
|
+
// `seq.createSubsequence(ignoreTrackTargetingBool)` per
|
|
9
|
+
// PREMIERE_API_NOTES.md's Sequences table (selection is a precondition —
|
|
10
|
+
// select clips first, e.g. via select-clips-by-name/select-all-clips).
|
|
11
|
+
// createSubsequence() itself gives the new sequence a Premiere-generated
|
|
12
|
+
// default name; there is no confirmed API to pass a name directly to it,
|
|
13
|
+
// so this command renames the resulting sequence (and its Project-panel
|
|
14
|
+
// item, per the "renaming gotcha" documented alongside seq.clone() in
|
|
15
|
+
// PREMIERE_API_NOTES.md — seq.name = x does NOT propagate to the panel)
|
|
16
|
+
// afterward if `name` was given.
|
|
17
|
+
//
|
|
18
|
+
// Semi-destructive (restructures the timeline): the selected clips are
|
|
19
|
+
// replaced by one nested-sequence clip. Undo is non-functional on this
|
|
20
|
+
// build per README.md.
|
|
21
|
+
//
|
|
22
|
+
// Verification: the sequence count increases by exactly one, and the new
|
|
23
|
+
// sequence is identified as whichever sequence appeared that wasn't in
|
|
24
|
+
// the "before" snapshot (createSubsequence()'s own return value is not
|
|
25
|
+
// trusted, matching every other QE/structural command in this panel).
|
|
26
|
+
function ppb_snapshotSequenceIds(project) {
|
|
27
|
+
var ids = {};
|
|
28
|
+
for (var i = 0; i < project.sequences.numSequences; i++) {
|
|
29
|
+
var s = project.sequences[i];
|
|
30
|
+
var id = null;
|
|
31
|
+
try { id = s.sequenceID; } catch (e) { id = null; }
|
|
32
|
+
ids[id !== null ? id : ("idx" + i)] = true;
|
|
33
|
+
}
|
|
34
|
+
return ids;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function ppb_nestClips(argsJson) {
|
|
38
|
+
try {
|
|
39
|
+
var args;
|
|
40
|
+
try {
|
|
41
|
+
args = JSON.parse(argsJson);
|
|
42
|
+
} catch (e) {
|
|
43
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!app.project) {
|
|
47
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
var seq = null;
|
|
51
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
52
|
+
seq = findSequenceByName(args.sequenceName);
|
|
53
|
+
if (!seq) {
|
|
54
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
seq = app.project.activeSequence;
|
|
58
|
+
if (!seq) {
|
|
59
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (app.project.activeSequence !== seq) {
|
|
63
|
+
app.project.activeSequence = seq;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
var selectedCount = 0;
|
|
67
|
+
function countSelected(tracks) {
|
|
68
|
+
for (var t = 0; t < tracks.numTracks; t++) {
|
|
69
|
+
for (var c = 0; c < tracks[t].clips.numItems; c++) {
|
|
70
|
+
var isSel = false;
|
|
71
|
+
try { isSel = tracks[t].clips[c].isSelected(); } catch (e) { isSel = false; }
|
|
72
|
+
if (isSel) {
|
|
73
|
+
selectedCount++;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
countSelected(seq.videoTracks);
|
|
79
|
+
countSelected(seq.audioTracks);
|
|
80
|
+
|
|
81
|
+
if (selectedCount === 0) {
|
|
82
|
+
return JSON.stringify({ ok: false, error: "no clips selected — select clips first (e.g. select-clips-by-name/select-clips-in-range)" });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
var numSequencesBefore = app.project.sequences.numSequences;
|
|
86
|
+
var idsBefore = ppb_snapshotSequenceIds(app.project);
|
|
87
|
+
|
|
88
|
+
var createError = null;
|
|
89
|
+
try {
|
|
90
|
+
seq.createSubsequence(true);
|
|
91
|
+
} catch (e) {
|
|
92
|
+
createError = e.toString();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
var numSequencesAfter = app.project.sequences.numSequences;
|
|
96
|
+
|
|
97
|
+
if (createError !== null || numSequencesAfter <= numSequencesBefore) {
|
|
98
|
+
return JSON.stringify({
|
|
99
|
+
ok: false,
|
|
100
|
+
error: createError !== null
|
|
101
|
+
? ("seq.createSubsequence(true) failed: " + createError)
|
|
102
|
+
: "createSubsequence() did not throw, but the project's sequence count did not increase",
|
|
103
|
+
numSequencesBefore: numSequencesBefore,
|
|
104
|
+
numSequencesAfter: numSequencesAfter
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
var newSeq = null;
|
|
109
|
+
for (var i = 0; i < app.project.sequences.numSequences; i++) {
|
|
110
|
+
var candidate = app.project.sequences[i];
|
|
111
|
+
var candidateId = null;
|
|
112
|
+
try { candidateId = candidate.sequenceID; } catch (e) { candidateId = null; }
|
|
113
|
+
var key = candidateId !== null ? candidateId : ("idx" + i);
|
|
114
|
+
if (!idsBefore[key]) {
|
|
115
|
+
newSeq = candidate;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!newSeq) {
|
|
121
|
+
return JSON.stringify({
|
|
122
|
+
ok: false,
|
|
123
|
+
error: "sequence count increased but the new sequence could not be identified",
|
|
124
|
+
numSequencesBefore: numSequencesBefore,
|
|
125
|
+
numSequencesAfter: numSequencesAfter
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
var previousName = null;
|
|
130
|
+
try { previousName = newSeq.name; } catch (e) { previousName = null; }
|
|
131
|
+
|
|
132
|
+
var renamed = false;
|
|
133
|
+
var renameNote = null;
|
|
134
|
+
if (args.name && typeof args.name === "string") {
|
|
135
|
+
try {
|
|
136
|
+
newSeq.name = args.name;
|
|
137
|
+
} catch (e) {
|
|
138
|
+
renameNote = "renaming the sequence object failed: " + e.toString();
|
|
139
|
+
}
|
|
140
|
+
// "renaming gotcha" per PREMIERE_API_NOTES.md: seq.name = x does not
|
|
141
|
+
// propagate to the Project panel item — find and rename it too.
|
|
142
|
+
try {
|
|
143
|
+
var rootChildren = app.project.rootItem.children;
|
|
144
|
+
for (var ri = 0; ri < rootChildren.numItems; ri++) {
|
|
145
|
+
var it = rootChildren[ri];
|
|
146
|
+
var itSeq = null;
|
|
147
|
+
try { itSeq = it.getSequence ? it.getSequence() : null; } catch (e2) { itSeq = null; }
|
|
148
|
+
if (itSeq && itSeq.sequenceID === newSeq.sequenceID) {
|
|
149
|
+
it.name = args.name;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
} catch (e3) {
|
|
154
|
+
// best-effort — panel-item rename is a bonus, not required for success
|
|
155
|
+
}
|
|
156
|
+
var readBackName = null;
|
|
157
|
+
try { readBackName = newSeq.name; } catch (e4) { readBackName = null; }
|
|
158
|
+
renamed = readBackName === args.name;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return JSON.stringify({
|
|
162
|
+
ok: true,
|
|
163
|
+
result: {
|
|
164
|
+
sourceSequenceName: seq.name,
|
|
165
|
+
selectedClipCount: selectedCount,
|
|
166
|
+
numSequencesBefore: numSequencesBefore,
|
|
167
|
+
numSequencesAfter: numSequencesAfter,
|
|
168
|
+
newSequenceName: newSeq.name,
|
|
169
|
+
newSequenceID: newSeq.sequenceID,
|
|
170
|
+
previousDefaultName: previousName,
|
|
171
|
+
requestedName: args.name || null,
|
|
172
|
+
renamed: renamed,
|
|
173
|
+
renameNote: renameNote
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
} catch (e) {
|
|
177
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Command: open-in-source → ppb_openInSource
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context.
|
|
4
|
+
//
|
|
5
|
+
// Ported from leancoderkavy's premiere-pro-mcp source-monitor.ts
|
|
6
|
+
// open_in_source. Resolves a project item by nodeId/name (same recursive
|
|
7
|
+
// bin walk as add-to-timeline/replace-clip) and opens it in the Source
|
|
8
|
+
// Monitor via app.sourceMonitor.openProjectItem(item).
|
|
9
|
+
//
|
|
10
|
+
// MUTATION RULE: verified by reading app.sourceMonitor.getProjectItem()
|
|
11
|
+
// back afterward and confirming its nodeId matches the requested item —
|
|
12
|
+
// never trusting openProjectItem()'s own (undocumented) return value.
|
|
13
|
+
|
|
14
|
+
function ppbFindItemOpenInSource_walk(item, args, depth) {
|
|
15
|
+
if (depth > 32) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
var isBin = false;
|
|
19
|
+
try {
|
|
20
|
+
isBin = typeof ProjectItemType !== "undefined" && item.type === ProjectItemType.BIN;
|
|
21
|
+
} catch (e) {
|
|
22
|
+
isBin = false;
|
|
23
|
+
}
|
|
24
|
+
var matched = false;
|
|
25
|
+
if (args.nodeId !== null) {
|
|
26
|
+
try { matched = item.nodeId === args.nodeId; } catch (e) { matched = false; }
|
|
27
|
+
} else if (args.name !== null) {
|
|
28
|
+
try { matched = item.name === args.name; } catch (e) { matched = false; }
|
|
29
|
+
}
|
|
30
|
+
if (matched) {
|
|
31
|
+
return item;
|
|
32
|
+
}
|
|
33
|
+
if (isBin && item.children) {
|
|
34
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
35
|
+
var found = ppbFindItemOpenInSource_walk(item.children[i], args, depth + 1);
|
|
36
|
+
if (found) {
|
|
37
|
+
return found;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function ppbFindItemOpenInSource_resolve(args) {
|
|
45
|
+
var root = app.project.rootItem;
|
|
46
|
+
for (var i = 0; i < root.children.numItems; i++) {
|
|
47
|
+
var found = ppbFindItemOpenInSource_walk(root.children[i], args, 1);
|
|
48
|
+
if (found) {
|
|
49
|
+
return found;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function ppb_openInSource(argsJson) {
|
|
56
|
+
try {
|
|
57
|
+
var args;
|
|
58
|
+
try {
|
|
59
|
+
args = JSON.parse(argsJson);
|
|
60
|
+
} catch (e) {
|
|
61
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
var hasNodeId = typeof args.nodeId === "string" && args.nodeId.length > 0;
|
|
65
|
+
var hasName = typeof args.name === "string" && args.name.length > 0;
|
|
66
|
+
if (!hasNodeId && !hasName) {
|
|
67
|
+
return JSON.stringify({ ok: false, error: "either nodeId or name is required to identify the project item" });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!app.project) {
|
|
71
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var item = ppbFindItemOpenInSource_resolve({
|
|
75
|
+
nodeId: hasNodeId ? args.nodeId : null,
|
|
76
|
+
name: hasNodeId ? null : args.name
|
|
77
|
+
});
|
|
78
|
+
if (!item) {
|
|
79
|
+
return JSON.stringify({ ok: false, error: "no project item found matching the given nodeId/name" });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var itemNodeId = null;
|
|
83
|
+
var itemName = null;
|
|
84
|
+
try { itemNodeId = item.nodeId; } catch (e1) { itemNodeId = null; }
|
|
85
|
+
try { itemName = item.name; } catch (e2) { itemName = null; }
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
app.sourceMonitor.openProjectItem(item);
|
|
89
|
+
} catch (e3) {
|
|
90
|
+
return JSON.stringify({ ok: false, error: "app.sourceMonitor.openProjectItem() failed: " + e3.toString() });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
var verifiedItem = null;
|
|
94
|
+
var verified = false;
|
|
95
|
+
try {
|
|
96
|
+
verifiedItem = app.sourceMonitor.getProjectItem();
|
|
97
|
+
if (verifiedItem) {
|
|
98
|
+
var verifiedNodeId = null;
|
|
99
|
+
try { verifiedNodeId = verifiedItem.nodeId; } catch (e4) { verifiedNodeId = null; }
|
|
100
|
+
verified = verifiedNodeId !== null && verifiedNodeId === itemNodeId;
|
|
101
|
+
}
|
|
102
|
+
} catch (e5) {
|
|
103
|
+
verified = false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return JSON.stringify({
|
|
107
|
+
ok: true,
|
|
108
|
+
result: {
|
|
109
|
+
opened: true,
|
|
110
|
+
item: { name: itemName, nodeId: itemNodeId },
|
|
111
|
+
verified: verified
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
} catch (e) {
|
|
115
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Command: open-project → ppb_openProject
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context.
|
|
4
|
+
//
|
|
5
|
+
// Ported from leancoderkavy/premiere-pro-mcp's project.ts open_project.
|
|
6
|
+
// Calls app.openDocument(path). WARNING (per PREMIERE_API_NOTES.md and
|
|
7
|
+
// set-active-project.jsx's header note): app.openDocument's behavior is
|
|
8
|
+
// only loosely documented — it may pop a dialog (unsupported project
|
|
9
|
+
// version, missing media relink prompts, etc.), and its behavior when the
|
|
10
|
+
// path is already open elsewhere is unconfirmed. A blocking dialog will
|
|
11
|
+
// freeze the CEP bridge until a human dismisses it in Premiere. Checks
|
|
12
|
+
// the file exists on disk before calling, to at least rule out that
|
|
13
|
+
// failure mode cheaply. Verified by reading app.project.path back
|
|
14
|
+
// afterward.
|
|
15
|
+
|
|
16
|
+
function ppb_openProject(argsJson) {
|
|
17
|
+
try {
|
|
18
|
+
var args;
|
|
19
|
+
try {
|
|
20
|
+
args = JSON.parse(argsJson);
|
|
21
|
+
} catch (e) {
|
|
22
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!args.path || typeof args.path !== "string") {
|
|
26
|
+
return JSON.stringify({ ok: false, error: "path is required" });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var file = new File(args.path);
|
|
30
|
+
if (!file.exists) {
|
|
31
|
+
return JSON.stringify({ ok: false, error: "no file exists at path: " + args.path });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
app.openDocument(args.path);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return JSON.stringify({ ok: false, error: "app.openDocument() failed: " + e.toString() });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
var newPath = null;
|
|
41
|
+
var newName = null;
|
|
42
|
+
try { newPath = app.project ? app.project.path : null; } catch (e) { newPath = null; }
|
|
43
|
+
try { newName = app.project ? app.project.name : null; } catch (e) { newName = null; }
|
|
44
|
+
|
|
45
|
+
var verified = newPath !== null && newPath === args.path;
|
|
46
|
+
|
|
47
|
+
return JSON.stringify({
|
|
48
|
+
ok: true,
|
|
49
|
+
result: {
|
|
50
|
+
opened: true,
|
|
51
|
+
requestedPath: args.path,
|
|
52
|
+
path: newPath,
|
|
53
|
+
name: newName,
|
|
54
|
+
verified: verified,
|
|
55
|
+
note: "app.openDocument() may pop a blocking dialog on this build (unsupported version, missing-media relink, etc.) — if the call hangs, a human needs to dismiss a dialog in Premiere itself"
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
} catch (e) {
|
|
59
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
60
|
+
}
|
|
61
|
+
}
|