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.
Files changed (247) hide show
  1. premiere_cli/__init__.py +11 -0
  2. premiere_cli/cli.py +3664 -0
  3. premiere_cli/log.py +66 -0
  4. premiere_cli/panel/.debug +8 -0
  5. premiere_cli/panel/CSXS/manifest.xml +52 -0
  6. premiere_cli/panel/css/style.css +53 -0
  7. premiere_cli/panel/host/commands/add-adjustment-layer.jsx +190 -0
  8. premiere_cli/panel/host/commands/add-audio-keyframes.jsx +176 -0
  9. premiere_cli/panel/host/commands/add-custom-metadata-field.jsx +63 -0
  10. premiere_cli/panel/host/commands/add-keyframe.jsx +181 -0
  11. premiere_cli/panel/host/commands/add-marker-to-project-item.jsx +194 -0
  12. premiere_cli/panel/host/commands/add-marker.jsx +129 -0
  13. premiere_cli/panel/host/commands/add-text-overlay.jsx +101 -0
  14. premiere_cli/panel/host/commands/add-to-render-queue.jsx +120 -0
  15. premiere_cli/panel/host/commands/add-to-timeline.jsx +300 -0
  16. premiere_cli/panel/host/commands/add-track.jsx +188 -0
  17. premiere_cli/panel/host/commands/add-transition.jsx +134 -0
  18. premiere_cli/panel/host/commands/adjust-audio-levels.jsx +132 -0
  19. premiere_cli/panel/host/commands/apply-audio-effect.jsx +118 -0
  20. premiere_cli/panel/host/commands/apply-effect.jsx +122 -0
  21. premiere_cli/panel/host/commands/apply-lut.jsx +107 -0
  22. premiere_cli/panel/host/commands/attach-custom-property.jsx +66 -0
  23. premiere_cli/panel/host/commands/auto-reframe-sequence.jsx +124 -0
  24. premiere_cli/panel/host/commands/batch-add-transitions.jsx +158 -0
  25. premiere_cli/panel/host/commands/batch-apply-effect.jsx +182 -0
  26. premiere_cli/panel/host/commands/batch-rename-clips.jsx +170 -0
  27. premiere_cli/panel/host/commands/batch-set-clips-enabled.jsx +145 -0
  28. premiere_cli/panel/host/commands/clear-item-in-out.jsx +117 -0
  29. premiere_cli/panel/host/commands/clear-sequence-in-out.jsx +100 -0
  30. premiere_cli/panel/host/commands/close-all-source-clips.jsx +32 -0
  31. premiere_cli/panel/host/commands/close-sequence.jsx +80 -0
  32. premiere_cli/panel/host/commands/close-source-monitor.jsx +32 -0
  33. premiere_cli/panel/host/commands/color-correct.jsx +164 -0
  34. premiere_cli/panel/host/commands/copy-effect-values.jsx +183 -0
  35. premiere_cli/panel/host/commands/copy-effects-between-clips.jsx +234 -0
  36. premiere_cli/panel/host/commands/create-bars-and-tone.jsx +152 -0
  37. premiere_cli/panel/host/commands/create-bin.jsx +76 -0
  38. premiere_cli/panel/host/commands/create-caption-track.jsx +159 -0
  39. premiere_cli/panel/host/commands/create-sequence-from-clips.jsx +170 -0
  40. premiere_cli/panel/host/commands/create-sequence-from-preset.jsx +90 -0
  41. premiere_cli/panel/host/commands/create-sequence.jsx +166 -0
  42. premiere_cli/panel/host/commands/create-smart-bin.jsx +80 -0
  43. premiere_cli/panel/host/commands/create-subclip.jsx +248 -0
  44. premiere_cli/panel/host/commands/create-subsequence.jsx +136 -0
  45. premiere_cli/panel/host/commands/debug-qe-inspect.jsx +248 -0
  46. premiere_cli/panel/host/commands/debug-qe-try-mutate.jsx +305 -0
  47. premiere_cli/panel/host/commands/delete-marker.jsx +178 -0
  48. premiere_cli/panel/host/commands/deselect-all-clips.jsx +98 -0
  49. premiere_cli/panel/host/commands/detach-proxy.jsx +116 -0
  50. premiere_cli/panel/host/commands/duplicate-clip.jsx +140 -0
  51. premiere_cli/panel/host/commands/duplicate-sequence.jsx +150 -0
  52. premiere_cli/panel/host/commands/encode-file.jsx +86 -0
  53. premiere_cli/panel/host/commands/encode-project-item.jsx +145 -0
  54. premiere_cli/panel/host/commands/export-aaf.jsx +77 -0
  55. premiere_cli/panel/host/commands/export-fcp-xml.jsx +65 -0
  56. premiere_cli/panel/host/commands/export-frame.jsx +381 -0
  57. premiere_cli/panel/host/commands/export-omf.jsx +95 -0
  58. premiere_cli/panel/host/commands/export-sequence-as-project.jsx +65 -0
  59. premiere_cli/panel/host/commands/export-sequence.jsx +100 -0
  60. premiere_cli/panel/host/commands/extract-audio-track.jsx +181 -0
  61. premiere_cli/panel/host/commands/extract-selection.jsx +113 -0
  62. premiere_cli/panel/host/commands/find-items-by-media-path.jsx +112 -0
  63. premiere_cli/panel/host/commands/freeze-frame.jsx +215 -0
  64. premiere_cli/panel/host/commands/get-active-sequence.jsx +103 -0
  65. premiere_cli/panel/host/commands/get-all-project-paths.jsx +72 -0
  66. premiere_cli/panel/host/commands/get-bin-contents.jsx +176 -0
  67. premiere_cli/panel/host/commands/get-clip-adjustment-layer.jsx +83 -0
  68. premiere_cli/panel/host/commands/get-clip-at-playhead.jsx +99 -0
  69. premiere_cli/panel/host/commands/get-clip-at-position.jsx +120 -0
  70. premiere_cli/panel/host/commands/get-clip-links.jsx +135 -0
  71. premiere_cli/panel/host/commands/get-clip-markers.jsx +144 -0
  72. premiere_cli/panel/host/commands/get-clip-speed.jsx +69 -0
  73. premiere_cli/panel/host/commands/get-color-label.jsx +89 -0
  74. premiere_cli/panel/host/commands/get-color-space.jsx +99 -0
  75. premiere_cli/panel/host/commands/get-duplicate-media.jsx +78 -0
  76. premiere_cli/panel/host/commands/get-effect-properties.jsx +129 -0
  77. premiere_cli/panel/host/commands/get-encoder-presets.jsx +131 -0
  78. premiere_cli/panel/host/commands/get-export-file-extension.jsx +56 -0
  79. premiere_cli/panel/host/commands/get-footage-interpretation.jsx +113 -0
  80. premiere_cli/panel/host/commands/get-full-clip-info.jsx +162 -0
  81. premiere_cli/panel/host/commands/get-full-project-overview.jsx +193 -0
  82. premiere_cli/panel/host/commands/get-full-sequence-info.jsx +184 -0
  83. premiere_cli/panel/host/commands/get-graphics-white-luminance.jsx +31 -0
  84. premiere_cli/panel/host/commands/get-insertion-bin.jsx +35 -0
  85. premiere_cli/panel/host/commands/get-item-metadata.jsx +94 -0
  86. premiere_cli/panel/host/commands/get-keyframes.jsx +158 -0
  87. premiere_cli/panel/host/commands/get-mogrt-component.jsx +111 -0
  88. premiere_cli/panel/host/commands/get-next-edit-point.jsx +131 -0
  89. premiere_cli/panel/host/commands/get-offline-media.jsx +67 -0
  90. premiere_cli/panel/host/commands/get-open-projects.jsx +50 -0
  91. premiere_cli/panel/host/commands/get-premiere-state.jsx +164 -0
  92. premiere_cli/panel/host/commands/get-project-info.jsx +63 -0
  93. premiere_cli/panel/host/commands/get-project-item-info.jsx +247 -0
  94. premiere_cli/panel/host/commands/get-project-panel-metadata.jsx +30 -0
  95. premiere_cli/panel/host/commands/get-qe-clip-info.jsx +198 -0
  96. premiere_cli/panel/host/commands/get-render-queue-status.jsx +35 -0
  97. premiere_cli/panel/host/commands/get-sequence-count.jsx +24 -0
  98. premiere_cli/panel/host/commands/get-sequence-in-out.jsx +76 -0
  99. premiere_cli/panel/host/commands/get-sequence-markers-by-type.jsx +89 -0
  100. premiere_cli/panel/host/commands/get-source-monitor-info.jsx +34 -0
  101. premiere_cli/panel/host/commands/get-source-monitor-position.jsx +30 -0
  102. premiere_cli/panel/host/commands/get-target-tracks.jsx +76 -0
  103. premiere_cli/panel/host/commands/get-timeline-gaps.jsx +124 -0
  104. premiere_cli/panel/host/commands/get-timeline-summary.jsx +154 -0
  105. premiere_cli/panel/host/commands/get-total-clip-count.jsx +67 -0
  106. premiere_cli/panel/host/commands/get-track-info.jsx +117 -0
  107. premiere_cli/panel/host/commands/get-unused-media.jsx +99 -0
  108. premiere_cli/panel/host/commands/get-used-media-report.jsx +125 -0
  109. premiere_cli/panel/host/commands/get-value-at-time.jsx +135 -0
  110. premiere_cli/panel/host/commands/get-version-info.jsx +33 -0
  111. premiere_cli/panel/host/commands/get-work-area.jsx +52 -0
  112. premiere_cli/panel/host/commands/get-workspaces.jsx +29 -0
  113. premiere_cli/panel/host/commands/get-xmp-metadata.jsx +107 -0
  114. premiere_cli/panel/host/commands/import-ae-comps.jsx +129 -0
  115. premiere_cli/panel/host/commands/import-fcp-xml.jsx +103 -0
  116. premiere_cli/panel/host/commands/import-folder.jsx +193 -0
  117. premiere_cli/panel/host/commands/import-image-sequence.jsx +171 -0
  118. premiere_cli/panel/host/commands/import-media.jsx +217 -0
  119. premiere_cli/panel/host/commands/import-mogrt-from-library.jsx +105 -0
  120. premiere_cli/panel/host/commands/import-mogrt.jsx +111 -0
  121. premiere_cli/panel/host/commands/import-sequences-from-project.jsx +80 -0
  122. premiere_cli/panel/host/commands/insert-from-source.jsx +162 -0
  123. premiere_cli/panel/host/commands/inspect-dom-object.jsx +162 -0
  124. premiere_cli/panel/host/commands/invert-selection.jsx +114 -0
  125. premiere_cli/panel/host/commands/is-work-area-enabled.jsx +88 -0
  126. premiere_cli/panel/host/commands/lift-selection.jsx +106 -0
  127. premiere_cli/panel/host/commands/link-selection.jsx +111 -0
  128. premiere_cli/panel/host/commands/list-available-audio-effects.jsx +33 -0
  129. premiere_cli/panel/host/commands/list-available-audio-transitions.jsx +35 -0
  130. premiere_cli/panel/host/commands/list-available-effects.jsx +33 -0
  131. premiere_cli/panel/host/commands/list-available-transitions.jsx +74 -0
  132. premiere_cli/panel/host/commands/list-markers.jsx +69 -0
  133. premiere_cli/panel/host/commands/list-project-items.jsx +105 -0
  134. premiere_cli/panel/host/commands/lock-track.jsx +114 -0
  135. premiere_cli/panel/host/commands/manage-proxies.jsx +176 -0
  136. premiere_cli/panel/host/commands/match-frame.jsx +141 -0
  137. premiere_cli/panel/host/commands/move-clip-to-track.jsx +220 -0
  138. premiere_cli/panel/host/commands/move-clip.jsx +97 -0
  139. premiere_cli/panel/host/commands/move-items-to-bin.jsx +194 -0
  140. premiere_cli/panel/host/commands/move-playhead-to-edit.jsx +174 -0
  141. premiere_cli/panel/host/commands/move-playhead.jsx +137 -0
  142. premiere_cli/panel/host/commands/nest-clips.jsx +179 -0
  143. premiere_cli/panel/host/commands/open-in-source.jsx +117 -0
  144. premiere_cli/panel/host/commands/open-project.jsx +61 -0
  145. premiere_cli/panel/host/commands/overwrite-clip-at.jsx +350 -0
  146. premiere_cli/panel/host/commands/overwrite-from-source.jsx +150 -0
  147. premiere_cli/panel/host/commands/play-source-monitor.jsx +36 -0
  148. premiere_cli/panel/host/commands/play-timeline.jsx +24 -0
  149. premiere_cli/panel/host/commands/razor-all-tracks.jsx +171 -0
  150. premiere_cli/panel/host/commands/redo.jsx +69 -0
  151. premiere_cli/panel/host/commands/refresh-media.jsx +101 -0
  152. premiere_cli/panel/host/commands/relink-media.jsx +132 -0
  153. premiere_cli/panel/host/commands/remove-all-effects.jsx +114 -0
  154. premiere_cli/panel/host/commands/remove-effect-by-name.jsx +143 -0
  155. premiere_cli/panel/host/commands/remove-effect.jsx +122 -0
  156. premiere_cli/panel/host/commands/remove-from-timeline.jsx +93 -0
  157. premiere_cli/panel/host/commands/remove-keyframe-range.jsx +173 -0
  158. premiere_cli/panel/host/commands/remove-keyframe.jsx +192 -0
  159. premiere_cli/panel/host/commands/remove-selected-clips.jsx +126 -0
  160. premiere_cli/panel/host/commands/remove-track-intervals.jsx +254 -0
  161. premiere_cli/panel/host/commands/remove-transition.jsx +164 -0
  162. premiere_cli/panel/host/commands/rename-bin.jsx +88 -0
  163. premiere_cli/panel/host/commands/rename-clip.jsx +127 -0
  164. premiere_cli/panel/host/commands/rename-project-item.jsx +111 -0
  165. premiere_cli/panel/host/commands/rename-track.jsx +84 -0
  166. premiere_cli/panel/host/commands/replace-clip-media.jsx +140 -0
  167. premiere_cli/panel/host/commands/replace-clip.jsx +188 -0
  168. premiere_cli/panel/host/commands/reverse-clip.jsx +187 -0
  169. premiere_cli/panel/host/commands/ripple-delete-clip.jsx +156 -0
  170. premiere_cli/panel/host/commands/roll-edit.jsx +162 -0
  171. premiere_cli/panel/host/commands/save-project-as.jsx +55 -0
  172. premiere_cli/panel/host/commands/save-project.jsx +57 -0
  173. premiere_cli/panel/host/commands/scene-edit-detection.jsx +128 -0
  174. premiere_cli/panel/host/commands/search-project-items.jsx +180 -0
  175. premiere_cli/panel/host/commands/select-all-clips.jsx +107 -0
  176. premiere_cli/panel/host/commands/select-clips-by-color.jsx +142 -0
  177. premiere_cli/panel/host/commands/select-clips-by-name.jsx +133 -0
  178. premiere_cli/panel/host/commands/select-clips-in-range.jsx +133 -0
  179. premiere_cli/panel/host/commands/select-disabled-clips.jsx +127 -0
  180. premiere_cli/panel/host/commands/select-project-item.jsx +115 -0
  181. premiere_cli/panel/host/commands/set-active-project.jsx +184 -0
  182. premiere_cli/panel/host/commands/set-active-sequence.jsx +87 -0
  183. premiere_cli/panel/host/commands/set-all-tracks-targeted.jsx +112 -0
  184. premiere_cli/panel/host/commands/set-anti-alias-quality.jsx +125 -0
  185. premiere_cli/panel/host/commands/set-blend-mode.jsx +111 -0
  186. premiere_cli/panel/host/commands/set-clip-anchor-point.jsx +102 -0
  187. premiere_cli/panel/host/commands/set-clip-enabled.jsx +127 -0
  188. premiere_cli/panel/host/commands/set-clip-opacity.jsx +102 -0
  189. premiere_cli/panel/host/commands/set-clip-pan.jsx +107 -0
  190. premiere_cli/panel/host/commands/set-clip-position.jsx +103 -0
  191. premiere_cli/panel/host/commands/set-clip-properties.jsx +221 -0
  192. premiere_cli/panel/host/commands/set-clip-rotation.jsx +102 -0
  193. premiere_cli/panel/host/commands/set-clip-scale.jsx +102 -0
  194. premiere_cli/panel/host/commands/set-clip-selection.jsx +144 -0
  195. premiere_cli/panel/host/commands/set-clip-speed.jsx +160 -0
  196. premiere_cli/panel/host/commands/set-clip-volume.jsx +128 -0
  197. premiere_cli/panel/host/commands/set-color-label.jsx +123 -0
  198. premiere_cli/panel/host/commands/set-color-value.jsx +155 -0
  199. premiere_cli/panel/host/commands/set-effect-property.jsx +124 -0
  200. premiere_cli/panel/host/commands/set-footage-interpretation.jsx +173 -0
  201. premiere_cli/panel/host/commands/set-frame-blend.jsx +145 -0
  202. premiere_cli/panel/host/commands/set-graphics-white-luminance.jsx +73 -0
  203. premiere_cli/panel/host/commands/set-item-in-out.jsx +180 -0
  204. premiere_cli/panel/host/commands/set-item-metadata.jsx +134 -0
  205. premiere_cli/panel/host/commands/set-item-offline.jsx +109 -0
  206. premiere_cli/panel/host/commands/set-item-start-time.jsx +139 -0
  207. premiere_cli/panel/host/commands/set-keyframe-interpolation.jsx +186 -0
  208. premiere_cli/panel/host/commands/set-override-frame-rate.jsx +123 -0
  209. premiere_cli/panel/host/commands/set-override-pixel-aspect-ratio.jsx +129 -0
  210. premiere_cli/panel/host/commands/set-poster-frame.jsx +192 -0
  211. premiere_cli/panel/host/commands/set-project-panel-metadata.jsx +69 -0
  212. premiere_cli/panel/host/commands/set-scale-to-frame-size.jsx +101 -0
  213. premiere_cli/panel/host/commands/set-scale-width-height.jsx +140 -0
  214. premiere_cli/panel/host/commands/set-sequence-in-out.jsx +65 -0
  215. premiere_cli/panel/host/commands/set-sequence-settings.jsx +184 -0
  216. premiere_cli/panel/host/commands/set-source-in-out.jsx +98 -0
  217. premiere_cli/panel/host/commands/set-target-track.jsx +91 -0
  218. premiere_cli/panel/host/commands/set-time-interpolation.jsx +141 -0
  219. premiere_cli/panel/host/commands/set-track-mute.jsx +91 -0
  220. premiere_cli/panel/host/commands/set-track-visibility.jsx +94 -0
  221. premiere_cli/panel/host/commands/set-transcode-on-ingest.jsx +78 -0
  222. premiere_cli/panel/host/commands/set-uniform-scale.jsx +104 -0
  223. premiere_cli/panel/host/commands/set-work-area.jsx +76 -0
  224. premiere_cli/panel/host/commands/set-workspace.jsx +35 -0
  225. premiere_cli/panel/host/commands/set-xmp-metadata.jsx +157 -0
  226. premiere_cli/panel/host/commands/slide-edit.jsx +162 -0
  227. premiere_cli/panel/host/commands/slip-edit.jsx +167 -0
  228. premiere_cli/panel/host/commands/split-clip.jsx +144 -0
  229. premiere_cli/panel/host/commands/stabilize-clip.jsx +139 -0
  230. premiere_cli/panel/host/commands/stop-playback.jsx +23 -0
  231. premiere_cli/panel/host/commands/trim-clip.jsx +111 -0
  232. premiere_cli/panel/host/commands/undo.jsx +114 -0
  233. premiere_cli/panel/host/commands/unlink-selection.jsx +106 -0
  234. premiere_cli/panel/host/commands/unnest-sequence.jsx +207 -0
  235. premiere_cli/panel/host/commands/update-marker.jsx +120 -0
  236. premiere_cli/panel/host/index.jsx +1227 -0
  237. premiere_cli/panel/host/presets/default-4k-25fps.sqpreset +63 -0
  238. premiere_cli/panel/index.html +16 -0
  239. premiere_cli/panel/js/cs-interface.js +11 -0
  240. premiere_cli/panel/js/main.js +409 -0
  241. premiere_cli/panel_install.py +220 -0
  242. premiere_cli-0.2.0.dist-info/METADATA +127 -0
  243. premiere_cli-0.2.0.dist-info/RECORD +247 -0
  244. premiere_cli-0.2.0.dist-info/WHEEL +5 -0
  245. premiere_cli-0.2.0.dist-info/entry_points.txt +3 -0
  246. premiere_cli-0.2.0.dist-info/licenses/LICENSE +428 -0
  247. premiere_cli-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,135 @@
