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,350 @@
|
|
|
1
|
+
// Command: overwrite-clip-at → ppb_overwriteClipAt
|
|
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, timeValueToSeconds,
|
|
5
|
+
// TICKS_PER_SECOND, ...) are already defined there.
|
|
6
|
+
//
|
|
7
|
+
// **Destructive.** Overwrites a bin project item onto the timeline at a
|
|
8
|
+
// given track/time, replacing whatever's already there. Ported from
|
|
9
|
+
// leancoderkavy's premiere-pro-mcp `overwrite_clip` tool (advanced.ts:
|
|
10
|
+
// `seq.overwriteClip(item, startTicks, trackIndex, audioTrackIndex)`),
|
|
11
|
+
// addressed here by trackType/trackIndex (this bridge's convention)
|
|
12
|
+
// rather than separate video/audio track-index args — the non-addressed
|
|
13
|
+
// side is passed `-1` per PREMIERE_API_NOTES.md ("pass -1 as the
|
|
14
|
+
// non-target index to place only the video or only the audio side").
|
|
15
|
+
//
|
|
16
|
+
// Signature is disputed across reference repos (seconds number vs Time
|
|
17
|
+
// object vs ticks string) — every plausible form is tried, then a
|
|
18
|
+
// track-level `track.overwriteClip(item, seconds)` fallback, then a QE
|
|
19
|
+
// `qeTrack.overwrite(item)` last resort (which has NO time argument at
|
|
20
|
+
// all and is only confirmed to land at track index 0 — a last resort,
|
|
21
|
+
// not a real substitute for time-addressed placement).
|
|
22
|
+
//
|
|
23
|
+
// **⚠️ Auto-linked audio trap** (PREMIERE_API_NOTES.md, hetpatel):
|
|
24
|
+
// overwriting a VIDEO clip whose source also has audio can silently
|
|
25
|
+
// place the linked audio too, potentially destroying existing audio on
|
|
26
|
+
// that track. This command snapshots every audio track before the
|
|
27
|
+
// video-side overwrite, and afterward scans for any NEW clip sharing the
|
|
28
|
+
// placed item's projectItem nodeId within 0.1s of the requested start —
|
|
29
|
+
// removing it (iterating backwards, since removal shifts indices) so the
|
|
30
|
+
// caller gets exactly the video-only placement they asked for. Any audio
|
|
31
|
+
// clip that WAS already there and got destroyed by the overwrite itself
|
|
32
|
+
// is NOT recoverable (undo is non-functional on this build) — this
|
|
33
|
+
// cleanup only removes auto-ADDED audio, it cannot undo auto-DESTROYED
|
|
34
|
+
// audio.
|
|
35
|
+
|
|
36
|
+
function ppbOverwriteClipAt_walkProjectItem(item, args, depth) {
|
|
37
|
+
if (depth > 32) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
var isBin = false;
|
|
41
|
+
try {
|
|
42
|
+
isBin = typeof ProjectItemType !== "undefined" && item.type === ProjectItemType.BIN;
|
|
43
|
+
} catch (e) {
|
|
44
|
+
isBin = false;
|
|
45
|
+
}
|
|
46
|
+
var matched = false;
|
|
47
|
+
if (args.nodeId !== null) {
|
|
48
|
+
try { matched = item.nodeId === args.nodeId; } catch (e) { matched = false; }
|
|
49
|
+
} else if (args.name !== null) {
|
|
50
|
+
try { matched = item.name === args.name; } catch (e) { matched = false; }
|
|
51
|
+
}
|
|
52
|
+
if (matched) {
|
|
53
|
+
return item;
|
|
54
|
+
}
|
|
55
|
+
if (isBin && item.children) {
|
|
56
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
57
|
+
var found = ppbOverwriteClipAt_walkProjectItem(item.children[i], args, depth + 1);
|
|
58
|
+
if (found) {
|
|
59
|
+
return found;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function ppbOverwriteClipAt_findProjectItem(nodeId, name) {
|
|
67
|
+
var root = app.project.rootItem;
|
|
68
|
+
for (var i = 0; i < root.children.numItems; i++) {
|
|
69
|
+
var found = ppbOverwriteClipAt_walkProjectItem(root.children[i], { nodeId: nodeId, name: nodeId ? null : name }, 1);
|
|
70
|
+
if (found) {
|
|
71
|
+
return found;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function ppbOverwriteClipAt_snapshotTrack(track) {
|
|
78
|
+
var out = [];
|
|
79
|
+
var numClips;
|
|
80
|
+
try {
|
|
81
|
+
numClips = track.clips.numItems;
|
|
82
|
+
} catch (e) {
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
for (var i = 0; i < numClips; i++) {
|
|
86
|
+
var c = track.clips[i];
|
|
87
|
+
var entry = { nodeId: null, name: null, startSeconds: null, itemNodeId: null };
|
|
88
|
+
try { entry.nodeId = c.nodeId; } catch (e2) { entry.nodeId = null; }
|
|
89
|
+
try { entry.name = c.name; } catch (e3) { entry.name = null; }
|
|
90
|
+
try { entry.startSeconds = timeValueToSeconds(c.start); } catch (e4) { entry.startSeconds = null; }
|
|
91
|
+
try { entry.itemNodeId = c.projectItem.nodeId; } catch (e5) { entry.itemNodeId = null; }
|
|
92
|
+
out.push(entry);
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function ppb_overwriteClipAt(argsJson) {
|
|
98
|
+
try {
|
|
99
|
+
var args;
|
|
100
|
+
try {
|
|
101
|
+
args = JSON.parse(argsJson);
|
|
102
|
+
} catch (e) {
|
|
103
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
var hasNodeId = typeof args.itemNodeId === "string" && args.itemNodeId.length > 0;
|
|
107
|
+
var hasName = typeof args.itemName === "string" && args.itemName.length > 0;
|
|
108
|
+
if (!hasNodeId && !hasName) {
|
|
109
|
+
return JSON.stringify({ ok: false, error: "either itemNodeId or itemName is required" });
|
|
110
|
+
}
|
|
111
|
+
if (args.trackType !== "video" && args.trackType !== "audio") {
|
|
112
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
|
|
113
|
+
}
|
|
114
|
+
if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
|
|
115
|
+
return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
|
|
116
|
+
}
|
|
117
|
+
if (typeof args.startSeconds !== "number" || isNaN(args.startSeconds) || args.startSeconds < 0) {
|
|
118
|
+
return JSON.stringify({ ok: false, error: "startSeconds must be a non-negative number" });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!app.project) {
|
|
122
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
var item = ppbOverwriteClipAt_findProjectItem(hasNodeId ? args.itemNodeId : null, hasNodeId ? null : args.itemName);
|
|
126
|
+
if (!item) {
|
|
127
|
+
return JSON.stringify({ ok: false, error: "no project item found matching the given itemNodeId/itemName" });
|
|
128
|
+
}
|
|
129
|
+
var itemNodeId = null;
|
|
130
|
+
try { itemNodeId = item.nodeId; } catch (e) { itemNodeId = null; }
|
|
131
|
+
|
|
132
|
+
var seq = null;
|
|
133
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
134
|
+
seq = findSequenceByName(args.sequenceName);
|
|
135
|
+
if (!seq) {
|
|
136
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
seq = app.project.activeSequence;
|
|
140
|
+
if (!seq) {
|
|
141
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
var trackCollection = args.trackType === "video" ? seq.videoTracks : seq.audioTracks;
|
|
146
|
+
if (args.trackIndex >= trackCollection.numTracks) {
|
|
147
|
+
return JSON.stringify({
|
|
148
|
+
ok: false,
|
|
149
|
+
error: "trackIndex " + args.trackIndex + " is out of range — sequence has " + trackCollection.numTracks + " " + args.trackType + " track(s)"
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
var targetTrack = trackCollection[args.trackIndex];
|
|
153
|
+
|
|
154
|
+
// Snapshot every audio track before the mutation, so an auto-linked
|
|
155
|
+
// clip added as a side effect of a video overwrite can be told apart
|
|
156
|
+
// from audio that was already there.
|
|
157
|
+
var audioTracksBefore = [];
|
|
158
|
+
if (args.trackType === "video") {
|
|
159
|
+
for (var at = 0; at < seq.audioTracks.numTracks; at++) {
|
|
160
|
+
audioTracksBefore.push(ppbOverwriteClipAt_snapshotTrack(seq.audioTracks[at]));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
var ticksString = String(Math.round(args.startSeconds * TICKS_PER_SECOND));
|
|
165
|
+
var timeObj = null;
|
|
166
|
+
try {
|
|
167
|
+
timeObj = new Time();
|
|
168
|
+
timeObj.seconds = args.startSeconds;
|
|
169
|
+
} catch (e) {
|
|
170
|
+
timeObj = null;
|
|
171
|
+
}
|
|
172
|
+
var vIdx = args.trackType === "video" ? args.trackIndex : -1;
|
|
173
|
+
var aIdx = args.trackType === "audio" ? args.trackIndex : -1;
|
|
174
|
+
|
|
175
|
+
var attempts = [];
|
|
176
|
+
var succeeded = false;
|
|
177
|
+
var formUsed = null;
|
|
178
|
+
|
|
179
|
+
if (typeof seq.overwriteClip === "function") {
|
|
180
|
+
var seqForms = [
|
|
181
|
+
{ label: "seq.overwriteClip(item, ticksString, v, a)", fn: function () { seq.overwriteClip(item, ticksString, vIdx, aIdx); } },
|
|
182
|
+
{ label: "seq.overwriteClip(item, seconds, v, a)", fn: function () { seq.overwriteClip(item, args.startSeconds, vIdx, aIdx); } }
|
|
183
|
+
];
|
|
184
|
+
if (timeObj !== null) {
|
|
185
|
+
seqForms.push({ label: "seq.overwriteClip(item, TimeObject, v, a)", fn: function () { seq.overwriteClip(item, timeObj, vIdx, aIdx); } });
|
|
186
|
+
}
|
|
187
|
+
for (var i = 0; i < seqForms.length && !succeeded; i++) {
|
|
188
|
+
try {
|
|
189
|
+
seqForms[i].fn();
|
|
190
|
+
attempts.push({ form: seqForms[i].label, success: true });
|
|
191
|
+
succeeded = true;
|
|
192
|
+
formUsed = seqForms[i].label;
|
|
193
|
+
} catch (e) {
|
|
194
|
+
attempts.push({ form: seqForms[i].label, success: false, error: e.toString() });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (!succeeded && typeof targetTrack.overwriteClip === "function") {
|
|
200
|
+
var trackForms = [
|
|
201
|
+
{ label: "track.overwriteClip(item, seconds)", fn: function () { targetTrack.overwriteClip(item, args.startSeconds); } }
|
|
202
|
+
];
|
|
203
|
+
if (timeObj !== null) {
|
|
204
|
+
trackForms.push({ label: "track.overwriteClip(item, TimeObject)", fn: function () { targetTrack.overwriteClip(item, timeObj); } });
|
|
205
|
+
}
|
|
206
|
+
for (var j = 0; j < trackForms.length && !succeeded; j++) {
|
|
207
|
+
try {
|
|
208
|
+
trackForms[j].fn();
|
|
209
|
+
attempts.push({ form: trackForms[j].label, success: true });
|
|
210
|
+
succeeded = true;
|
|
211
|
+
formUsed = trackForms[j].label;
|
|
212
|
+
} catch (e) {
|
|
213
|
+
attempts.push({ form: trackForms[j].label, success: false, error: e.toString() });
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
var qeFallbackWarning = null;
|
|
219
|
+
if (!succeeded) {
|
|
220
|
+
try {
|
|
221
|
+
ensureQEEnabled();
|
|
222
|
+
activateSequenceForQE(seq);
|
|
223
|
+
if (typeof qe !== "undefined" && qe.project) {
|
|
224
|
+
var qeSeq = qe.project.getActiveSequence();
|
|
225
|
+
var qeTrack = args.trackType === "video" ? qeSeq.getVideoTrackAt(args.trackIndex) : qeSeq.getAudioTrackAt(args.trackIndex);
|
|
226
|
+
if (qeTrack && typeof qeTrack.overwrite === "function") {
|
|
227
|
+
qeTrack.overwrite(item);
|
|
228
|
+
attempts.push({ form: "qeTrack.overwrite(item)", success: true });
|
|
229
|
+
succeeded = true;
|
|
230
|
+
formUsed = "qeTrack.overwrite(item)";
|
|
231
|
+
qeFallbackWarning = "used the QE fallback, which has NO time argument — the item was placed wherever qeTrack.overwrite() lands on this build (confirmed track-start-of-empty-track behavior per QE_DOM_NOTES.md), NOT necessarily at the requested startSeconds. Check the reported placedStartSeconds below.";
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
} catch (e) {
|
|
235
|
+
attempts.push({ form: "qeTrack.overwrite(item)", success: false, error: e.toString() });
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (!succeeded) {
|
|
240
|
+
return JSON.stringify({
|
|
241
|
+
ok: false,
|
|
242
|
+
error: "could not overwrite the clip onto the timeline with any known argument form or the QE fallback",
|
|
243
|
+
attempts: attempts
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Find the newly-placed clip on the target track nearest the
|
|
248
|
+
// requested start time (nodeId is fresh, so match by proximity).
|
|
249
|
+
var placedStartSeconds = null;
|
|
250
|
+
var placedName = null;
|
|
251
|
+
try {
|
|
252
|
+
var numClipsAfter = targetTrack.clips.numItems;
|
|
253
|
+
var bestDelta = null;
|
|
254
|
+
for (var k = 0; k < numClipsAfter; k++) {
|
|
255
|
+
var candidate = targetTrack.clips[k];
|
|
256
|
+
var candidateStart = null;
|
|
257
|
+
try { candidateStart = timeValueToSeconds(candidate.start); } catch (e2) { candidateStart = null; }
|
|
258
|
+
if (candidateStart === null) {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
var delta = Math.abs(candidateStart - args.startSeconds);
|
|
262
|
+
if (bestDelta === null || delta < bestDelta) {
|
|
263
|
+
bestDelta = delta;
|
|
264
|
+
placedStartSeconds = candidateStart;
|
|
265
|
+
try { placedName = candidate.name; } catch (e3) { placedName = null; }
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
} catch (e) {
|
|
269
|
+
// leave placedStartSeconds/placedName null
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Auto-linked-audio cleanup: scan every audio track for a clip that
|
|
273
|
+
// wasn't in the "before" snapshot, shares the placed item's
|
|
274
|
+
// projectItem nodeId, and sits within 0.1s of the requested start —
|
|
275
|
+
// remove it, iterating tracks/clips backwards since removal shifts
|
|
276
|
+
// later indices.
|
|
277
|
+
var removedAutoLinkedAudio = [];
|
|
278
|
+
if (args.trackType === "video" && itemNodeId !== null) {
|
|
279
|
+
for (var at2 = seq.audioTracks.numTracks - 1; at2 >= 0; at2--) {
|
|
280
|
+
var audioTrack = seq.audioTracks[at2];
|
|
281
|
+
var beforeList = audioTracksBefore[at2] || [];
|
|
282
|
+
var numAudioClips;
|
|
283
|
+
try {
|
|
284
|
+
numAudioClips = audioTrack.clips.numItems;
|
|
285
|
+
} catch (e4) {
|
|
286
|
+
numAudioClips = 0;
|
|
287
|
+
}
|
|
288
|
+
for (var ci = numAudioClips - 1; ci >= 0; ci--) {
|
|
289
|
+
var aClip = audioTrack.clips[ci];
|
|
290
|
+
var aStart = null;
|
|
291
|
+
var aItemNodeId = null;
|
|
292
|
+
try { aStart = timeValueToSeconds(aClip.start); } catch (e5) { aStart = null; }
|
|
293
|
+
try { aItemNodeId = aClip.projectItem.nodeId; } catch (e6) { aItemNodeId = null; }
|
|
294
|
+
if (aItemNodeId !== itemNodeId || aStart === null || Math.abs(aStart - args.startSeconds) > 0.1) {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
// Was this clip already there before the overwrite? Match by
|
|
298
|
+
// nodeId (existing clips keep theirs; a freshly auto-linked
|
|
299
|
+
// clip has a nodeId not present in the "before" snapshot).
|
|
300
|
+
var aNodeId = null;
|
|
301
|
+
try { aNodeId = aClip.nodeId; } catch (e7) { aNodeId = null; }
|
|
302
|
+
var wasPresentBefore = false;
|
|
303
|
+
for (var bi = 0; bi < beforeList.length; bi++) {
|
|
304
|
+
if (beforeList[bi].nodeId === aNodeId) {
|
|
305
|
+
wasPresentBefore = true;
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (wasPresentBefore) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
var removedOk = false;
|
|
313
|
+
try {
|
|
314
|
+
aClip.remove(false, false);
|
|
315
|
+
removedOk = true;
|
|
316
|
+
} catch (e8) {
|
|
317
|
+
removedOk = false;
|
|
318
|
+
}
|
|
319
|
+
removedAutoLinkedAudio.push({
|
|
320
|
+
audioTrackIndex: at2,
|
|
321
|
+
startSeconds: aStart,
|
|
322
|
+
removed: removedOk
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return JSON.stringify({
|
|
329
|
+
ok: true,
|
|
330
|
+
result: {
|
|
331
|
+
sequenceName: seq.name,
|
|
332
|
+
trackType: args.trackType,
|
|
333
|
+
trackIndex: args.trackIndex,
|
|
334
|
+
itemName: (function () { try { return item.name; } catch (e9) { return null; } })(),
|
|
335
|
+
itemNodeId: itemNodeId,
|
|
336
|
+
requestedStartSeconds: args.startSeconds,
|
|
337
|
+
formUsed: formUsed,
|
|
338
|
+
attempts: attempts,
|
|
339
|
+
placedStartSeconds: placedStartSeconds,
|
|
340
|
+
placedName: placedName,
|
|
341
|
+
verified: placedStartSeconds !== null && Math.abs(placedStartSeconds - args.startSeconds) < 0.5,
|
|
342
|
+
removedAutoLinkedAudio: removedAutoLinkedAudio,
|
|
343
|
+
qeFallbackWarning: qeFallbackWarning,
|
|
344
|
+
warning: "destructive: this overwrites whatever was already on the target track at this position, and undo is non-functional on this build."
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
} catch (e) {
|
|
348
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
349
|
+
}
|
|
350
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// Command: overwrite-from-source → ppb_overwriteFromSource
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (secondsToTicksString,
|
|
4
|
+
// timeValueToSeconds, serializeTrackItem, findSequenceByName,
|
|
5
|
+
// ppbAddToTimeline_cleanupLinkedAudio) are already defined there.
|
|
6
|
+
//
|
|
7
|
+
// Ported from leancoderkavy's premiere-pro-mcp source-monitor.ts
|
|
8
|
+
// overwrite_from_source — identical to insert-from-source except it calls
|
|
9
|
+
// seq.overwriteClip() (destroys whatever content is at the target
|
|
10
|
+
// position/duration instead of rippling it later). Destructive.
|
|
11
|
+
//
|
|
12
|
+
// Same auto-linked-audio trap and track-index-ignored caveat as
|
|
13
|
+
// insert-from-source/add-to-timeline — see those files' comments.
|
|
14
|
+
function ppb_overwriteFromSource(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.trackType !== "video" && args.trackType !== "audio") {
|
|
24
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
|
|
25
|
+
}
|
|
26
|
+
if (typeof args.trackIndex !== "number") {
|
|
27
|
+
return JSON.stringify({ ok: false, error: "trackIndex is required" });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!app.project) {
|
|
31
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
var seq = null;
|
|
35
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
36
|
+
seq = findSequenceByName(args.sequenceName);
|
|
37
|
+
if (!seq) {
|
|
38
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
seq = app.project.activeSequence;
|
|
42
|
+
if (!seq) {
|
|
43
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
var item = null;
|
|
48
|
+
try {
|
|
49
|
+
item = app.sourceMonitor.getProjectItem();
|
|
50
|
+
} catch (e2) {
|
|
51
|
+
return JSON.stringify({ ok: false, error: "app.sourceMonitor.getProjectItem() failed: " + e2.toString() });
|
|
52
|
+
}
|
|
53
|
+
if (!item) {
|
|
54
|
+
return JSON.stringify({ ok: false, error: "no clip open in Source Monitor" });
|
|
55
|
+
}
|
|
56
|
+
var itemNodeId = null;
|
|
57
|
+
try { itemNodeId = item.nodeId; } catch (e3) { itemNodeId = null; }
|
|
58
|
+
|
|
59
|
+
var atSeconds = null;
|
|
60
|
+
var posTicks = null;
|
|
61
|
+
if (typeof args.atSeconds === "number" && !isNaN(args.atSeconds)) {
|
|
62
|
+
atSeconds = args.atSeconds;
|
|
63
|
+
posTicks = secondsToTicksString(atSeconds);
|
|
64
|
+
} else {
|
|
65
|
+
try {
|
|
66
|
+
var playerPos = seq.getPlayerPosition();
|
|
67
|
+
posTicks = playerPos.ticks;
|
|
68
|
+
atSeconds = timeValueToSeconds(playerPos);
|
|
69
|
+
} catch (e4) {
|
|
70
|
+
return JSON.stringify({ ok: false, error: "atSeconds was not given and seq.getPlayerPosition() failed: " + e4.toString() });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var trackCollection = args.trackType === "video" ? seq.videoTracks : seq.audioTracks;
|
|
75
|
+
var numTracks;
|
|
76
|
+
try { numTracks = trackCollection.numTracks; } catch (e5) { numTracks = 0; }
|
|
77
|
+
if (args.trackIndex >= numTracks) {
|
|
78
|
+
return JSON.stringify({ ok: false, error: "trackIndex " + args.trackIndex + " is out of range — sequence has " + numTracks + " " + args.trackType + " track(s)" });
|
|
79
|
+
}
|
|
80
|
+
var targetTrack = trackCollection[args.trackIndex];
|
|
81
|
+
var trackClipCountBefore = null;
|
|
82
|
+
try { trackClipCountBefore = targetTrack.clips.numItems; } catch (e6) { trackClipCountBefore = null; }
|
|
83
|
+
|
|
84
|
+
var vIdx = args.trackType === "video" ? args.trackIndex : -1;
|
|
85
|
+
var aIdx = args.trackType === "audio" ? args.trackIndex : -1;
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
seq.overwriteClip(item, posTicks, vIdx, aIdx);
|
|
89
|
+
} catch (e7) {
|
|
90
|
+
return JSON.stringify({ ok: false, error: "seq.overwriteClip() failed: " + e7.toString() });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
var trackClipCountAfter = null;
|
|
94
|
+
try { trackClipCountAfter = targetTrack.clips.numItems; } catch (e8) { trackClipCountAfter = null; }
|
|
95
|
+
|
|
96
|
+
var toleranceSeconds = 0.1;
|
|
97
|
+
function ppbOverwriteFromSource_locate() {
|
|
98
|
+
try {
|
|
99
|
+
for (var t2 = 0; t2 < trackCollection.numTracks; t2++) {
|
|
100
|
+
var scanTrack = trackCollection[t2];
|
|
101
|
+
for (var c2 = 0; c2 < scanTrack.clips.numItems; c2++) {
|
|
102
|
+
var candidate = scanTrack.clips[c2];
|
|
103
|
+
var candNodeId = null;
|
|
104
|
+
try { candNodeId = candidate.projectItem.nodeId; } catch (e9) { candNodeId = null; }
|
|
105
|
+
if (candNodeId !== itemNodeId) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
var candStart = null;
|
|
109
|
+
try { candStart = timeValueToSeconds(candidate.start); } catch (e10) { candStart = null; }
|
|
110
|
+
if (candStart !== null && Math.abs(candStart - atSeconds) <= toleranceSeconds) {
|
|
111
|
+
return serializeTrackItem(candidate, t2, c2);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} catch (e11) {
|
|
116
|
+
// fall through
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
var placedClip = ppbOverwriteFromSource_locate();
|
|
122
|
+
var trackHonored = placedClip !== null && placedClip.trackIndex === args.trackIndex;
|
|
123
|
+
|
|
124
|
+
var linkedAudioCleanup = { performed: false, removedCount: 0, removed: [] };
|
|
125
|
+
if (args.trackType === "video") {
|
|
126
|
+
var removedList = ppbAddToTimeline_cleanupLinkedAudio(seq, itemNodeId, atSeconds, toleranceSeconds);
|
|
127
|
+
linkedAudioCleanup = { performed: true, removedCount: removedList.length, removed: removedList };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return JSON.stringify({
|
|
131
|
+
ok: true,
|
|
132
|
+
result: {
|
|
133
|
+
sequenceName: seq.name,
|
|
134
|
+
overwritten: true,
|
|
135
|
+
trackType: args.trackType,
|
|
136
|
+
requestedTrackIndex: args.trackIndex,
|
|
137
|
+
actualTrackIndex: placedClip !== null ? placedClip.trackIndex : null,
|
|
138
|
+
trackHonored: trackHonored,
|
|
139
|
+
atSeconds: atSeconds,
|
|
140
|
+
item: { name: (function () { try { return item.name; } catch (e) { return null; } })(), nodeId: itemNodeId },
|
|
141
|
+
placedClip: placedClip,
|
|
142
|
+
trackClipCountBefore: trackClipCountBefore,
|
|
143
|
+
trackClipCountAfter: trackClipCountAfter,
|
|
144
|
+
linkedAudioCleanup: linkedAudioCleanup
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
} catch (e) {
|
|
148
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Command: play-source-monitor → ppb_playSourceMonitor
|
|
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 playback.ts
|
|
6
|
+
// play_source_monitor. Standard DOM (app.sourceMonitor.play(speed)) — no
|
|
7
|
+
// QE, no sequence involved (operates on whatever clip is currently open
|
|
8
|
+
// in the Source Monitor).
|
|
9
|
+
function ppb_playSourceMonitor(argsJson) {
|
|
10
|
+
try {
|
|
11
|
+
var args;
|
|
12
|
+
try {
|
|
13
|
+
args = JSON.parse(argsJson);
|
|
14
|
+
} catch (e) {
|
|
15
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
var speed = 1.0;
|
|
19
|
+
if (args.speed !== undefined && args.speed !== null) {
|
|
20
|
+
if (typeof args.speed !== "number" || isNaN(args.speed)) {
|
|
21
|
+
return JSON.stringify({ ok: false, error: "speed must be a number" });
|
|
22
|
+
}
|
|
23
|
+
speed = args.speed;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
app.sourceMonitor.play(speed);
|
|
28
|
+
} catch (e) {
|
|
29
|
+
return JSON.stringify({ ok: false, error: "could not play source monitor: " + e.toString() });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return JSON.stringify({ ok: true, result: { playing: true, speed: speed } });
|
|
33
|
+
} catch (e) {
|
|
34
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Command: play-timeline → ppb_playTimeline
|
|
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
|
+
// Ported from leancoderkavy/premiere-pro-mcp's playback.ts play_timeline.
|
|
7
|
+
// QE DOM only (qe.startPlayback()) — this is inherently active-sequence-
|
|
8
|
+
// only, there is no sequenceName override: the QE DOM always operates on
|
|
9
|
+
// whichever sequence tab is currently frontmost in Premiere.
|
|
10
|
+
function ppb_playTimeline(argsJson) {
|
|
11
|
+
try {
|
|
12
|
+
ensureQEEnabled();
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
qe.startPlayback();
|
|
16
|
+
} catch (e) {
|
|
17
|
+
return JSON.stringify({ ok: false, error: "could not start playback: " + e.toString() });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return JSON.stringify({ ok: true, result: { playing: true } });
|
|
21
|
+
} catch (e) {
|
|
22
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
23
|
+
}
|
|
24
|
+
}
|