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,193 @@
|
|
|
1
|
+
// Command: get-full-project-overview → ppb_getFullProjectOverview
|
|
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
|
+
// ensureQEEnabled, findSequenceByName, ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Builds a nested bin tree of the whole project plus a mediaTypeCounts
|
|
7
|
+
// classification of every non-bin item by its mediaPath extension. Helper
|
|
8
|
+
// names are prefixed ppbFullOverview_ to avoid colliding with same-purpose
|
|
9
|
+
// helpers in other lazily-loaded command files evaluated into this same
|
|
10
|
+
// global context.
|
|
11
|
+
|
|
12
|
+
var PPB_FULL_OVERVIEW_VIDEO_EXTENSIONS = ["mp4", "mov", "mxf", "avi", "m4v", "mts"];
|
|
13
|
+
var PPB_FULL_OVERVIEW_AUDIO_EXTENSIONS = ["wav", "mp3", "aac", "m4a", "aiff"];
|
|
14
|
+
var PPB_FULL_OVERVIEW_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "tif", "tiff", "psd", "svg", "gif"];
|
|
15
|
+
|
|
16
|
+
function ppbFullOverview_extOf(mediaPath) {
|
|
17
|
+
if (!mediaPath || typeof mediaPath !== "string") {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
var dot = mediaPath.lastIndexOf(".");
|
|
21
|
+
if (dot === -1 || dot === mediaPath.length - 1) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return mediaPath.substring(dot + 1).toLowerCase();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function ppbFullOverview_inList(ext, list) {
|
|
28
|
+
if (ext === null) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
for (var i = 0; i < list.length; i++) {
|
|
32
|
+
if (list[i] === ext) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function ppbFullOverview_isBin(item) {
|
|
40
|
+
try {
|
|
41
|
+
return typeof ProjectItemType !== "undefined" && item.type === ProjectItemType.BIN;
|
|
42
|
+
} catch (e) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function ppbFullOverview_typeToString(item) {
|
|
48
|
+
try {
|
|
49
|
+
if (typeof ProjectItemType !== "undefined") {
|
|
50
|
+
if (item.type === ProjectItemType.CLIP) {
|
|
51
|
+
return "CLIP";
|
|
52
|
+
}
|
|
53
|
+
if (item.type === ProjectItemType.FILE) {
|
|
54
|
+
return "FILE";
|
|
55
|
+
}
|
|
56
|
+
if (item.type === ProjectItemType.ROOT) {
|
|
57
|
+
return "ROOT";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
} catch (e) {
|
|
61
|
+
// fall through to raw number below
|
|
62
|
+
}
|
|
63
|
+
return String(item.type);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Classifies one non-bin item into counts. A sequence item always counts
|
|
67
|
+
// as "sequence" regardless of any extension on its mediaPath. An offline
|
|
68
|
+
// item ADDITIONALLY increments "offline", on top of its type bucket.
|
|
69
|
+
function ppbFullOverview_classify(item, counts) {
|
|
70
|
+
var isSequence = false;
|
|
71
|
+
try {
|
|
72
|
+
isSequence = item.isSequence();
|
|
73
|
+
} catch (e) {
|
|
74
|
+
isSequence = false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
var isOffline = false;
|
|
78
|
+
try {
|
|
79
|
+
isOffline = item.isOffline();
|
|
80
|
+
} catch (e) {
|
|
81
|
+
isOffline = false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
var mediaPath = null;
|
|
85
|
+
try {
|
|
86
|
+
mediaPath = item.getMediaPath();
|
|
87
|
+
} catch (e) {
|
|
88
|
+
mediaPath = null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (isSequence) {
|
|
92
|
+
counts.sequence++;
|
|
93
|
+
} else {
|
|
94
|
+
var ext = ppbFullOverview_extOf(mediaPath);
|
|
95
|
+
if (ppbFullOverview_inList(ext, PPB_FULL_OVERVIEW_VIDEO_EXTENSIONS)) {
|
|
96
|
+
counts.video++;
|
|
97
|
+
} else if (ppbFullOverview_inList(ext, PPB_FULL_OVERVIEW_AUDIO_EXTENSIONS)) {
|
|
98
|
+
counts.audio++;
|
|
99
|
+
} else if (ppbFullOverview_inList(ext, PPB_FULL_OVERVIEW_IMAGE_EXTENSIONS)) {
|
|
100
|
+
counts.image++;
|
|
101
|
+
} else {
|
|
102
|
+
counts.other++;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (isOffline) {
|
|
107
|
+
counts.offline++;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Capped at depth 32 to defend against pathological/circular bin
|
|
112
|
+
// structures rather than looping forever.
|
|
113
|
+
function ppbFullOverview_buildBinTree(item, counts, depth) {
|
|
114
|
+
var node = { name: item.name, bins: [], items: [] };
|
|
115
|
+
|
|
116
|
+
if (depth > 32 || !item.children) {
|
|
117
|
+
return node;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
121
|
+
var child = item.children[i];
|
|
122
|
+
|
|
123
|
+
if (ppbFullOverview_isBin(child)) {
|
|
124
|
+
node.bins.push(ppbFullOverview_buildBinTree(child, counts, depth + 1));
|
|
125
|
+
} else {
|
|
126
|
+
var mediaPath = null;
|
|
127
|
+
try {
|
|
128
|
+
mediaPath = child.getMediaPath();
|
|
129
|
+
} catch (e) {
|
|
130
|
+
mediaPath = null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
node.items.push({
|
|
134
|
+
name: child.name,
|
|
135
|
+
type: ppbFullOverview_typeToString(child),
|
|
136
|
+
mediaPath: mediaPath
|
|
137
|
+
});
|
|
138
|
+
ppbFullOverview_classify(child, counts);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return node;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function ppb_getFullProjectOverview(argsJson) {
|
|
146
|
+
try {
|
|
147
|
+
if (!app.project) {
|
|
148
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
var proj = app.project;
|
|
152
|
+
var sequences = [];
|
|
153
|
+
|
|
154
|
+
for (var j = 0; j < proj.sequences.numSequences; j++) {
|
|
155
|
+
var seq = proj.sequences[j];
|
|
156
|
+
var frameRate = null;
|
|
157
|
+
var durationSeconds = null;
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
frameRate = TICKS_PER_SECOND / Number(seq.timebase);
|
|
161
|
+
} catch (e) {
|
|
162
|
+
frameRate = null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
durationSeconds = (Number(seq.end) - Number(seq.zeroPoint)) / TICKS_PER_SECOND;
|
|
167
|
+
} catch (e) {
|
|
168
|
+
durationSeconds = null;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
sequences.push({
|
|
172
|
+
name: seq.name,
|
|
173
|
+
sequenceID: seq.sequenceID,
|
|
174
|
+
frameRate: frameRate,
|
|
175
|
+
durationSeconds: durationSeconds
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
var counts = { video: 0, audio: 0, image: 0, sequence: 0, other: 0, offline: 0 };
|
|
180
|
+
var binTree = ppbFullOverview_buildBinTree(proj.rootItem, counts, 1);
|
|
181
|
+
|
|
182
|
+
var result = {
|
|
183
|
+
project: { name: proj.name, path: proj.path },
|
|
184
|
+
binTree: binTree,
|
|
185
|
+
sequences: sequences,
|
|
186
|
+
mediaTypeCounts: counts
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
return JSON.stringify({ ok: true, result: result });
|
|
190
|
+
} catch (e) {
|
|
191
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// Command: get-full-sequence-info → ppb_getFullSequenceInfo
|
|
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. This is a self-contained command
|
|
8
|
+
// file (each command file loads independently, so it cannot rely on
|
|
9
|
+
// helpers defined only in another command file) — its own clip/track
|
|
10
|
+
// serialization is defined locally, layering `components` on top of the
|
|
11
|
+
// shared serializeTrackItem() fields.
|
|
12
|
+
|
|
13
|
+
// Per PREMIERE_API_NOTES.md's component model: clip.components[0]=Motion,
|
|
14
|
+
// [1]=Opacity, [2+]=applied effects.
|
|
15
|
+
function ppb_serializeComponentsForFullSequenceInfo(clip) {
|
|
16
|
+
var components = [];
|
|
17
|
+
try {
|
|
18
|
+
for (var i = 0; i < clip.components.numItems; i++) {
|
|
19
|
+
var comp = clip.components[i];
|
|
20
|
+
var entry = { displayName: null, matchName: null, enabled: null, numProperties: null };
|
|
21
|
+
try { entry.displayName = comp.displayName; } catch (e) { entry.displayName = null; }
|
|
22
|
+
try { entry.matchName = comp.matchName; } catch (e) { entry.matchName = null; }
|
|
23
|
+
try { entry.enabled = comp.enabled; } catch (e) { entry.enabled = null; }
|
|
24
|
+
try { entry.numProperties = comp.properties.numItems; } catch (e) { entry.numProperties = null; }
|
|
25
|
+
components.push(entry);
|
|
26
|
+
}
|
|
27
|
+
} catch (e) {
|
|
28
|
+
// leave components as whatever was collected so far
|
|
29
|
+
}
|
|
30
|
+
return components;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function ppb_serializeClipForFullSequenceInfo(clip, trackIndex, clipIndex) {
|
|
34
|
+
var out = serializeTrackItem(clip, trackIndex, clipIndex);
|
|
35
|
+
out.components = ppb_serializeComponentsForFullSequenceInfo(clip);
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function ppb_serializeTrackForFullSequenceInfo(track, trackIndex) {
|
|
40
|
+
var out = {
|
|
41
|
+
index: trackIndex,
|
|
42
|
+
name: null,
|
|
43
|
+
isMuted: null,
|
|
44
|
+
isLocked: null,
|
|
45
|
+
clipCount: null,
|
|
46
|
+
clips: []
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
try { out.name = track.name; } catch (e) { out.name = null; }
|
|
50
|
+
try { out.isMuted = track.isMuted(); } catch (e) { out.isMuted = null; }
|
|
51
|
+
try { out.isLocked = track.isLocked(); } catch (e) { out.isLocked = null; }
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
out.clipCount = track.clips.numItems;
|
|
55
|
+
for (var c = 0; c < track.clips.numItems; c++) {
|
|
56
|
+
out.clips.push(ppb_serializeClipForFullSequenceInfo(track.clips[c], trackIndex, c));
|
|
57
|
+
}
|
|
58
|
+
} catch (e) {
|
|
59
|
+
// leave clipCount/clips as-is
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Markers have no reliable indexing (PREMIERE_API_NOTES.md) — iterate via
|
|
66
|
+
// getFirstMarker()/getNextMarker(m), capped to guard against a pathological
|
|
67
|
+
// linked-list (e.g. a cycle from a corrupt project).
|
|
68
|
+
function ppb_serializeSequenceMarkers(seq) {
|
|
69
|
+
var markers = [];
|
|
70
|
+
try {
|
|
71
|
+
var m = seq.markers.getFirstMarker();
|
|
72
|
+
var iterations = 0;
|
|
73
|
+
while (m !== null && typeof m !== "undefined" && iterations < 10000) {
|
|
74
|
+
var entry = { name: null, comments: null, type: null, startSeconds: null, endSeconds: null, guid: null };
|
|
75
|
+
try { entry.name = m.name; } catch (e) { entry.name = null; }
|
|
76
|
+
try { entry.comments = m.comments; } catch (e) { entry.comments = null; }
|
|
77
|
+
try { entry.type = m.type; } catch (e) { entry.type = null; }
|
|
78
|
+
try { entry.startSeconds = timeValueToSeconds(m.start); } catch (e) { entry.startSeconds = null; }
|
|
79
|
+
try { entry.endSeconds = timeValueToSeconds(m.end); } catch (e) { entry.endSeconds = null; }
|
|
80
|
+
try { entry.guid = m.guid; } catch (e) { entry.guid = null; }
|
|
81
|
+
markers.push(entry);
|
|
82
|
+
|
|
83
|
+
m = seq.markers.getNextMarker(m);
|
|
84
|
+
iterations++;
|
|
85
|
+
}
|
|
86
|
+
} catch (e) {
|
|
87
|
+
// leave markers as whatever was collected so far
|
|
88
|
+
}
|
|
89
|
+
return markers;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function ppb_getFullSequenceInfo(argsJson) {
|
|
93
|
+
try {
|
|
94
|
+
var args;
|
|
95
|
+
try {
|
|
96
|
+
args = JSON.parse(argsJson);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!app.project) {
|
|
102
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
var seq = null;
|
|
106
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
107
|
+
seq = findSequenceByName(args.sequenceName);
|
|
108
|
+
if (!seq) {
|
|
109
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
seq = app.project.activeSequence;
|
|
113
|
+
if (!seq) {
|
|
114
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
var frameRate = null;
|
|
119
|
+
try {
|
|
120
|
+
frameRate = getSequenceFps(seq);
|
|
121
|
+
} catch (e) {
|
|
122
|
+
frameRate = null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
var durationSeconds = null;
|
|
126
|
+
try {
|
|
127
|
+
durationSeconds = (Number(seq.end) - Number(seq.zeroPoint)) / TICKS_PER_SECOND;
|
|
128
|
+
} catch (e) {
|
|
129
|
+
durationSeconds = null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
var width = null;
|
|
133
|
+
var height = null;
|
|
134
|
+
try {
|
|
135
|
+
var settings = seq.getSettings();
|
|
136
|
+
width = settings.videoFrameWidth;
|
|
137
|
+
height = settings.videoFrameHeight;
|
|
138
|
+
} catch (e) {
|
|
139
|
+
// best-effort only
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
var videoTracks = [];
|
|
143
|
+
try {
|
|
144
|
+
for (var v = 0; v < seq.videoTracks.numTracks; v++) {
|
|
145
|
+
videoTracks.push(ppb_serializeTrackForFullSequenceInfo(seq.videoTracks[v], v));
|
|
146
|
+
}
|
|
147
|
+
} catch (e) {
|
|
148
|
+
// leave videoTracks as whatever was collected so far
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
var audioTracks = [];
|
|
152
|
+
try {
|
|
153
|
+
for (var a = 0; a < seq.audioTracks.numTracks; a++) {
|
|
154
|
+
audioTracks.push(ppb_serializeTrackForFullSequenceInfo(seq.audioTracks[a], a));
|
|
155
|
+
}
|
|
156
|
+
} catch (e) {
|
|
157
|
+
// leave audioTracks as whatever was collected so far
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
var markerCount = null;
|
|
161
|
+
try {
|
|
162
|
+
markerCount = seq.markers.numMarkers;
|
|
163
|
+
} catch (e) {
|
|
164
|
+
markerCount = null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
var result = {
|
|
168
|
+
name: seq.name,
|
|
169
|
+
sequenceID: seq.sequenceID,
|
|
170
|
+
frameRate: frameRate,
|
|
171
|
+
durationSeconds: durationSeconds,
|
|
172
|
+
width: width,
|
|
173
|
+
height: height,
|
|
174
|
+
videoTracks: videoTracks,
|
|
175
|
+
audioTracks: audioTracks,
|
|
176
|
+
markers: ppb_serializeSequenceMarkers(seq),
|
|
177
|
+
markerCount: markerCount
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
return JSON.stringify({ ok: true, result: result });
|
|
181
|
+
} catch (e) {
|
|
182
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Command: get-graphics-white-luminance → ppb_getGraphicsWhiteLuminance
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context.
|
|
4
|
+
//
|
|
5
|
+
// READ-only. Ported from leancoderkavy/premiere-pro-mcp's project.ts
|
|
6
|
+
// get_graphics_white_luminance: app.project.getGraphicsWhiteLuminance() —
|
|
7
|
+
// the HDR graphics-white-luminance setting (in nits), not documented
|
|
8
|
+
// elsewhere in PREMIERE_API_NOTES.md. Pairs with
|
|
9
|
+
// set-graphics-white-luminance.jsx.
|
|
10
|
+
|
|
11
|
+
function ppb_getGraphicsWhiteLuminance(argsJson) {
|
|
12
|
+
try {
|
|
13
|
+
if (!app.project) {
|
|
14
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
15
|
+
}
|
|
16
|
+
if (typeof app.project.getGraphicsWhiteLuminance !== "function") {
|
|
17
|
+
return JSON.stringify({ ok: false, error: "getGraphicsWhiteLuminance is not available on this Premiere build" });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
var value = null;
|
|
21
|
+
try {
|
|
22
|
+
value = app.project.getGraphicsWhiteLuminance();
|
|
23
|
+
} catch (e) {
|
|
24
|
+
return JSON.stringify({ ok: false, error: "getGraphicsWhiteLuminance() failed: " + e.toString() });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return JSON.stringify({ ok: true, result: { graphicsWhiteLuminance: value } });
|
|
28
|
+
} catch (e) {
|
|
29
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Command: get-insertion-bin → ppb_getInsertionBin
|
|
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
|
+
// ensureQEEnabled, findSequenceByName, ...) are already defined there.
|
|
5
|
+
//
|
|
6
|
+
// Thin read of app.project.getInsertionBin() — the bin currently focused
|
|
7
|
+
// in the Project panel, i.e. where a new import would land.
|
|
8
|
+
|
|
9
|
+
function ppb_getInsertionBin(argsJson) {
|
|
10
|
+
try {
|
|
11
|
+
if (!app.project) {
|
|
12
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
var bin = null;
|
|
16
|
+
try {
|
|
17
|
+
bin = app.project.getInsertionBin();
|
|
18
|
+
} catch (e) {
|
|
19
|
+
return JSON.stringify({ ok: false, error: "getInsertionBin failed: " + e.toString() });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!bin) {
|
|
23
|
+
return JSON.stringify({ ok: false, error: "no insertion bin found" });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var result = { name: null, nodeId: null, treePath: null };
|
|
27
|
+
try { result.name = bin.name; } catch (e) { result.name = null; }
|
|
28
|
+
try { result.nodeId = bin.nodeId; } catch (e) { result.nodeId = null; }
|
|
29
|
+
try { result.treePath = bin.treePath; } catch (e) { result.treePath = null; }
|
|
30
|
+
|
|
31
|
+
return JSON.stringify({ ok: true, result: result });
|
|
32
|
+
} catch (e) {
|
|
33
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Command: get-item-metadata → ppb_getItemMetadata
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context.
|
|
4
|
+
//
|
|
5
|
+
// Project-item addressing: at least one of nodeId/name is required.
|
|
6
|
+
// nodeId is matched exactly; name is matched exactly against item.name
|
|
7
|
+
// (first match wins, depth-first). This helper is duplicated in each of
|
|
8
|
+
// the get-item-metadata / get-color-label / get-footage-interpretation /
|
|
9
|
+
// get-xmp-metadata / get-color-space command files (prefixed
|
|
10
|
+
// ppbFindItem<Command>_) since each command file loads independently and
|
|
11
|
+
// cannot rely on helpers defined only in another command file.
|
|
12
|
+
|
|
13
|
+
function ppbFindItemGetItemMetadata_walk(item, args, depth) {
|
|
14
|
+
if (depth > 32) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
var isBin = false;
|
|
19
|
+
try {
|
|
20
|
+
isBin = typeof ProjectItemType !== "undefined" && item.type === ProjectItemType.BIN;
|
|
21
|
+
} catch (e) {
|
|
22
|
+
isBin = false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var matched = false;
|
|
26
|
+
if (args.nodeId !== null) {
|
|
27
|
+
try { matched = item.nodeId === args.nodeId; } catch (e) { matched = false; }
|
|
28
|
+
} else if (args.name !== null) {
|
|
29
|
+
try { matched = item.name === args.name; } catch (e) { matched = false; }
|
|
30
|
+
}
|
|
31
|
+
if (matched) {
|
|
32
|
+
return item;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (isBin && item.children) {
|
|
36
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
37
|
+
var found = ppbFindItemGetItemMetadata_walk(item.children[i], args, depth + 1);
|
|
38
|
+
if (found) {
|
|
39
|
+
return found;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function ppbFindItemGetItemMetadata_resolve(args) {
|
|
47
|
+
var root = app.project.rootItem;
|
|
48
|
+
for (var i = 0; i < root.children.numItems; i++) {
|
|
49
|
+
var found = ppbFindItemGetItemMetadata_walk(root.children[i], args, 1);
|
|
50
|
+
if (found) {
|
|
51
|
+
return found;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function ppb_getItemMetadata(argsJson) {
|
|
58
|
+
try {
|
|
59
|
+
var args;
|
|
60
|
+
try {
|
|
61
|
+
args = JSON.parse(argsJson);
|
|
62
|
+
} catch (e) {
|
|
63
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
var hasNodeId = typeof args.nodeId === "string" && args.nodeId.length > 0;
|
|
67
|
+
var hasName = typeof args.name === "string" && args.name.length > 0;
|
|
68
|
+
if (!hasNodeId && !hasName) {
|
|
69
|
+
return JSON.stringify({ ok: false, error: "either nodeId or name is required" });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!app.project) {
|
|
73
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var item = ppbFindItemGetItemMetadata_resolve({
|
|
77
|
+
nodeId: hasNodeId ? args.nodeId : null,
|
|
78
|
+
name: hasNodeId ? null : args.name
|
|
79
|
+
});
|
|
80
|
+
if (!item) {
|
|
81
|
+
return JSON.stringify({ ok: false, error: "no project item found matching the given nodeId/name" });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
var result = { name: null, nodeId: null, mediaPath: null, projectMetadata: null };
|
|
85
|
+
try { result.name = item.name; } catch (e) { result.name = null; }
|
|
86
|
+
try { result.nodeId = item.nodeId; } catch (e) { result.nodeId = null; }
|
|
87
|
+
try { result.mediaPath = item.getMediaPath(); } catch (e) { result.mediaPath = null; }
|
|
88
|
+
try { result.projectMetadata = item.getProjectMetadata(); } catch (e) { result.projectMetadata = null; }
|
|
89
|
+
|
|
90
|
+
return JSON.stringify({ ok: true, result: result });
|
|
91
|
+
} catch (e) {
|
|
92
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// Command: get-keyframes → ppb_getKeyframes
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// findClipComponent, findComponentProperty, timeValueToSeconds,
|
|
5
|
+
// keyTimeToSeconds, getSequenceFps, ...) are already defined there.
|
|
6
|
+
//
|
|
7
|
+
// Standard-DOM only — no QE needed. Ported from leancoderkavy's
|
|
8
|
+
// premiere-pro-mcp `get_keyframes` tool (keyframes.ts), addressed here by
|
|
9
|
+
// trackType/trackIndex/clipIndex + componentName/propertyName. READ-only.
|
|
10
|
+
//
|
|
11
|
+
// Per PREMIERE_API_NOTES.md, prop.getKeys() key times are DISPUTED across
|
|
12
|
+
// Premiere builds/repos (Time objects vs. raw ticks vs. raw seconds) —
|
|
13
|
+
// keyTimeToSeconds() normalizes defensively (see its own comment for the
|
|
14
|
+
// heuristic). Each key is reported as BOTH sequenceSeconds (raw Premiere
|
|
15
|
+
// time) AND clipRelativeSeconds (offset by the clip's own start, matching
|
|
16
|
+
// how add-audio-keyframes/add-keyframe accept clip-relative input).
|
|
17
|
+
function ppb_getKeyframes(argsJson) {
|
|
18
|
+
try {
|
|
19
|
+
var args;
|
|
20
|
+
try {
|
|
21
|
+
args = JSON.parse(argsJson);
|
|
22
|
+
} catch (e) {
|
|
23
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (args.trackType !== "video" && args.trackType !== "audio") {
|
|
27
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
|
|
28
|
+
}
|
|
29
|
+
if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
|
|
30
|
+
return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
|
|
31
|
+
}
|
|
32
|
+
if (typeof args.clipIndex !== "number" || args.clipIndex < 0 || Math.floor(args.clipIndex) !== args.clipIndex) {
|
|
33
|
+
return JSON.stringify({ ok: false, error: "clipIndex must be a non-negative integer" });
|
|
34
|
+
}
|
|
35
|
+
if (typeof args.componentName !== "string" || !args.componentName) {
|
|
36
|
+
return JSON.stringify({ ok: false, error: "componentName is required" });
|
|
37
|
+
}
|
|
38
|
+
if (typeof args.propertyName !== "string" || !args.propertyName) {
|
|
39
|
+
return JSON.stringify({ ok: false, error: "propertyName is required" });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!app.project) {
|
|
43
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
var seq = null;
|
|
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 trackCollection = args.trackType === "video" ? seq.videoTracks : seq.audioTracks;
|
|
60
|
+
var numTracks = trackCollection.numTracks;
|
|
61
|
+
if (args.trackIndex >= numTracks) {
|
|
62
|
+
return JSON.stringify({
|
|
63
|
+
ok: false,
|
|
64
|
+
error: "trackIndex " + args.trackIndex + " is out of range — sequence has " + numTracks + " " + args.trackType + " track(s)"
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
var track = trackCollection[args.trackIndex];
|
|
69
|
+
var numClips = track.clips.numItems;
|
|
70
|
+
if (args.clipIndex >= numClips) {
|
|
71
|
+
return JSON.stringify({
|
|
72
|
+
ok: false,
|
|
73
|
+
error: "clipIndex " + args.clipIndex + " is out of range — track " + args.trackIndex + " has " + numClips + " clip(s)"
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
var clip = track.clips[args.clipIndex];
|
|
78
|
+
var clipName = null;
|
|
79
|
+
try { clipName = clip.name; } catch (e) { clipName = null; }
|
|
80
|
+
|
|
81
|
+
var clipStartSeconds = 0;
|
|
82
|
+
try { clipStartSeconds = timeValueToSeconds(clip.start) || 0; } catch (e) { clipStartSeconds = 0; }
|
|
83
|
+
|
|
84
|
+
var comp = findClipComponent(clip, [args.componentName], [args.componentName]);
|
|
85
|
+
if (!comp) {
|
|
86
|
+
return JSON.stringify({
|
|
87
|
+
ok: false,
|
|
88
|
+
error: "component \"" + args.componentName + "\" not found on clip (matched against matchName and displayName)"
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
var compDisplayName = null;
|
|
92
|
+
try { compDisplayName = comp.displayName; } catch (e) { compDisplayName = null; }
|
|
93
|
+
|
|
94
|
+
var prop = findComponentProperty(comp, [args.propertyName]);
|
|
95
|
+
if (!prop) {
|
|
96
|
+
return JSON.stringify({
|
|
97
|
+
ok: false,
|
|
98
|
+
error: "property \"" + args.propertyName + "\" not found on component \"" + compDisplayName + "\""
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
var isTimeVarying = false;
|
|
103
|
+
try { isTimeVarying = prop.isTimeVarying(); } catch (e) { isTimeVarying = false; }
|
|
104
|
+
|
|
105
|
+
if (!isTimeVarying) {
|
|
106
|
+
return JSON.stringify({
|
|
107
|
+
ok: true,
|
|
108
|
+
result: {
|
|
109
|
+
sequenceName: seq.name,
|
|
110
|
+
trackType: args.trackType,
|
|
111
|
+
trackIndex: args.trackIndex,
|
|
112
|
+
clipIndex: args.clipIndex,
|
|
113
|
+
clipName: clipName,
|
|
114
|
+
componentName: compDisplayName,
|
|
115
|
+
propertyName: args.propertyName,
|
|
116
|
+
isTimeVarying: false,
|
|
117
|
+
keyCount: 0,
|
|
118
|
+
keys: []
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
var rawKeys = null;
|
|
124
|
+
try { rawKeys = prop.getKeys(); } catch (e) { rawKeys = null; }
|
|
125
|
+
|
|
126
|
+
var keys = [];
|
|
127
|
+
if (rawKeys) {
|
|
128
|
+
for (var i = 0; i < rawKeys.length; i++) {
|
|
129
|
+
var rawKey = rawKeys[i];
|
|
130
|
+
var entry = { sequenceSeconds: null, clipRelativeSeconds: null, value: null };
|
|
131
|
+
try { entry.sequenceSeconds = keyTimeToSeconds(rawKey); } catch (e1) { entry.sequenceSeconds = null; }
|
|
132
|
+
if (entry.sequenceSeconds !== null) {
|
|
133
|
+
entry.clipRelativeSeconds = entry.sequenceSeconds - clipStartSeconds;
|
|
134
|
+
}
|
|
135
|
+
try { entry.value = prop.getValueAtKey(rawKey); } catch (e2) { entry.value = null; }
|
|
136
|
+
keys.push(entry);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return JSON.stringify({
|
|
141
|
+
ok: true,
|
|
142
|
+
result: {
|
|
143
|
+
sequenceName: seq.name,
|
|
144
|
+
trackType: args.trackType,
|
|
145
|
+
trackIndex: args.trackIndex,
|
|
146
|
+
clipIndex: args.clipIndex,
|
|
147
|
+
clipName: clipName,
|
|
148
|
+
componentName: compDisplayName,
|
|
149
|
+
propertyName: args.propertyName,
|
|
150
|
+
isTimeVarying: true,
|
|
151
|
+
keyCount: keys.length,
|
|
152
|
+
keys: keys
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
} catch (e) {
|
|
156
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
157
|
+
}
|
|
158
|
+
}
|