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,140 @@
|
|
|
1
|
+
// Command: duplicate-clip → ppb_duplicateClip
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// resolveTimelineClip, serializeTrackItem, secondsToTicksString,
|
|
5
|
+
// timeValueToSeconds, ...) are already defined there.
|
|
6
|
+
//
|
|
7
|
+
// Inserts a NEW instance of the addressed clip's own projectItem onto
|
|
8
|
+
// the SAME track, via the standard-DOM seq.insertClip() (ripple) —
|
|
9
|
+
// PREMIERE_API_NOTES.md's "Clips / TrackItems" insert form, same as
|
|
10
|
+
// add-to-timeline. Ported from leancoderkavy's premiere-pro-mcp
|
|
11
|
+
// duplicate_clip tool, adapted: the reference places the duplicate on
|
|
12
|
+
// trackIndex+1 (a DIFFERENT track) with no position argument; this
|
|
13
|
+
// command instead keeps it on the SAME track (no second track is implied
|
|
14
|
+
// by this panel's clip-addressing convention) and accepts an explicit
|
|
15
|
+
// targetStartSeconds, defaulting to right after the original clip's own
|
|
16
|
+
// end (clip.endSeconds) so it never collides with the original — insert
|
|
17
|
+
// ripples, so there's no destructive overwrite risk either way.
|
|
18
|
+
//
|
|
19
|
+
// MUTATION RULE: verified via the track's clips.numItems increasing by
|
|
20
|
+
// exactly one, plus a best-effort lookup of the newly-inserted clip by
|
|
21
|
+
// matching projectItem + requested start time (serialized the same way
|
|
22
|
+
// as get-full-clip-info).
|
|
23
|
+
|
|
24
|
+
function ppb_duplicateClip(argsJson) {
|
|
25
|
+
try {
|
|
26
|
+
var args;
|
|
27
|
+
try {
|
|
28
|
+
args = JSON.parse(argsJson);
|
|
29
|
+
} catch (e) {
|
|
30
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (args.trackType !== "video" && args.trackType !== "audio") {
|
|
34
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
|
|
35
|
+
}
|
|
36
|
+
if (typeof args.trackIndex !== "number" || typeof args.clipIndex !== "number") {
|
|
37
|
+
return JSON.stringify({ ok: false, error: "trackIndex and clipIndex are required" });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!app.project) {
|
|
41
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
var seq = null;
|
|
45
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
46
|
+
seq = findSequenceByName(args.sequenceName);
|
|
47
|
+
if (!seq) {
|
|
48
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
seq = app.project.activeSequence;
|
|
52
|
+
if (!seq) {
|
|
53
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
var resolved = resolveTimelineClip(seq, args.trackType, args.trackIndex, args.clipIndex);
|
|
58
|
+
if (resolved.error) {
|
|
59
|
+
return JSON.stringify({ ok: false, error: resolved.error });
|
|
60
|
+
}
|
|
61
|
+
var clip = resolved.clip;
|
|
62
|
+
|
|
63
|
+
var projectItem = null;
|
|
64
|
+
try { projectItem = clip.projectItem; } catch (e2) { projectItem = null; }
|
|
65
|
+
if (!projectItem) {
|
|
66
|
+
return JSON.stringify({ ok: false, error: "could not read the source projectItem for this clip" });
|
|
67
|
+
}
|
|
68
|
+
var itemNodeId = null;
|
|
69
|
+
try { itemNodeId = projectItem.nodeId; } catch (e3) { itemNodeId = null; }
|
|
70
|
+
|
|
71
|
+
var originalBefore = serializeTrackItem(clip, args.trackIndex, args.clipIndex);
|
|
72
|
+
|
|
73
|
+
var targetStartSeconds;
|
|
74
|
+
if (typeof args.targetStartSeconds === "number") {
|
|
75
|
+
targetStartSeconds = args.targetStartSeconds;
|
|
76
|
+
} else if (originalBefore.endSeconds !== null) {
|
|
77
|
+
targetStartSeconds = originalBefore.endSeconds;
|
|
78
|
+
} else {
|
|
79
|
+
return JSON.stringify({ ok: false, error: "targetStartSeconds was not given and the original clip's endSeconds could not be read to default it" });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var trackCollection = args.trackType === "video" ? seq.videoTracks : seq.audioTracks;
|
|
83
|
+
var track = trackCollection[args.trackIndex];
|
|
84
|
+
var clipCountBefore = null;
|
|
85
|
+
try { clipCountBefore = track.clips.numItems; } catch (e4) { clipCountBefore = null; }
|
|
86
|
+
|
|
87
|
+
var vIdx = args.trackType === "video" ? args.trackIndex : -1;
|
|
88
|
+
var aIdx = args.trackType === "audio" ? args.trackIndex : -1;
|
|
89
|
+
var startTicks = secondsToTicksString(targetStartSeconds);
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
seq.insertClip(projectItem, startTicks, vIdx, aIdx);
|
|
93
|
+
} catch (e5) {
|
|
94
|
+
return JSON.stringify({ ok: false, error: "seq.insertClip() failed: " + e5.toString() });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
var clipCountAfter = null;
|
|
98
|
+
try { clipCountAfter = track.clips.numItems; } catch (e6) { clipCountAfter = null; }
|
|
99
|
+
var verified = clipCountBefore !== null && clipCountAfter !== null && clipCountAfter === clipCountBefore + 1;
|
|
100
|
+
|
|
101
|
+
var newClip = null;
|
|
102
|
+
var toleranceSeconds = 0.1;
|
|
103
|
+
try {
|
|
104
|
+
for (var c = 0; c < track.clips.numItems; c++) {
|
|
105
|
+
var candidate = track.clips[c];
|
|
106
|
+
var candNodeId = null;
|
|
107
|
+
try { candNodeId = candidate.projectItem.nodeId; } catch (e7) { candNodeId = null; }
|
|
108
|
+
if (candNodeId !== itemNodeId) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
var candStart = null;
|
|
112
|
+
try { candStart = timeValueToSeconds(candidate.start); } catch (e8) { candStart = null; }
|
|
113
|
+
if (candStart !== null && Math.abs(candStart - targetStartSeconds) <= toleranceSeconds) {
|
|
114
|
+
newClip = serializeTrackItem(candidate, args.trackIndex, c);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} catch (e9) {
|
|
119
|
+
newClip = null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return JSON.stringify({
|
|
123
|
+
ok: true,
|
|
124
|
+
result: {
|
|
125
|
+
sequenceName: seq.name,
|
|
126
|
+
trackType: args.trackType,
|
|
127
|
+
trackIndex: args.trackIndex,
|
|
128
|
+
sourceClipIndex: args.clipIndex,
|
|
129
|
+
targetStartSeconds: targetStartSeconds,
|
|
130
|
+
originalClip: originalBefore,
|
|
131
|
+
newClip: newClip,
|
|
132
|
+
clipCountBefore: clipCountBefore,
|
|
133
|
+
clipCountAfter: clipCountAfter,
|
|
134
|
+
verified: verified
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
} catch (e) {
|
|
138
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// Command: duplicate-sequence → ppb_duplicateSequence
|
|
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 sequence.ts duplicate_sequence
|
|
7
|
+
// tool. Duplicates a sequence via `seq.clone()` per PREMIERE_API_NOTES.md's
|
|
8
|
+
// Sequences table. clone() gives the copy a Premiere-generated default name
|
|
9
|
+
// (there is no confirmed API to pass a name directly to it) — this command
|
|
10
|
+
// renames the resulting sequence (and its Project-panel item, per the
|
|
11
|
+
// "renaming gotcha" documented alongside seq.clone() in
|
|
12
|
+
// PREMIERE_API_NOTES.md — seq.name = x does NOT propagate to the panel)
|
|
13
|
+
// afterward, same pattern as nest-clips.jsx.
|
|
14
|
+
//
|
|
15
|
+
// Verification: the sequence count increases by exactly one, and the new
|
|
16
|
+
// sequence is identified as whichever sequence appeared that wasn't in the
|
|
17
|
+
// "before" snapshot (clone()'s own return value is not trusted, matching
|
|
18
|
+
// every other QE/structural command in this panel).
|
|
19
|
+
function ppbDupSeq_snapshotIds(project) {
|
|
20
|
+
var ids = {};
|
|
21
|
+
for (var i = 0; i < project.sequences.numSequences; i++) {
|
|
22
|
+
var s = project.sequences[i];
|
|
23
|
+
var id = null;
|
|
24
|
+
try { id = s.sequenceID; } catch (e) { id = null; }
|
|
25
|
+
ids[id !== null ? id : ("idx" + i)] = true;
|
|
26
|
+
}
|
|
27
|
+
return ids;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function ppb_duplicateSequence(argsJson) {
|
|
31
|
+
try {
|
|
32
|
+
var args;
|
|
33
|
+
try {
|
|
34
|
+
args = JSON.parse(argsJson);
|
|
35
|
+
} catch (e) {
|
|
36
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!app.project) {
|
|
40
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
41
|
+
}
|
|
42
|
+
if (!args.newName || typeof args.newName !== "string") {
|
|
43
|
+
return JSON.stringify({ ok: false, error: "newName is required" });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
var seq;
|
|
47
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
48
|
+
seq = findSequenceByName(args.sequenceName);
|
|
49
|
+
if (!seq) {
|
|
50
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
seq = app.project.activeSequence;
|
|
54
|
+
if (!seq) {
|
|
55
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
var numSequencesBefore = app.project.sequences.numSequences;
|
|
60
|
+
var idsBefore = ppbDupSeq_snapshotIds(app.project);
|
|
61
|
+
|
|
62
|
+
var cloneError = null;
|
|
63
|
+
try {
|
|
64
|
+
seq.clone();
|
|
65
|
+
} catch (e) {
|
|
66
|
+
cloneError = e.toString();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
var numSequencesAfter = app.project.sequences.numSequences;
|
|
70
|
+
|
|
71
|
+
if (cloneError !== null || numSequencesAfter <= numSequencesBefore) {
|
|
72
|
+
return JSON.stringify({
|
|
73
|
+
ok: false,
|
|
74
|
+
error: cloneError !== null
|
|
75
|
+
? ("seq.clone() failed: " + cloneError)
|
|
76
|
+
: "clone() did not throw, but the project's sequence count did not increase",
|
|
77
|
+
numSequencesBefore: numSequencesBefore,
|
|
78
|
+
numSequencesAfter: numSequencesAfter
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var newSeq = null;
|
|
83
|
+
for (var i = 0; i < app.project.sequences.numSequences; i++) {
|
|
84
|
+
var candidate = app.project.sequences[i];
|
|
85
|
+
var candidateId = null;
|
|
86
|
+
try { candidateId = candidate.sequenceID; } catch (e) { candidateId = null; }
|
|
87
|
+
var key = candidateId !== null ? candidateId : ("idx" + i);
|
|
88
|
+
if (!idsBefore[key]) {
|
|
89
|
+
newSeq = candidate;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!newSeq) {
|
|
95
|
+
return JSON.stringify({
|
|
96
|
+
ok: false,
|
|
97
|
+
error: "sequence count increased but the cloned sequence could not be identified",
|
|
98
|
+
numSequencesBefore: numSequencesBefore,
|
|
99
|
+
numSequencesAfter: numSequencesAfter
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
var previousName = null;
|
|
104
|
+
try { previousName = newSeq.name; } catch (e) { previousName = null; }
|
|
105
|
+
|
|
106
|
+
var renameNote = null;
|
|
107
|
+
try {
|
|
108
|
+
newSeq.name = args.newName;
|
|
109
|
+
} catch (e) {
|
|
110
|
+
renameNote = "renaming the sequence object failed: " + e.toString();
|
|
111
|
+
}
|
|
112
|
+
// "renaming gotcha" per PREMIERE_API_NOTES.md: seq.name = x does not
|
|
113
|
+
// propagate to the Project panel item — find and rename it too.
|
|
114
|
+
try {
|
|
115
|
+
var rootChildren = app.project.rootItem.children;
|
|
116
|
+
for (var ri = 0; ri < rootChildren.numItems; ri++) {
|
|
117
|
+
var it = rootChildren[ri];
|
|
118
|
+
var itSeq = null;
|
|
119
|
+
try { itSeq = it.getSequence ? it.getSequence() : null; } catch (e2) { itSeq = null; }
|
|
120
|
+
if (itSeq && itSeq.sequenceID === newSeq.sequenceID) {
|
|
121
|
+
it.name = args.newName;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
} catch (e3) {
|
|
126
|
+
// best-effort — panel-item rename is a bonus, not required for success
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
var readBackName = null;
|
|
130
|
+
try { readBackName = newSeq.name; } catch (e4) { readBackName = null; }
|
|
131
|
+
var renamed = readBackName === args.newName;
|
|
132
|
+
|
|
133
|
+
return JSON.stringify({
|
|
134
|
+
ok: true,
|
|
135
|
+
result: {
|
|
136
|
+
sourceSequenceName: seq.name,
|
|
137
|
+
numSequencesBefore: numSequencesBefore,
|
|
138
|
+
numSequencesAfter: numSequencesAfter,
|
|
139
|
+
previousDefaultName: previousName,
|
|
140
|
+
newSequenceName: newSeq.name,
|
|
141
|
+
newSequenceID: newSeq.sequenceID,
|
|
142
|
+
requestedName: args.newName,
|
|
143
|
+
renamed: renamed,
|
|
144
|
+
renameNote: renameNote
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
} catch (e) {
|
|
148
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Command: encode-file → ppb_encodeFile
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context.
|
|
4
|
+
//
|
|
5
|
+
// Queues an EXTERNAL file (not a project item, not a sequence — a path on
|
|
6
|
+
// disk not necessarily imported into this project at all) for export in
|
|
7
|
+
// Adobe Media Encoder via app.encoder.launchEncoder() + encodeFile() +
|
|
8
|
+
// startBatch(), mirroring the reference tool this ports (leancoderkavy's
|
|
9
|
+
// premiere-pro-mcp encode_file). **Fire-and-forget** — same no-progress-API
|
|
10
|
+
// caveat as add-to-render-queue/encode-project-item: encodeFile() returns
|
|
11
|
+
// as soon as the job is queued, so this command cannot verify the output
|
|
12
|
+
// file exists.
|
|
13
|
+
|
|
14
|
+
function ppb_encodeFile(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
|
+
if (!args.inputPath || typeof args.inputPath !== "string") {
|
|
24
|
+
return JSON.stringify({ ok: false, error: "inputPath is required" });
|
|
25
|
+
}
|
|
26
|
+
if (!args.outputPath || typeof args.outputPath !== "string") {
|
|
27
|
+
return JSON.stringify({ ok: false, error: "outputPath is required" });
|
|
28
|
+
}
|
|
29
|
+
if (!args.presetPath || typeof args.presetPath !== "string") {
|
|
30
|
+
return JSON.stringify({ ok: false, error: "presetPath is required (an absolute .epr file path)" });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
var inputFile = new File(args.inputPath);
|
|
34
|
+
if (!inputFile.exists) {
|
|
35
|
+
return JSON.stringify({ ok: false, error: "input file not found: " + args.inputPath });
|
|
36
|
+
}
|
|
37
|
+
var presetFile = new File(args.presetPath);
|
|
38
|
+
if (!presetFile.exists) {
|
|
39
|
+
return JSON.stringify({ ok: false, error: "preset file not found: " + args.presetPath });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
var startBatch = args.startBatch === true;
|
|
43
|
+
|
|
44
|
+
if (!app.encoder) {
|
|
45
|
+
return JSON.stringify({ ok: false, error: "Adobe Media Encoder is not available (app.encoder is undefined)" });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
app.encoder.launchEncoder();
|
|
50
|
+
} catch (e) {
|
|
51
|
+
return JSON.stringify({ ok: false, error: "app.encoder.launchEncoder() failed: " + e.toString() });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
// Matches the reference tool's own call shape: encodeFile(input,
|
|
56
|
+
// output, preset, removeOnCompletion01, srcIn, srcOut) — srcIn/srcOut
|
|
57
|
+
// are left undefined here (this command takes no in/out-point args
|
|
58
|
+
// per spec), encoding the entire input file.
|
|
59
|
+
app.encoder.encodeFile(args.inputPath, args.outputPath, args.presetPath, 1 /* removeOnCompletion */);
|
|
60
|
+
} catch (e) {
|
|
61
|
+
return JSON.stringify({ ok: false, error: "app.encoder.encodeFile() failed: " + e.toString() });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (startBatch) {
|
|
65
|
+
try {
|
|
66
|
+
app.encoder.startBatch();
|
|
67
|
+
} catch (e) {
|
|
68
|
+
return JSON.stringify({ ok: false, error: "job was queued but app.encoder.startBatch() failed: " + e.toString() });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return JSON.stringify({
|
|
73
|
+
ok: true,
|
|
74
|
+
result: {
|
|
75
|
+
inputPath: args.inputPath,
|
|
76
|
+
outputPath: args.outputPath,
|
|
77
|
+
presetPath: args.presetPath,
|
|
78
|
+
startBatch: startBatch,
|
|
79
|
+
note: "fire-and-forget: the job is queued in Adobe Media Encoder, not exported synchronously — " +
|
|
80
|
+
"there is no progress API, so this result does NOT confirm the output file exists yet."
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
} catch (e) {
|
|
84
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// Command: encode-project-item → ppb_encodeProjectItem
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context.
|
|
4
|
+
//
|
|
5
|
+
// Queues a PROJECT ITEM (not a sequence) for export in Adobe Media Encoder
|
|
6
|
+
// via app.encoder.launchEncoder() + encodeProjectItem() + startBatch(),
|
|
7
|
+
// mirroring the reference tool this ports (leancoderkavy's
|
|
8
|
+
// premiere-pro-mcp encode_project_item). **Fire-and-forget** — same no-
|
|
9
|
+
// progress-API caveat as add-to-render-queue: encodeProjectItem() returns
|
|
10
|
+
// as soon as the job is queued, so this command cannot verify the output
|
|
11
|
+
// file exists.
|
|
12
|
+
|
|
13
|
+
// Project-item addressing (nodeId or name) — duplicated per command file
|
|
14
|
+
// since each loads independently; same walk as get-item-metadata.jsx's
|
|
15
|
+
// ppbFindItemGetItemMetadata_* helpers, prefixed for this file.
|
|
16
|
+
function ppbFindItemEncodeProjectItem_walk(item, args, depth) {
|
|
17
|
+
if (depth > 32) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
var isBin = false;
|
|
21
|
+
try {
|
|
22
|
+
isBin = typeof ProjectItemType !== "undefined" && item.type === ProjectItemType.BIN;
|
|
23
|
+
} catch (e) {
|
|
24
|
+
isBin = false;
|
|
25
|
+
}
|
|
26
|
+
var matched = false;
|
|
27
|
+
if (args.nodeId !== null) {
|
|
28
|
+
try { matched = item.nodeId === args.nodeId; } catch (e) { matched = false; }
|
|
29
|
+
} else if (args.name !== null) {
|
|
30
|
+
try { matched = item.name === args.name; } catch (e) { matched = false; }
|
|
31
|
+
}
|
|
32
|
+
if (matched) {
|
|
33
|
+
return item;
|
|
34
|
+
}
|
|
35
|
+
if (isBin && item.children) {
|
|
36
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
37
|
+
var found = ppbFindItemEncodeProjectItem_walk(item.children[i], args, depth + 1);
|
|
38
|
+
if (found) {
|
|
39
|
+
return found;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function ppbFindItemEncodeProjectItem_resolve(args) {
|
|
47
|
+
var root = app.project.rootItem;
|
|
48
|
+
for (var i = 0; i < root.children.numItems; i++) {
|
|
49
|
+
var found = ppbFindItemEncodeProjectItem_walk(root.children[i], args, 1);
|
|
50
|
+
if (found) {
|
|
51
|
+
return found;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function ppb_encodeProjectItem(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 to address the project item" });
|
|
70
|
+
}
|
|
71
|
+
if (!args.outputPath || typeof args.outputPath !== "string") {
|
|
72
|
+
return JSON.stringify({ ok: false, error: "outputPath is required" });
|
|
73
|
+
}
|
|
74
|
+
if (!args.presetPath || typeof args.presetPath !== "string") {
|
|
75
|
+
return JSON.stringify({ ok: false, error: "presetPath is required (an absolute .epr file path)" });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!app.project) {
|
|
79
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var item = ppbFindItemEncodeProjectItem_resolve({
|
|
83
|
+
nodeId: hasNodeId ? args.nodeId : null,
|
|
84
|
+
name: hasNodeId ? null : args.name
|
|
85
|
+
});
|
|
86
|
+
if (!item) {
|
|
87
|
+
return JSON.stringify({ ok: false, error: "no project item found matching the given nodeId/name" });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
var presetFile = new File(args.presetPath);
|
|
91
|
+
if (!presetFile.exists) {
|
|
92
|
+
return JSON.stringify({ ok: false, error: "preset file not found: " + args.presetPath });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
var startBatch = args.startBatch === true;
|
|
96
|
+
|
|
97
|
+
if (!app.encoder) {
|
|
98
|
+
return JSON.stringify({ ok: false, error: "Adobe Media Encoder is not available (app.encoder is undefined)" });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
app.encoder.launchEncoder();
|
|
103
|
+
} catch (e) {
|
|
104
|
+
return JSON.stringify({ ok: false, error: "app.encoder.launchEncoder() failed: " + e.toString() });
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
var itemName = null;
|
|
108
|
+
try { itemName = item.name; } catch (e) { itemName = null; }
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
app.encoder.encodeProjectItem(
|
|
112
|
+
item,
|
|
113
|
+
args.outputPath,
|
|
114
|
+
args.presetPath,
|
|
115
|
+
typeof app.encoder.ENCODE_IN_TO_OUT !== "undefined" ? app.encoder.ENCODE_IN_TO_OUT : 1,
|
|
116
|
+
1 /* removeOnCompletion */
|
|
117
|
+
);
|
|
118
|
+
} catch (e) {
|
|
119
|
+
return JSON.stringify({ ok: false, error: "app.encoder.encodeProjectItem() failed: " + e.toString() });
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (startBatch) {
|
|
123
|
+
try {
|
|
124
|
+
app.encoder.startBatch();
|
|
125
|
+
} catch (e) {
|
|
126
|
+
return JSON.stringify({ ok: false, error: "job was queued but app.encoder.startBatch() failed: " + e.toString() });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return JSON.stringify({
|
|
131
|
+
ok: true,
|
|
132
|
+
result: {
|
|
133
|
+
item: itemName,
|
|
134
|
+
nodeId: hasNodeId ? args.nodeId : (item.nodeId || null),
|
|
135
|
+
outputPath: args.outputPath,
|
|
136
|
+
presetPath: args.presetPath,
|
|
137
|
+
startBatch: startBatch,
|
|
138
|
+
note: "fire-and-forget: the job is queued in Adobe Media Encoder, not exported synchronously — " +
|
|
139
|
+
"there is no progress API, so this result does NOT confirm the output file exists yet."
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
} catch (e) {
|
|
143
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Command: export-aaf → ppb_exportAaf
|
|
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
|
+
// Exports the given (or active) sequence as an AAF file via
|
|
7
|
+
// seq.exportAsAAF(path, mixdown01, mono01, rate, bits)
|
|
8
|
+
// (PREMIERE_API_NOTES.md's "FCP XML / AAF / OMF / EDL" line) — synchronous,
|
|
9
|
+
// no AME dependency. Defaults mirror the reference tool this ports
|
|
10
|
+
// (leancoderkavy's premiere-pro-mcp export_aaf): mixdown=true,
|
|
11
|
+
// explodeToMono=false, sampleRate=48000, bitsPerSample=16.
|
|
12
|
+
|
|
13
|
+
function ppb_exportAaf(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.outputPath || typeof args.outputPath !== "string") {
|
|
23
|
+
return JSON.stringify({ ok: false, error: "outputPath is required" });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!app.project) {
|
|
27
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var seq = null;
|
|
31
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
32
|
+
seq = findSequenceByName(args.sequenceName);
|
|
33
|
+
if (!seq) {
|
|
34
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
seq = app.project.activeSequence;
|
|
38
|
+
if (!seq) {
|
|
39
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
var mixdown = args.mixdown !== false; // default true
|
|
44
|
+
var mono = args.mono === true; // default false
|
|
45
|
+
var rate = typeof args.rate === "number" ? args.rate : 48000;
|
|
46
|
+
var bits = typeof args.bits === "number" ? args.bits : 16;
|
|
47
|
+
|
|
48
|
+
var result = {
|
|
49
|
+
sequenceName: seq.name,
|
|
50
|
+
outputPath: args.outputPath,
|
|
51
|
+
mixdown: mixdown,
|
|
52
|
+
mono: mono,
|
|
53
|
+
rate: rate,
|
|
54
|
+
bits: bits
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
seq.exportAsAAF(args.outputPath, mixdown ? 1 : 0, mono ? 1 : 0, rate, bits);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
return JSON.stringify({ ok: false, error: "exportAsAAF failed: " + e.toString() });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
var outFile = new File(args.outputPath);
|
|
64
|
+
if (!outFile.exists) {
|
|
65
|
+
return JSON.stringify({
|
|
66
|
+
ok: false,
|
|
67
|
+
error: "exportAsAAF ran but no file was written to " + args.outputPath
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
result.fileSizeBytes = outFile.length;
|
|
72
|
+
|
|
73
|
+
return JSON.stringify({ ok: true, result: result });
|
|
74
|
+
} catch (e) {
|
|
75
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Command: export-fcp-xml → ppb_exportFcpXml
|
|
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
|
+
// Exports the given (or active) sequence as a Final Cut Pro XML file via
|
|
7
|
+
// seq.exportAsFinalCutProXML(path) (PREMIERE_API_NOTES.md's "FCP XML / AAF
|
|
8
|
+
// / OMF / EDL" line) — synchronous, no AME dependency.
|
|
9
|
+
|
|
10
|
+
function ppb_exportFcpXml(argsJson) {
|
|
11
|
+
try {
|
|
12
|
+
var args;
|
|
13
|
+
try {
|
|
14
|
+
args = JSON.parse(argsJson);
|
|
15
|
+
} catch (e) {
|
|
16
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!args.outputPath || typeof args.outputPath !== "string") {
|
|
20
|
+
return JSON.stringify({ ok: false, error: "outputPath is required" });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!app.project) {
|
|
24
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var seq = null;
|
|
28
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
29
|
+
seq = findSequenceByName(args.sequenceName);
|
|
30
|
+
if (!seq) {
|
|
31
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
seq = app.project.activeSequence;
|
|
35
|
+
if (!seq) {
|
|
36
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
var result = {
|
|
41
|
+
sequenceName: seq.name,
|
|
42
|
+
outputPath: args.outputPath
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
seq.exportAsFinalCutProXML(args.outputPath);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
return JSON.stringify({ ok: false, error: "exportAsFinalCutProXML failed: " + e.toString() });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
var outFile = new File(args.outputPath);
|
|
52
|
+
if (!outFile.exists) {
|
|
53
|
+
return JSON.stringify({
|
|
54
|
+
ok: false,
|
|
55
|
+
error: "exportAsFinalCutProXML ran but no file was written to " + args.outputPath
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
result.fileSizeBytes = outFile.length;
|
|
60
|
+
|
|
61
|
+
return JSON.stringify({ ok: true, result: result });
|
|
62
|
+
} catch (e) {
|
|
63
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
64
|
+
}
|
|
65
|
+
}
|