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,89 @@
|
|
|
1
|
+
// Command: get-sequence-markers-by-type → ppb_getSequenceMarkersByType
|
|
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, timeValueToSeconds, ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Same marker iteration pattern as get-full-sequence-info.jsx and
|
|
7
|
+
// list-markers.jsx (getFirstMarker/getNextMarker, capped at 10000),
|
|
8
|
+
// filtering to markers whose type matches the requested type.
|
|
9
|
+
|
|
10
|
+
var PPB_MARKER_TYPES = ["Comment", "Chapter", "Segmentation", "WebLink", "FlashCuePoint"];
|
|
11
|
+
|
|
12
|
+
function ppbMarkersByType_isValidType(type) {
|
|
13
|
+
for (var i = 0; i < PPB_MARKER_TYPES.length; i++) {
|
|
14
|
+
if (PPB_MARKER_TYPES[i] === type) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function ppbMarkersByType_serialize(seq, type) {
|
|
22
|
+
var markers = [];
|
|
23
|
+
var m = seq.markers.getFirstMarker();
|
|
24
|
+
var iterations = 0;
|
|
25
|
+
while (m !== null && typeof m !== "undefined" && iterations < 10000) {
|
|
26
|
+
var markerType = null;
|
|
27
|
+
try { markerType = m.type; } catch (e) { markerType = null; }
|
|
28
|
+
|
|
29
|
+
if (markerType === type) {
|
|
30
|
+
var entry = { name: null, comments: null, type: markerType, startSeconds: null, endSeconds: null, guid: null };
|
|
31
|
+
try { entry.name = m.name; } catch (e) { entry.name = null; }
|
|
32
|
+
try { entry.comments = m.comments; } catch (e) { entry.comments = null; }
|
|
33
|
+
try { entry.startSeconds = timeValueToSeconds(m.start); } catch (e) { entry.startSeconds = null; }
|
|
34
|
+
try { entry.endSeconds = timeValueToSeconds(m.end); } catch (e) { entry.endSeconds = null; }
|
|
35
|
+
try { entry.guid = m.guid; } catch (e) { entry.guid = null; }
|
|
36
|
+
markers.push(entry);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
m = seq.markers.getNextMarker(m);
|
|
40
|
+
iterations++;
|
|
41
|
+
}
|
|
42
|
+
return markers;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function ppb_getSequenceMarkersByType(argsJson) {
|
|
46
|
+
try {
|
|
47
|
+
var args;
|
|
48
|
+
try {
|
|
49
|
+
args = JSON.parse(argsJson);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (typeof args.type !== "string" || !ppbMarkersByType_isValidType(args.type)) {
|
|
55
|
+
return JSON.stringify({ ok: false, error: "type must be one of: " + PPB_MARKER_TYPES.join(", ") });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!app.project) {
|
|
59
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
var seq = null;
|
|
63
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
64
|
+
seq = findSequenceByName(args.sequenceName);
|
|
65
|
+
if (!seq) {
|
|
66
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
seq = app.project.activeSequence;
|
|
70
|
+
if (!seq) {
|
|
71
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
var markers = [];
|
|
76
|
+
try {
|
|
77
|
+
markers = ppbMarkersByType_serialize(seq, args.type);
|
|
78
|
+
} catch (e) {
|
|
79
|
+
return JSON.stringify({ ok: false, error: "failed to read markers: " + e.toString() });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return JSON.stringify({
|
|
83
|
+
ok: true,
|
|
84
|
+
result: { sequenceName: seq.name, type: args.type, markers: markers, count: markers.length }
|
|
85
|
+
});
|
|
86
|
+
} catch (e) {
|
|
87
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Command: get-source-monitor-info → ppb_getSourceMonitorInfo
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use.
|
|
3
|
+
//
|
|
4
|
+
// Standard-DOM read only — no QE DOM needed. Ported from leancoderkavy's
|
|
5
|
+
// premiere-pro-mcp `get_source_monitor_info` tool (source-monitor.ts). No
|
|
6
|
+
// clip loaded in the Source Monitor is a valid, truthful "loaded: false"
|
|
7
|
+
// result, not an error — same convention as get-premiere-state.
|
|
8
|
+
|
|
9
|
+
function ppb_getSourceMonitorInfo() {
|
|
10
|
+
try {
|
|
11
|
+
var item = null;
|
|
12
|
+
try {
|
|
13
|
+
item = app.sourceMonitor.getProjectItem();
|
|
14
|
+
} catch (e) {
|
|
15
|
+
return JSON.stringify({ ok: false, error: "app.sourceMonitor.getProjectItem() failed: " + e.toString() });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!item) {
|
|
19
|
+
return JSON.stringify({ ok: true, result: { loaded: false } });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
var result = { loaded: true, nodeId: null, name: null, mediaPath: null, inPointSeconds: null, outPointSeconds: null };
|
|
23
|
+
|
|
24
|
+
try { result.nodeId = item.nodeId; } catch (e) { result.nodeId = null; }
|
|
25
|
+
try { result.name = item.name; } catch (e) { result.name = null; }
|
|
26
|
+
try { result.mediaPath = item.getMediaPath(); } catch (e) { result.mediaPath = null; }
|
|
27
|
+
try { result.inPointSeconds = timeValueToSeconds(item.getInPoint()); } catch (e) { result.inPointSeconds = null; }
|
|
28
|
+
try { result.outPointSeconds = timeValueToSeconds(item.getOutPoint()); } catch (e) { result.outPointSeconds = null; }
|
|
29
|
+
|
|
30
|
+
return JSON.stringify({ ok: true, result: result });
|
|
31
|
+
} catch (e) {
|
|
32
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Command: get-source-monitor-position → ppb_getSourceMonitorPosition
|
|
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
|
+
// timeValueToSeconds, ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Ported from leancoderkavy/premiere-pro-mcp's playback.ts
|
|
7
|
+
// get_source_monitor_position. Standard DOM (app.sourceMonitor.getPosition())
|
|
8
|
+
// — no sequence involved. Fails if no clip is currently open in the
|
|
9
|
+
// Source Monitor.
|
|
10
|
+
function ppb_getSourceMonitorPosition(argsJson) {
|
|
11
|
+
try {
|
|
12
|
+
var pos = null;
|
|
13
|
+
try {
|
|
14
|
+
pos = app.sourceMonitor.getPosition();
|
|
15
|
+
} catch (e) {
|
|
16
|
+
return JSON.stringify({ ok: false, error: "could not read source monitor position: " + e.toString() });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (pos === null || typeof pos === "undefined") {
|
|
20
|
+
return JSON.stringify({ ok: false, error: "no clip open in Source Monitor" });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var seconds = null;
|
|
24
|
+
try { seconds = timeValueToSeconds(pos); } catch (e) { seconds = null; }
|
|
25
|
+
|
|
26
|
+
return JSON.stringify({ ok: true, result: { seconds: seconds } });
|
|
27
|
+
} catch (e) {
|
|
28
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Command: get-target-tracks → ppb_getTargetTracks
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Standard-DOM read only — no QE DOM needed, no need to activate the
|
|
7
|
+
// sequence tab. Ported from leancoderkavy's premiere-pro-mcp
|
|
8
|
+
// `get_target_tracks` tool (track-targeting.ts), which only reads the
|
|
9
|
+
// active sequence; here `sequenceName` may target any open sequence.
|
|
10
|
+
|
|
11
|
+
function ppb_getTargetTracks(argsJson) {
|
|
12
|
+
try {
|
|
13
|
+
var args;
|
|
14
|
+
try {
|
|
15
|
+
args = JSON.parse(argsJson);
|
|
16
|
+
} catch (e) {
|
|
17
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!app.project) {
|
|
21
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var seq = null;
|
|
25
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
26
|
+
seq = findSequenceByName(args.sequenceName);
|
|
27
|
+
if (!seq) {
|
|
28
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
seq = app.project.activeSequence;
|
|
32
|
+
if (!seq) {
|
|
33
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var video = [];
|
|
38
|
+
try {
|
|
39
|
+
for (var v = 0; v < seq.videoTracks.numTracks; v++) {
|
|
40
|
+
var vTrack = seq.videoTracks[v];
|
|
41
|
+
try {
|
|
42
|
+
if (vTrack.isTargeted()) {
|
|
43
|
+
video.push({ index: v, name: vTrack.name });
|
|
44
|
+
}
|
|
45
|
+
} catch (e) {
|
|
46
|
+
// skip tracks whose isTargeted() throws
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
} catch (e) {
|
|
50
|
+
// leave video as whatever was collected so far
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
var audio = [];
|
|
54
|
+
try {
|
|
55
|
+
for (var a = 0; a < seq.audioTracks.numTracks; a++) {
|
|
56
|
+
var aTrack = seq.audioTracks[a];
|
|
57
|
+
try {
|
|
58
|
+
if (aTrack.isTargeted()) {
|
|
59
|
+
audio.push({ index: a, name: aTrack.name });
|
|
60
|
+
}
|
|
61
|
+
} catch (e) {
|
|
62
|
+
// skip tracks whose isTargeted() throws
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
} catch (e) {
|
|
66
|
+
// leave audio as whatever was collected so far
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return JSON.stringify({
|
|
70
|
+
ok: true,
|
|
71
|
+
result: { sequenceName: seq.name, video: video, audio: audio }
|
|
72
|
+
});
|
|
73
|
+
} catch (e) {
|
|
74
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Command: get-timeline-gaps → ppb_getTimelineGaps
|
|
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, timeValueToSeconds, ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Standard-DOM read only, no QE DOM needed. Assumes each track's clips
|
|
7
|
+
// collection is already ordered by start time (Premiere returns it that
|
|
8
|
+
// way) — walks each track once, tracking the end of the previous clip and
|
|
9
|
+
// reporting any gap larger than minGapSeconds before the next one.
|
|
10
|
+
|
|
11
|
+
var PPB_TIMELINE_GAPS_DEFAULT_MIN_SECONDS = 0.04;
|
|
12
|
+
|
|
13
|
+
function ppbTimelineGaps_findGaps(tracks, trackType, minGapSeconds, gaps) {
|
|
14
|
+
for (var t = 0; t < tracks.numTracks; t++) {
|
|
15
|
+
var track = tracks[t];
|
|
16
|
+
var numClips = 0;
|
|
17
|
+
try {
|
|
18
|
+
numClips = track.clips.numItems;
|
|
19
|
+
} catch (e) {
|
|
20
|
+
numClips = 0;
|
|
21
|
+
}
|
|
22
|
+
if (numClips === 0) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var trackName = null;
|
|
27
|
+
try { trackName = track.name; } catch (e) { trackName = null; }
|
|
28
|
+
|
|
29
|
+
var prevEnd = 0;
|
|
30
|
+
var prevClipName = null;
|
|
31
|
+
for (var c = 0; c < numClips; c++) {
|
|
32
|
+
var clip = track.clips[c];
|
|
33
|
+
|
|
34
|
+
var startSeconds = null;
|
|
35
|
+
var endSeconds = null;
|
|
36
|
+
var clipName = null;
|
|
37
|
+
try { startSeconds = timeValueToSeconds(clip.start); } catch (e) { startSeconds = null; }
|
|
38
|
+
try { endSeconds = timeValueToSeconds(clip.end); } catch (e) { endSeconds = null; }
|
|
39
|
+
try { clipName = clip.name; } catch (e) { clipName = null; }
|
|
40
|
+
|
|
41
|
+
if (startSeconds !== null) {
|
|
42
|
+
var gapSeconds = startSeconds - prevEnd;
|
|
43
|
+
if (gapSeconds > minGapSeconds) {
|
|
44
|
+
gaps.push({
|
|
45
|
+
trackType: trackType,
|
|
46
|
+
trackIndex: t,
|
|
47
|
+
trackName: trackName,
|
|
48
|
+
gapStartSeconds: prevEnd,
|
|
49
|
+
gapEndSeconds: startSeconds,
|
|
50
|
+
gapDurationSeconds: gapSeconds,
|
|
51
|
+
beforeClip: prevClipName,
|
|
52
|
+
afterClip: clipName
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (endSeconds !== null) {
|
|
58
|
+
prevEnd = endSeconds;
|
|
59
|
+
}
|
|
60
|
+
prevClipName = clipName;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function ppb_getTimelineGaps(argsJson) {
|
|
66
|
+
try {
|
|
67
|
+
var args;
|
|
68
|
+
try {
|
|
69
|
+
args = JSON.parse(argsJson);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!app.project) {
|
|
75
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
var seq = null;
|
|
79
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
80
|
+
seq = findSequenceByName(args.sequenceName);
|
|
81
|
+
if (!seq) {
|
|
82
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
seq = app.project.activeSequence;
|
|
86
|
+
if (!seq) {
|
|
87
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
var trackType = args.trackType;
|
|
92
|
+
if (trackType !== "video" && trackType !== "audio" && trackType !== "both" && typeof trackType !== "undefined" && trackType !== null) {
|
|
93
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\", \"audio\", or \"both\"" });
|
|
94
|
+
}
|
|
95
|
+
if (!trackType) {
|
|
96
|
+
trackType = "both";
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
var minGapSeconds = PPB_TIMELINE_GAPS_DEFAULT_MIN_SECONDS;
|
|
100
|
+
if (typeof args.minGapSeconds === "number" && args.minGapSeconds >= 0) {
|
|
101
|
+
minGapSeconds = args.minGapSeconds;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
var gaps = [];
|
|
105
|
+
if (trackType !== "audio") {
|
|
106
|
+
ppbTimelineGaps_findGaps(seq.videoTracks, "video", minGapSeconds, gaps);
|
|
107
|
+
}
|
|
108
|
+
if (trackType !== "video") {
|
|
109
|
+
ppbTimelineGaps_findGaps(seq.audioTracks, "audio", minGapSeconds, gaps);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return JSON.stringify({
|
|
113
|
+
ok: true,
|
|
114
|
+
result: {
|
|
115
|
+
sequenceName: seq.name,
|
|
116
|
+
gapCount: gaps.length,
|
|
117
|
+
minGapSeconds: minGapSeconds,
|
|
118
|
+
gaps: gaps
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
} catch (e) {
|
|
122
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// Command: get-timeline-summary → ppb_getTimelineSummary
|
|
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, serializeTrackItem, ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Standard-DOM read only (seq.videoTracks[i].clips[j]) — no QE DOM needed,
|
|
7
|
+
// no need to activate the sequence tab. Compact, human-oriented overview —
|
|
8
|
+
// no per-clip data, just per-track roll-ups.
|
|
9
|
+
|
|
10
|
+
// video clips have Motion+Opacity built in (2 baseline components);
|
|
11
|
+
// audio clips have their own built-in component(s) (Volume etc, baseline 1).
|
|
12
|
+
var GET_TIMELINE_SUMMARY_VIDEO_BASELINE_COMPONENTS = 2;
|
|
13
|
+
var GET_TIMELINE_SUMMARY_AUDIO_BASELINE_COMPONENTS = 1;
|
|
14
|
+
|
|
15
|
+
function ppb_summarizeTrackForTimelineSummary(track, trackIndex, durationSeconds, baselineComponents) {
|
|
16
|
+
var out = { index: trackIndex, name: null, clipCount: 0, coveragePercent: 0 };
|
|
17
|
+
var totalClips = 0;
|
|
18
|
+
var clipsWithEffects = 0;
|
|
19
|
+
var coveredSeconds = 0;
|
|
20
|
+
|
|
21
|
+
try { out.name = track.name; } catch (e) { out.name = null; }
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
var numClips = track.clips.numItems;
|
|
25
|
+
out.clipCount = numClips;
|
|
26
|
+
totalClips = numClips;
|
|
27
|
+
|
|
28
|
+
for (var c = 0; c < numClips; c++) {
|
|
29
|
+
var clip = track.clips[c];
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
var clipDuration = timeValueToSeconds(clip.duration);
|
|
33
|
+
if (clipDuration !== null) {
|
|
34
|
+
coveredSeconds += clipDuration;
|
|
35
|
+
}
|
|
36
|
+
} catch (e) {
|
|
37
|
+
// skip unreadable clip duration
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
if (clip.components.numItems > baselineComponents) {
|
|
42
|
+
clipsWithEffects++;
|
|
43
|
+
}
|
|
44
|
+
} catch (e) {
|
|
45
|
+
// skip unreadable clip components
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} catch (e) {
|
|
49
|
+
// leave clipCount/totals as whatever was collected so far
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (durationSeconds && durationSeconds > 0) {
|
|
53
|
+
out.coveragePercent = Math.round((coveredSeconds / durationSeconds) * 1000) / 10;
|
|
54
|
+
} else {
|
|
55
|
+
out.coveragePercent = 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return { track: out, totalClips: totalClips, clipsWithEffects: clipsWithEffects };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function ppb_getTimelineSummary(argsJson) {
|
|
62
|
+
try {
|
|
63
|
+
var args;
|
|
64
|
+
try {
|
|
65
|
+
args = JSON.parse(argsJson);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!app.project) {
|
|
71
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var seq = null;
|
|
75
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
76
|
+
seq = findSequenceByName(args.sequenceName);
|
|
77
|
+
if (!seq) {
|
|
78
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
seq = app.project.activeSequence;
|
|
82
|
+
if (!seq) {
|
|
83
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
var frameRate = null;
|
|
88
|
+
try {
|
|
89
|
+
frameRate = getSequenceFps(seq);
|
|
90
|
+
} catch (e) {
|
|
91
|
+
frameRate = null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var durationSeconds = null;
|
|
95
|
+
try {
|
|
96
|
+
durationSeconds = (Number(seq.end) - Number(seq.zeroPoint)) / TICKS_PER_SECOND;
|
|
97
|
+
} catch (e) {
|
|
98
|
+
durationSeconds = null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
var totalClips = 0;
|
|
102
|
+
var clipsWithEffects = 0;
|
|
103
|
+
|
|
104
|
+
var videoTracks = [];
|
|
105
|
+
try {
|
|
106
|
+
for (var v = 0; v < seq.videoTracks.numTracks; v++) {
|
|
107
|
+
var vSummary = ppb_summarizeTrackForTimelineSummary(
|
|
108
|
+
seq.videoTracks[v], v, durationSeconds, GET_TIMELINE_SUMMARY_VIDEO_BASELINE_COMPONENTS
|
|
109
|
+
);
|
|
110
|
+
videoTracks.push(vSummary.track);
|
|
111
|
+
totalClips += vSummary.totalClips;
|
|
112
|
+
clipsWithEffects += vSummary.clipsWithEffects;
|
|
113
|
+
}
|
|
114
|
+
} catch (e) {
|
|
115
|
+
// leave videoTracks as whatever was collected so far
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
var audioTracks = [];
|
|
119
|
+
try {
|
|
120
|
+
for (var a = 0; a < seq.audioTracks.numTracks; a++) {
|
|
121
|
+
var aSummary = ppb_summarizeTrackForTimelineSummary(
|
|
122
|
+
seq.audioTracks[a], a, durationSeconds, GET_TIMELINE_SUMMARY_AUDIO_BASELINE_COMPONENTS
|
|
123
|
+
);
|
|
124
|
+
audioTracks.push(aSummary.track);
|
|
125
|
+
totalClips += aSummary.totalClips;
|
|
126
|
+
clipsWithEffects += aSummary.clipsWithEffects;
|
|
127
|
+
}
|
|
128
|
+
} catch (e) {
|
|
129
|
+
// leave audioTracks as whatever was collected so far
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
var markerCount = null;
|
|
133
|
+
try {
|
|
134
|
+
markerCount = seq.markers.numMarkers;
|
|
135
|
+
} catch (e) {
|
|
136
|
+
markerCount = null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
var result = {
|
|
140
|
+
sequenceName: seq.name,
|
|
141
|
+
frameRate: frameRate,
|
|
142
|
+
durationSeconds: durationSeconds,
|
|
143
|
+
videoTracks: videoTracks,
|
|
144
|
+
audioTracks: audioTracks,
|
|
145
|
+
totalClips: totalClips,
|
|
146
|
+
clipsWithEffects: clipsWithEffects,
|
|
147
|
+
markerCount: markerCount
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
return JSON.stringify({ ok: true, result: result });
|
|
151
|
+
} catch (e) {
|
|
152
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Command: get-total-clip-count → ppb_getTotalClipCount
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Standard-DOM read only — no QE DOM needed, no need to activate the
|
|
7
|
+
// sequence tab. Ported from leancoderkavy's premiere-pro-mcp
|
|
8
|
+
// `get_total_clip_count` tool (utility.ts), which only reads the active
|
|
9
|
+
// sequence; here `sequenceName` may target any open sequence.
|
|
10
|
+
|
|
11
|
+
function ppb_getTotalClipCount(argsJson) {
|
|
12
|
+
try {
|
|
13
|
+
var args;
|
|
14
|
+
try {
|
|
15
|
+
args = JSON.parse(argsJson);
|
|
16
|
+
} catch (e) {
|
|
17
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!app.project) {
|
|
21
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var seq = null;
|
|
25
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
26
|
+
seq = findSequenceByName(args.sequenceName);
|
|
27
|
+
if (!seq) {
|
|
28
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
seq = app.project.activeSequence;
|
|
32
|
+
if (!seq) {
|
|
33
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var videoClips = 0;
|
|
38
|
+
try {
|
|
39
|
+
for (var v = 0; v < seq.videoTracks.numTracks; v++) {
|
|
40
|
+
videoClips += seq.videoTracks[v].clips.numItems;
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {
|
|
43
|
+
// leave videoClips as whatever was collected so far
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
var audioClips = 0;
|
|
47
|
+
try {
|
|
48
|
+
for (var a = 0; a < seq.audioTracks.numTracks; a++) {
|
|
49
|
+
audioClips += seq.audioTracks[a].clips.numItems;
|
|
50
|
+
}
|
|
51
|
+
} catch (e) {
|
|
52
|
+
// leave audioClips as whatever was collected so far
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return JSON.stringify({
|
|
56
|
+
ok: true,
|
|
57
|
+
result: {
|
|
58
|
+
sequenceName: seq.name,
|
|
59
|
+
videoClips: videoClips,
|
|
60
|
+
audioClips: audioClips,
|
|
61
|
+
total: videoClips + audioClips
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
} catch (e) {
|
|
65
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Command: get-track-info → ppb_getTrackInfo
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// timeValueToSeconds, ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Standard-DOM read only — no QE DOM needed, no need to activate the
|
|
7
|
+
// sequence tab. Ported from leancoderkavy's premiere-pro-mcp
|
|
8
|
+
// `get_track_info` tool (track-targeting.ts).
|
|
9
|
+
|
|
10
|
+
function ppb_getTrackInfo(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.trackType !== "video" && args.trackType !== "audio") {
|
|
20
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
|
|
21
|
+
}
|
|
22
|
+
if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
|
|
23
|
+
return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
|
|
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 trackCollection = args.trackType === "video" ? seq.videoTracks : seq.audioTracks;
|
|
44
|
+
var numTracks = trackCollection.numTracks;
|
|
45
|
+
if (args.trackIndex >= numTracks) {
|
|
46
|
+
return JSON.stringify({
|
|
47
|
+
ok: false,
|
|
48
|
+
error: "trackIndex " + args.trackIndex + " is out of range — sequence has " + numTracks + " " + args.trackType + " track(s)"
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var track = trackCollection[args.trackIndex];
|
|
53
|
+
|
|
54
|
+
var result = {
|
|
55
|
+
sequenceName: seq.name,
|
|
56
|
+
trackType: args.trackType,
|
|
57
|
+
trackIndex: args.trackIndex,
|
|
58
|
+
name: null,
|
|
59
|
+
clipCount: 0,
|
|
60
|
+
isMuted: null,
|
|
61
|
+
isLocked: null,
|
|
62
|
+
isTargeted: null,
|
|
63
|
+
clips: [],
|
|
64
|
+
transitions: []
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
try { result.name = track.name; } catch (e) { result.name = null; }
|
|
68
|
+
try { result.isMuted = track.isMuted(); } catch (e) { result.isMuted = null; }
|
|
69
|
+
try { result.isLocked = track.isLocked(); } catch (e) { result.isLocked = null; }
|
|
70
|
+
try { result.isTargeted = track.isTargeted(); } catch (e) { result.isTargeted = null; }
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
var numClips = track.clips.numItems;
|
|
74
|
+
result.clipCount = numClips;
|
|
75
|
+
for (var c = 0; c < numClips; c++) {
|
|
76
|
+
var clip = track.clips[c];
|
|
77
|
+
var ci = {
|
|
78
|
+
clipIndex: c,
|
|
79
|
+
nodeId: null,
|
|
80
|
+
name: null,
|
|
81
|
+
startSeconds: null,
|
|
82
|
+
endSeconds: null,
|
|
83
|
+
durationSeconds: null,
|
|
84
|
+
disabled: null,
|
|
85
|
+
speed: null
|
|
86
|
+
};
|
|
87
|
+
try { ci.nodeId = clip.nodeId; } catch (e) { ci.nodeId = null; }
|
|
88
|
+
try { ci.name = clip.name; } catch (e) { ci.name = null; }
|
|
89
|
+
try { ci.startSeconds = timeValueToSeconds(clip.start); } catch (e) { ci.startSeconds = null; }
|
|
90
|
+
try { ci.endSeconds = timeValueToSeconds(clip.end); } catch (e) { ci.endSeconds = null; }
|
|
91
|
+
try { ci.durationSeconds = timeValueToSeconds(clip.duration); } catch (e) { ci.durationSeconds = null; }
|
|
92
|
+
try { ci.disabled = clip.disabled; } catch (e) { ci.disabled = null; }
|
|
93
|
+
try { ci.speed = clip.getSpeed(); } catch (e) { ci.speed = null; }
|
|
94
|
+
result.clips.push(ci);
|
|
95
|
+
}
|
|
96
|
+
} catch (e) {
|
|
97
|
+
// leave clips as whatever was collected so far
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
var numTransitions = track.transitions.numItems;
|
|
102
|
+
for (var t = 0; t < numTransitions; t++) {
|
|
103
|
+
var transition = track.transitions[t];
|
|
104
|
+
var ti = { transitionIndex: t, startSeconds: null, endSeconds: null };
|
|
105
|
+
try { ti.startSeconds = timeValueToSeconds(transition.start); } catch (e) { ti.startSeconds = null; }
|
|
106
|
+
try { ti.endSeconds = timeValueToSeconds(transition.end); } catch (e) { ti.endSeconds = null; }
|
|
107
|
+
result.transitions.push(ti);
|
|
108
|
+
}
|
|
109
|
+
} catch (e) {
|
|
110
|
+
// transitions collection unavailable on this track/build — leave empty
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return JSON.stringify({ ok: true, result: result });
|
|
114
|
+
} catch (e) {
|
|
115
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
116
|
+
}
|
|
117
|
+
}
|