1
+ // Command: get-clip-links → ppb_getClipLinks
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. Clip addressing (sequenceName?,
7
+ // trackType, trackIndex, clipIndex) matches get-full-clip-info.jsx. Linked
8
+ // clips are detected heuristically — same source projectItem.nodeId and
9
+ // the same start time — since there is no direct "get linked items" API
10
+ // (per PREMIERE_API_NOTES.md's Clips/TrackItems section). Helper names are
11
+ // prefixed ppbClipLinks_ to avoid colliding with same-purpose helpers in
12
+ // other lazily-loaded command files evaluated into this same global
13
+ // context.
14
+
15
+ function ppbClipLinks_findLinked(tracks, trackTypeLabel, clipNodeId, clipStartSeconds, srcNodeId, linked) {
16
+ for (var t = 0; t < tracks.numTracks; t++) {
17
+ var track = tracks[t];
18
+ var numClips = 0;
19
+ try {
20
+ numClips = track.clips.numItems;
21
+ } catch (e) {
22
+ numClips = 0;
23
+ }
24
+
25
+ for (var c = 0; c < numClips; c++) {
26
+ var other = track.clips[c];
27
+
28
+ var otherNodeId = null;
29
+ try { otherNodeId = other.nodeId; } catch (e) { otherNodeId = null; }
30
+ if (otherNodeId && clipNodeId && otherNodeId === clipNodeId) {
31
+ continue;
32
+ }
33
+
34
+ var otherSrcNodeId = null;
35
+ try {
36
+ otherSrcNodeId = other.projectItem ? other.projectItem.nodeId : null;
37
+ } catch (e) {
38
+ otherSrcNodeId = null;
39
+ }
40
+
41
+ var otherStartSeconds = null;
42
+ try { otherStartSeconds = timeValueToSeconds(other.start); } catch (e) { otherStartSeconds = null; }
43
+
44
+ if (srcNodeId && otherSrcNodeId === srcNodeId && otherStartSeconds !== null && clipStartSeconds !== null && otherStartSeconds === clipStartSeconds) {
45
+ var entry = { nodeId: otherNodeId, name: null, trackType: trackTypeLabel, trackIndex: t, startSeconds: otherStartSeconds, endSeconds: null };
46
+ try { entry.name = other.name; } catch (e) { entry.name = null; }
47
+ try { entry.endSeconds = timeValueToSeconds(other.end); } catch (e) { entry.endSeconds = null; }
48
+ linked.push(entry);
49
+ }
50
+ }
51
+ }
52
+ }
53
+
54
+ function ppb_getClipLinks(argsJson) {
55
+ try {
56
+ var args;
57
+ try {
58
+ args = JSON.parse(argsJson);
59
+ } catch (e) {
60
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
61
+ }
62
+
63
+ if (args.trackType !== "video" && args.trackType !== "audio") {
64
+ return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
65
+ }
66
+ if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
67
+ return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
68
+ }
69
+ if (typeof args.clipIndex !== "number" || args.clipIndex < 0 || Math.floor(args.clipIndex) !== args.clipIndex) {
70
+ return JSON.stringify({ ok: false, error: "clipIndex must be a non-negative integer" });
71
+ }
72
+
73
+ if (!app.project) {
74
+ return JSON.stringify({ ok: false, error: "no project open" });
75
+ }
76
+
77
+ var seq = null;
78
+ if (args.sequenceName && typeof args.sequenceName === "string") {
79
+ seq = findSequenceByName(args.sequenceName);
80
+ if (!seq) {
81
+ return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
82
+ }
83
+ } else {
84
+ seq = app.project.activeSequence;
85
+ if (!seq) {
86
+ return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
87
+ }
88
+ }
89
+
90
+ var trackCollection = args.trackType === "video" ? seq.videoTracks : seq.audioTracks;
91
+ var numTracks = trackCollection.numTracks;
92
+ if (args.trackIndex >= numTracks) {
93
+ return JSON.stringify({
94
+ ok: false,
95
+ error: "trackIndex " + args.trackIndex + " is out of range — sequence has " + numTracks + " " + args.trackType + " track(s)"
96
+ });
97
+ }
98
+
99
+ var track = trackCollection[args.trackIndex];
100
+ var numClips = track.clips.numItems;
101
+ if (args.clipIndex >= numClips) {
102
+ return JSON.stringify({
103
+ ok: false,
104
+ error: "clipIndex " + args.clipIndex + " is out of range — track " + args.trackIndex + " has " + numClips + " clip(s)"
105
+ });
106
+ }
107
+
108
+ var clip = track.clips[args.clipIndex];
109
+
110
+ var info = { nodeId: null, name: null, trackType: args.trackType, trackIndex: args.trackIndex, clipIndex: args.clipIndex };
111
+ try { info.nodeId = clip.nodeId; } catch (e) { info.nodeId = null; }
112
+ try { info.name = clip.name; } catch (e) { info.name = null; }
113
+
114
+ var clipStartSeconds = null;
115
+ try { clipStartSeconds = timeValueToSeconds(clip.start); } catch (e) { clipStartSeconds = null; }
116
+
117
+ var srcNodeId = null;
118
+ try {
119
+ srcNodeId = clip.projectItem ? clip.projectItem.nodeId : null;
120
+ } catch (e) {
121
+ srcNodeId = null;
122
+ }
123
+
124
+ var linked = [];
125
+ ppbClipLinks_findLinked(seq.videoTracks, "video", info.nodeId, clipStartSeconds, srcNodeId, linked);
126
+ ppbClipLinks_findLinked(seq.audioTracks, "audio", info.nodeId, clipStartSeconds, srcNodeId, linked);
127
+
128
+ info.linkedClips = linked;
129
+ info.linkedCount = linked.length;
130
+
131
+ return JSON.stringify({ ok: true, result: info });
132
+ } catch (e) {
133
+ return JSON.stringify({ ok: false, error: e.toString() });
134
+ }
135
+ }
@@ -0,0 +1,144 @@
1
+ // Command: get-clip-markers → ppb_getClipMarkers
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
+ // Clip addressing matches get-full-clip-info.jsx (sequenceName?,
7
+ // trackType, trackIndex, clipIndex) — the reference tool this is ported
8
+ // from (leancoderkavy's get_clip_markers) addresses a PROJECT item by
9
+ // item_id, but per our own convention every other clip-scoped command
10
+ // addresses a TIMELINE clip the same way get-full-clip-info does, so this
11
+ // reads clip.markers (a TrackItem's own marker collection — same API
12
+ // shape as seq.markers per PREMIERE_API_NOTES.md) rather than a project
13
+ // item's getMarkers().
14
+
15
+ function ppbGetClipMarkers_serialize(clip, sourceOut) {
16
+ var markers = [];
17
+ // clip.markers (a TrackItem's own marker collection) is undefined on
18
+ // this Premiere 2026 build (live-tested 2026-07-17: "undefined is not
19
+ // an object") — fall back to the clip's source project item's
20
+ // getMarkers(). Semantics differ slightly (source-item markers vs
21
+ // timeline-clip markers); result reports which source answered.
22
+ var collection = null;
23
+ try {
24
+ if (clip.markers && typeof clip.markers.getFirstMarker === "function") {
25
+ collection = clip.markers;
26
+ sourceOut.source = "trackItem";
27
+ }
28
+ } catch (e) {
29
+ // fall through
30
+ }
31
+ if (collection === null) {
32
+ try {
33
+ var itemMarkers = clip.projectItem.getMarkers();
34
+ if (itemMarkers && typeof itemMarkers.getFirstMarker === "function") {
35
+ collection = itemMarkers;
36
+ sourceOut.source = "projectItem";
37
+ }
38
+ } catch (e) {
39
+ // fall through
40
+ }
41
+ }
42
+ if (collection === null) {
43
+ throw new Error("neither clip.markers nor clip.projectItem.getMarkers() is available on this build");
44
+ }
45
+
46
+ var m = collection.getFirstMarker();
47
+ var iterations = 0;
48
+ while (m !== null && typeof m !== "undefined" && iterations < 10000) {
49
+ var entry = { name: null, comments: null, type: null, startSeconds: null, endSeconds: null, guid: null };
50
+ try { entry.name = m.name; } catch (e) { entry.name = null; }
51
+ try { entry.comments = m.comments; } catch (e) { entry.comments = null; }
52
+ try { entry.type = m.type; } catch (e) { entry.type = null; }
53
+ try { entry.startSeconds = timeValueToSeconds(m.start); } catch (e) { entry.startSeconds = null; }
54
+ try { entry.endSeconds = timeValueToSeconds(m.end); } catch (e) { entry.endSeconds = null; }
55
+ try { entry.guid = m.guid; } catch (e) { entry.guid = null; }
56
+ markers.push(entry);
57
+
58
+ m = collection.getNextMarker(m);
59
+ iterations++;
60
+ }
61
+ return markers;
62
+ }
63
+
64
+ function ppb_getClipMarkers(argsJson) {
65
+ try {
66
+ var args;
67
+ try {
68
+ args = JSON.parse(argsJson);
69
+ } catch (e) {
70
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
71
+ }
72
+
73
+ if (args.trackType !== "video" && args.trackType !== "audio") {
74
+ return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
75
+ }
76
+ if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
77
+ return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
78
+ }
79
+ if (typeof args.clipIndex !== "number" || args.clipIndex < 0 || Math.floor(args.clipIndex) !== args.clipIndex) {
80
+ return JSON.stringify({ ok: false, error: "clipIndex must be a non-negative integer" });
81
+ }
82
+
83
+ if (!app.project) {
84
+ return JSON.stringify({ ok: false, error: "no project open" });
85
+ }
86
+
87
+ var seq = null;
88
+ if (args.sequenceName && typeof args.sequenceName === "string") {
89
+ seq = findSequenceByName(args.sequenceName);
90
+ if (!seq) {
91
+ return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
92
+ }
93
+ } else {
94
+ seq = app.project.activeSequence;
95
+ if (!seq) {
96
+ return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
97
+ }
98
+ }
99
+
100
+ var trackCollection = args.trackType === "video" ? seq.videoTracks : seq.audioTracks;
101
+ var numTracks = trackCollection.numTracks;
102
+ if (args.trackIndex >= numTracks) {
103
+ return JSON.stringify({
104
+ ok: false,
105
+ error: "trackIndex " + args.trackIndex + " is out of range — sequence has " + numTracks + " " + args.trackType + " track(s)"
106
+ });
107
+ }
108
+
109
+ var track = trackCollection[args.trackIndex];
110
+ var numClips = track.clips.numItems;
111
+ if (args.clipIndex >= numClips) {
112
+ return JSON.stringify({
113
+ ok: false,
114
+ error: "clipIndex " + args.clipIndex + " is out of range — track " + args.trackIndex + " has " + numClips + " clip(s)"
115
+ });
116
+ }
117
+
118
+ var clip = track.clips[args.clipIndex];
119
+
120
+ var markers = [];
121
+ try {
122
+ var markerSource = { source: null };
123
+ markers = ppbGetClipMarkers_serialize(clip, markerSource);
124
+ } catch (e) {
125
+ return JSON.stringify({ ok: false, error: "failed to read clip markers: " + e.toString() });
126
+ }
127
+
128
+ return JSON.stringify({
129
+ ok: true,
130
+ result: {
131
+ sequenceName: seq.name,
132
+ trackType: args.trackType,
133
+ trackIndex: args.trackIndex,
134
+ clipIndex: args.clipIndex,
135
+ clipName: (function () { try { return clip.name; } catch (e) { return null; } })(),
136
+ markers: markers,
137
+ markerCount: markers.length,
138
+ markerSource: markerSource.source
139
+ }
140
+ });
141
+ } catch (e) {
142
+ return JSON.stringify({ ok: false, error: e.toString() });
143
+ }
144
+ }
@@ -0,0 +1,69 @@
1
+ // Command: get-clip-speed → ppb_getClipSpeed
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
3
+ // same global ExtendScript context — shared helpers (findSequenceByName,
4
+ // resolveTimelineClip, ...) are already defined there.
5
+ //
6
+ // READ-ONLY. Ported from leancoderkavy's premiere-pro-mcp get_clip_speed
7
+ // tool: reads the standard-DOM clip.getSpeed()/isSpeedReversed(), the
8
+ // same pair set-clip-speed verifies its own writes against.
9
+
10
+ function ppb_getClipSpeed(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" || typeof args.clipIndex !== "number") {
23
+ return JSON.stringify({ ok: false, error: "trackIndex and clipIndex are required" });
24
+ }
25
+
26
+ if (!app.project) {
27
+ return JSON.stringify({ ok: false, error: "no project open" });
28
+ }
29
+
30
+ var seq = null;
31
+ if (args.sequenceName && typeof args.sequenceName === "string") {
32
+ seq = findSequenceByName(args.sequenceName);
33
+ if (!seq) {
34
+ return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
35
+ }
36
+ } else {
37
+ seq = app.project.activeSequence;
38
+ if (!seq) {
39
+ return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
40
+ }
41
+ }
42
+
43
+ var resolved = resolveTimelineClip(seq, args.trackType, args.trackIndex, args.clipIndex);
44
+ if (resolved.error) {
45
+ return JSON.stringify({ ok: false, error: resolved.error });
46
+ }
47
+ var clip = resolved.clip;
48
+
49
+ var speed = null;
50
+ var isSpeedReversed = null;
51
+ try { speed = clip.getSpeed(); } catch (e2) { speed = null; }
52
+ try { isSpeedReversed = clip.isSpeedReversed() === true || clip.isSpeedReversed() === 1; } catch (e3) { isSpeedReversed = null; }
53
+
54
+ return JSON.stringify({
55
+ ok: true,
56
+ result: {
57
+ sequenceName: seq.name,
58
+ trackType: args.trackType,
59
+ trackIndex: args.trackIndex,
60
+ clipIndex: args.clipIndex,
61
+ clipName: (function () { try { return clip.name; } catch (e) { return null; } })(),
62
+ speed: speed,
63
+ isSpeedReversed: isSpeedReversed
64
+ }
65
+ });
66
+ } catch (e) {
67
+ return JSON.stringify({ ok: false, error: e.toString() });
68
+ }
69
+ }
@@ -0,0 +1,89 @@
1
+ // Command: get-color-label → ppb_getColorLabel
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 (see
6
+ // get-item-metadata.jsx for the shared design note — the resolver is
7
+ // duplicated per-file since command files load independently).
8
+
9
+ function ppbFindItemGetColorLabel_walk(item, args, depth) {
10
+ if (depth > 32) {
11
+ return null;
12
+ }
13
+
14
+ var isBin = false;
15
+ try {
16
+ isBin = typeof ProjectItemType !== "undefined" && item.type === ProjectItemType.BIN;
17
+ } catch (e) {
18
+ isBin = false;
19
+ }
20
+
21
+ var matched = false;
22
+ if (args.nodeId !== null) {
23
+ try { matched = item.nodeId === args.nodeId; } catch (e) { matched = false; }
24
+ } else if (args.name !== null) {
25
+ try { matched = item.name === args.name; } catch (e) { matched = false; }
26
+ }
27
+ if (matched) {
28
+ return item;
29
+ }
30
+
31
+ if (isBin && item.children) {
32
+ for (var i = 0; i < item.children.numItems; i++) {
33
+ var found = ppbFindItemGetColorLabel_walk(item.children[i], args, depth + 1);
34
+ if (found) {
35
+ return found;
36
+ }
37
+ }
38
+ }
39
+ return null;
40
+ }
41
+
42
+ function ppbFindItemGetColorLabel_resolve(args) {
43
+ var root = app.project.rootItem;
44
+ for (var i = 0; i < root.children.numItems; i++) {
45
+ var found = ppbFindItemGetColorLabel_walk(root.children[i], args, 1);
46
+ if (found) {
47
+ return found;
48
+ }
49
+ }
50
+ return null;
51
+ }
52
+
53
+ function ppb_getColorLabel(argsJson) {
54
+ try {
55
+ var args;
56
+ try {
57
+ args = JSON.parse(argsJson);
58
+ } catch (e) {
59
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
60
+ }
61
+
62
+ var hasNodeId = typeof args.nodeId === "string" && args.nodeId.length > 0;
63
+ var hasName = typeof args.name === "string" && args.name.length > 0;
64
+ if (!hasNodeId && !hasName) {
65
+ return JSON.stringify({ ok: false, error: "either nodeId or name is required" });
66
+ }
67
+
68
+ if (!app.project) {
69
+ return JSON.stringify({ ok: false, error: "no project open" });
70
+ }
71
+
72
+ var item = ppbFindItemGetColorLabel_resolve({
73
+ nodeId: hasNodeId ? args.nodeId : null,
74
+ name: hasNodeId ? null : args.name
75
+ });
76
+ if (!item) {
77
+ return JSON.stringify({ ok: false, error: "no project item found matching the given nodeId/name" });
78
+ }
79
+
80
+ var result = { name: null, nodeId: null, colorLabel: null };
81
+ try { result.name = item.name; } catch (e) { result.name = null; }
82
+ try { result.nodeId = item.nodeId; } catch (e) { result.nodeId = null; }
83
+ try { result.colorLabel = item.getColorLabel(); } catch (e) { result.colorLabel = null; }
84
+
85
+ return JSON.stringify({ ok: true, result: result });
86
+ } catch (e) {
87
+ return JSON.stringify({ ok: false, error: e.toString() });
88
+ }
89
+ }
@@ -0,0 +1,99 @@
1
+ // Command: get-color-space → ppb_getColorSpace
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 (see
6
+ // get-item-metadata.jsx for the shared design note — the resolver is
7
+ // duplicated per-file since command files load independently).
8
+
9
+ function ppbFindItemGetColorSpace_walk(item, args, depth) {
10
+ if (depth > 32) {
11
+ return null;
12
+ }
13
+
14
+ var isBin = false;
15
+ try {
16
+ isBin = typeof ProjectItemType !== "undefined" && item.type === ProjectItemType.BIN;
17
+ } catch (e) {
18
+ isBin = false;
19
+ }
20
+
21
+ var matched = false;
22
+ if (args.nodeId !== null) {
23
+ try { matched = item.nodeId === args.nodeId; } catch (e) { matched = false; }
24
+ } else if (args.name !== null) {
25
+ try { matched = item.name === args.name; } catch (e) { matched = false; }
26
+ }
27
+ if (matched) {
28
+ return item;
29
+ }
30
+
31
+ if (isBin && item.children) {
32
+ for (var i = 0; i < item.children.numItems; i++) {
33
+ var found = ppbFindItemGetColorSpace_walk(item.children[i], args, depth + 1);
34
+ if (found) {
35
+ return found;
36
+ }
37
+ }
38
+ }
39
+ return null;
40
+ }
41
+
42
+ function ppbFindItemGetColorSpace_resolve(args) {
43
+ var root = app.project.rootItem;
44
+ for (var i = 0; i < root.children.numItems; i++) {
45
+ var found = ppbFindItemGetColorSpace_walk(root.children[i], args, 1);
46
+ if (found) {
47
+ return found;
48
+ }
49
+ }
50
+ return null;
51
+ }
52
+
53
+ function ppb_getColorSpace(argsJson) {
54
+ try {
55
+ var args;
56
+ try {
57
+ args = JSON.parse(argsJson);
58
+ } catch (e) {
59
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
60
+ }
61
+
62
+ var hasNodeId = typeof args.nodeId === "string" && args.nodeId.length > 0;
63
+ var hasName = typeof args.name === "string" && args.name.length > 0;
64
+ if (!hasNodeId && !hasName) {
65
+ return JSON.stringify({ ok: false, error: "either nodeId or name is required" });
66
+ }
67
+
68
+ if (!app.project) {
69
+ return JSON.stringify({ ok: false, error: "no project open" });
70
+ }
71
+
72
+ var item = ppbFindItemGetColorSpace_resolve({
73
+ nodeId: hasNodeId ? args.nodeId : null,
74
+ name: hasNodeId ? null : args.name
75
+ });
76
+ if (!item) {
77
+ return JSON.stringify({ ok: false, error: "no project item found matching the given nodeId/name" });
78
+ }
79
+
80
+ var result = {
81
+ name: null,
82
+ nodeId: null,
83
+ colorSpace: null,
84
+ originalColorSpace: null,
85
+ embeddedLUT: null,
86
+ inputLUT: null
87
+ };
88
+ try { result.name = item.name; } catch (e) { result.name = null; }
89
+ try { result.nodeId = item.nodeId; } catch (e) { result.nodeId = null; }
90
+ try { result.colorSpace = item.getColorSpace(); } catch (e) { result.colorSpace = null; }
91
+ try { result.originalColorSpace = item.getOriginalColorSpace(); } catch (e) { result.originalColorSpace = null; }
92
+ try { result.embeddedLUT = item.getEmbeddedLUTID(); } catch (e) { result.embeddedLUT = null; }
93
+ try { result.inputLUT = item.getInputLUTID(); } catch (e) { result.inputLUT = null; }
94
+
95
+ return JSON.stringify({ ok: true, result: result });
96
+ } catch (e) {
97
+ return JSON.stringify({ ok: false, error: e.toString() });
98
+ }
99
+ }
@@ -0,0 +1,78 @@
1
+ // Command: get-duplicate-media → ppb_getDuplicateMedia
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
+ // Recursive walk of app.project.rootItem.children (same shape as
7
+ // list-project-items.jsx), grouping non-bin items by mediaPath and
8
+ // reporting groups with more than one member. Helper names are prefixed
9
+ // ppbDuplicateMedia_ to avoid colliding with same-purpose helpers in other
10
+ // lazily-loaded command files evaluated into this same global context.
11
+
12
+ function ppbDuplicateMedia_isBin(item) {
13
+ try {
14
+ return typeof ProjectItemType !== "undefined" && item.type === ProjectItemType.BIN;
15
+ } catch (e) {
16
+ return false;
17
+ }
18
+ }
19
+
20
+ // Capped at depth 32 to defend against pathological/circular bin
21
+ // structures rather than looping forever.
22
+ function ppbDuplicateMedia_scan(item, depth, pathMap, order) {
23
+ if (depth > 32) {
24
+ return;
25
+ }
26
+
27
+ var mediaPath = null;
28
+ try {
29
+ mediaPath = item.getMediaPath();
30
+ } catch (e) {
31
+ mediaPath = null;
32
+ }
33
+
34
+ if (mediaPath) {
35
+ if (!pathMap[mediaPath]) {
36
+ pathMap[mediaPath] = [];
37
+ order.push(mediaPath);
38
+ }
39
+ var entry = { nodeId: null, name: null, treePath: null };
40
+ try { entry.nodeId = item.nodeId; } catch (e) { entry.nodeId = null; }
41
+ try { entry.name = item.name; } catch (e) { entry.name = null; }
42
+ try { entry.treePath = item.treePath; } catch (e) { entry.treePath = null; }
43
+ pathMap[mediaPath].push(entry);
44
+ }
45
+
46
+ if (ppbDuplicateMedia_isBin(item) && item.children) {
47
+ for (var i = 0; i < item.children.numItems; i++) {
48
+ ppbDuplicateMedia_scan(item.children[i], depth + 1, pathMap, order);
49
+ }
50
+ }
51
+ }
52
+
53
+ function ppb_getDuplicateMedia(argsJson) {
54
+ try {
55
+ if (!app.project) {
56
+ return JSON.stringify({ ok: false, error: "no project open" });
57
+ }
58
+
59
+ var pathMap = {};
60
+ var order = [];
61
+ var root = app.project.rootItem;
62
+ for (var i = 0; i < root.children.numItems; i++) {
63
+ ppbDuplicateMedia_scan(root.children[i], 1, pathMap, order);
64
+ }
65
+
66
+ var duplicates = [];
67
+ for (var j = 0; j < order.length; j++) {
68
+ var path = order[j];
69
+ if (pathMap[path].length > 1) {
70
+ duplicates.push({ mediaPath: path, count: pathMap[path].length, items: pathMap[path] });
71
+ }
72
+ }
73
+
74
+ return JSON.stringify({ ok: true, result: { duplicateGroupCount: duplicates.length, duplicates: duplicates } });
75
+ } catch (e) {
76
+ return JSON.stringify({ ok: false, error: e.toString() });
77
+ }
78
+ }