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,103 @@
|
|
|
1
|
+
// Command: get-active-sequence → ppb_getActiveSequence
|
|
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
|
+
// 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.
|
|
8
|
+
|
|
9
|
+
function ppb_serializeTrack(track, trackIndex) {
|
|
10
|
+
var out = {
|
|
11
|
+
index: trackIndex,
|
|
12
|
+
name: null,
|
|
13
|
+
isMuted: null,
|
|
14
|
+
isLocked: null,
|
|
15
|
+
clipCount: null,
|
|
16
|
+
clips: []
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
try { out.name = track.name; } catch (e) { out.name = null; }
|
|
20
|
+
try { out.isMuted = track.isMuted(); } catch (e) { out.isMuted = null; }
|
|
21
|
+
try { out.isLocked = track.isLocked(); } catch (e) { out.isLocked = null; }
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
out.clipCount = track.clips.numItems;
|
|
25
|
+
for (var c = 0; c < track.clips.numItems; c++) {
|
|
26
|
+
out.clips.push(serializeTrackItem(track.clips[c], trackIndex, c));
|
|
27
|
+
}
|
|
28
|
+
} catch (e) {
|
|
29
|
+
// leave clipCount/clips as-is (null / whatever was collected so far)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function ppb_getActiveSequence(argsJson) {
|
|
36
|
+
try {
|
|
37
|
+
if (!app.project) {
|
|
38
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var seq = app.project.activeSequence;
|
|
42
|
+
if (!seq) {
|
|
43
|
+
return JSON.stringify({ ok: false, error: "no active sequence" });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
var frameRate = null;
|
|
47
|
+
try {
|
|
48
|
+
frameRate = getSequenceFps(seq);
|
|
49
|
+
} catch (e) {
|
|
50
|
+
frameRate = null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
var durationSeconds = null;
|
|
54
|
+
try {
|
|
55
|
+
durationSeconds = (Number(seq.end) - Number(seq.zeroPoint)) / TICKS_PER_SECOND;
|
|
56
|
+
} catch (e) {
|
|
57
|
+
durationSeconds = null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
var width = null;
|
|
61
|
+
var height = null;
|
|
62
|
+
try {
|
|
63
|
+
var settings = seq.getSettings();
|
|
64
|
+
width = settings.videoFrameWidth;
|
|
65
|
+
height = settings.videoFrameHeight;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
// best-effort only
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var videoTracks = [];
|
|
71
|
+
try {
|
|
72
|
+
for (var v = 0; v < seq.videoTracks.numTracks; v++) {
|
|
73
|
+
videoTracks.push(ppb_serializeTrack(seq.videoTracks[v], v));
|
|
74
|
+
}
|
|
75
|
+
} catch (e) {
|
|
76
|
+
// leave videoTracks as whatever was collected so far
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
var audioTracks = [];
|
|
80
|
+
try {
|
|
81
|
+
for (var a = 0; a < seq.audioTracks.numTracks; a++) {
|
|
82
|
+
audioTracks.push(ppb_serializeTrack(seq.audioTracks[a], a));
|
|
83
|
+
}
|
|
84
|
+
} catch (e) {
|
|
85
|
+
// leave audioTracks as whatever was collected so far
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
var result = {
|
|
89
|
+
name: seq.name,
|
|
90
|
+
sequenceID: seq.sequenceID,
|
|
91
|
+
frameRate: frameRate,
|
|
92
|
+
durationSeconds: durationSeconds,
|
|
93
|
+
width: width,
|
|
94
|
+
height: height,
|
|
95
|
+
videoTracks: videoTracks,
|
|
96
|
+
audioTracks: audioTracks
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return JSON.stringify({ ok: true, result: result });
|
|
100
|
+
} catch (e) {
|
|
101
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Command: get-all-project-paths → ppb_getAllProjectPaths
|
|
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), collecting every unique non-null mediaPath.
|
|
8
|
+
// Helper names are prefixed ppbAllProjectPaths_ to avoid colliding with
|
|
9
|
+
// same-purpose helpers in other lazily-loaded command files evaluated into
|
|
10
|
+
// this same global context.
|
|
11
|
+
|
|
12
|
+
function ppbAllProjectPaths_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 ppbAllProjectPaths_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 && !pathMap[mediaPath]) {
|
|
35
|
+
var entry = { path: mediaPath, name: null, nodeId: null, offline: null };
|
|
36
|
+
try { entry.name = item.name; } catch (e) { entry.name = null; }
|
|
37
|
+
try { entry.nodeId = item.nodeId; } catch (e) { entry.nodeId = null; }
|
|
38
|
+
try { entry.offline = item.isOffline(); } catch (e) { entry.offline = null; }
|
|
39
|
+
pathMap[mediaPath] = entry;
|
|
40
|
+
order.push(mediaPath);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (ppbAllProjectPaths_isBin(item) && item.children) {
|
|
44
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
45
|
+
ppbAllProjectPaths_scan(item.children[i], depth + 1, pathMap, order);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function ppb_getAllProjectPaths(argsJson) {
|
|
51
|
+
try {
|
|
52
|
+
if (!app.project) {
|
|
53
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
var pathMap = {};
|
|
57
|
+
var order = [];
|
|
58
|
+
var root = app.project.rootItem;
|
|
59
|
+
for (var i = 0; i < root.children.numItems; i++) {
|
|
60
|
+
ppbAllProjectPaths_scan(root.children[i], 1, pathMap, order);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
var paths = [];
|
|
64
|
+
for (var j = 0; j < order.length; j++) {
|
|
65
|
+
paths.push(pathMap[order[j]]);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return JSON.stringify({ ok: true, result: { pathCount: paths.length, paths: paths } });
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// Command: get-bin-contents → ppb_getBinContents
|
|
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
|
+
// Resolves a bin by a '/'-separated path (same convention as
|
|
7
|
+
// create-sequence's --bin) starting at app.project.rootItem, then
|
|
8
|
+
// recursively lists its contents (same walk shape as list-project-items.jsx),
|
|
9
|
+
// capped at depth 32. Helper names are prefixed ppbBinContents_ to avoid
|
|
10
|
+
// colliding with same-purpose helpers in other lazily-loaded command files
|
|
11
|
+
// evaluated into this same global context.
|
|
12
|
+
|
|
13
|
+
function ppbBinContents_isBin(item) {
|
|
14
|
+
try {
|
|
15
|
+
return typeof ProjectItemType !== "undefined" && item.type === ProjectItemType.BIN;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function ppbBinContents_typeToString(item) {
|
|
22
|
+
try {
|
|
23
|
+
if (typeof ProjectItemType !== "undefined") {
|
|
24
|
+
if (item.type === ProjectItemType.BIN) {
|
|
25
|
+
return "BIN";
|
|
26
|
+
}
|
|
27
|
+
if (item.type === ProjectItemType.CLIP) {
|
|
28
|
+
return "CLIP";
|
|
29
|
+
}
|
|
30
|
+
if (item.type === ProjectItemType.FILE) {
|
|
31
|
+
return "FILE";
|
|
32
|
+
}
|
|
33
|
+
if (item.type === ProjectItemType.ROOT) {
|
|
34
|
+
return "ROOT";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
} catch (e) {
|
|
38
|
+
// fall through to raw number below
|
|
39
|
+
}
|
|
40
|
+
return String(item.type);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Capped at depth 32 to defend against pathological/circular bin
|
|
44
|
+
// structures rather than looping forever.
|
|
45
|
+
function ppbBinContents_walk(item, parentPath, depth, results) {
|
|
46
|
+
if (depth > 32) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
var treePath = null;
|
|
51
|
+
try {
|
|
52
|
+
treePath = item.treePath;
|
|
53
|
+
} catch (e) {
|
|
54
|
+
treePath = null;
|
|
55
|
+
}
|
|
56
|
+
if (!treePath) {
|
|
57
|
+
treePath = parentPath + "/" + item.name;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
var mediaPath = null;
|
|
61
|
+
try {
|
|
62
|
+
mediaPath = item.getMediaPath();
|
|
63
|
+
} catch (e) {
|
|
64
|
+
mediaPath = null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
var isOffline = null;
|
|
68
|
+
try {
|
|
69
|
+
isOffline = item.isOffline();
|
|
70
|
+
} catch (e) {
|
|
71
|
+
isOffline = null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var colorLabel = null;
|
|
75
|
+
try {
|
|
76
|
+
colorLabel = item.getColorLabel();
|
|
77
|
+
} catch (e) {
|
|
78
|
+
colorLabel = null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
results.push({
|
|
82
|
+
name: item.name,
|
|
83
|
+
treePath: treePath,
|
|
84
|
+
nodeId: item.nodeId,
|
|
85
|
+
type: ppbBinContents_typeToString(item),
|
|
86
|
+
mediaPath: mediaPath,
|
|
87
|
+
isOffline: isOffline,
|
|
88
|
+
colorLabel: colorLabel
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (ppbBinContents_isBin(item) && item.children) {
|
|
92
|
+
for (var i = 0; i < item.children.numItems; i++) {
|
|
93
|
+
ppbBinContents_walk(item.children[i], treePath, depth + 1, results);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Resolves a '/'-separated bin path to a bin ProjectItem, starting at
|
|
99
|
+
// rootItem. Every path segment must match an existing bin by name — this
|
|
100
|
+
// command never creates bins (unlike create-sequence's --bin).
|
|
101
|
+
function ppbBinContents_findBin(binPath) {
|
|
102
|
+
var segments = binPath.split("/").filter(function (s) { return s.length > 0; });
|
|
103
|
+
var current = app.project.rootItem;
|
|
104
|
+
|
|
105
|
+
for (var i = 0; i < segments.length; i++) {
|
|
106
|
+
var segment = segments[i];
|
|
107
|
+
var found = null;
|
|
108
|
+
|
|
109
|
+
for (var j = 0; j < current.children.numItems; j++) {
|
|
110
|
+
var child = current.children[j];
|
|
111
|
+
if (child.name === segment && ppbBinContents_isBin(child)) {
|
|
112
|
+
found = child;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!found) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
current = found;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return current;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function ppb_getBinContents(argsJson) {
|
|
127
|
+
try {
|
|
128
|
+
var args;
|
|
129
|
+
try {
|
|
130
|
+
args = JSON.parse(argsJson);
|
|
131
|
+
} catch (e) {
|
|
132
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (!args.binPath || typeof args.binPath !== "string") {
|
|
136
|
+
return JSON.stringify({ ok: false, error: "binPath is required" });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!app.project) {
|
|
140
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
var bin = ppbBinContents_findBin(args.binPath);
|
|
144
|
+
if (!bin) {
|
|
145
|
+
return JSON.stringify({ ok: false, error: "no bin found at path \"" + args.binPath + "\"" });
|
|
146
|
+
}
|
|
147
|
+
if (!ppbBinContents_isBin(bin)) {
|
|
148
|
+
return JSON.stringify({ ok: false, error: "\"" + args.binPath + "\" is not a bin" });
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
var results = [];
|
|
152
|
+
for (var i = 0; i < bin.children.numItems; i++) {
|
|
153
|
+
ppbBinContents_walk(bin.children[i], bin.treePath || args.binPath, 1, results);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
var binTreePath = null;
|
|
157
|
+
try {
|
|
158
|
+
binTreePath = bin.treePath;
|
|
159
|
+
} catch (e) {
|
|
160
|
+
binTreePath = args.binPath;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return JSON.stringify({
|
|
164
|
+
ok: true,
|
|
165
|
+
result: {
|
|
166
|
+
binPath: args.binPath,
|
|
167
|
+
binNodeId: bin.nodeId,
|
|
168
|
+
binTreePath: binTreePath,
|
|
169
|
+
items: results,
|
|
170
|
+
count: results.length
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
} catch (e) {
|
|
174
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Command: get-clip-adjustment-layer → ppb_getClipAdjustmentLayer
|
|
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_clip_adjustment_layer` tool (advanced.ts), which addresses the clip
|
|
9
|
+
// by nodeId; here it uses the same sequenceName/trackType/trackIndex/
|
|
10
|
+
// clipIndex addressing convention as get-full-clip-info instead.
|
|
11
|
+
|
|
12
|
+
function ppb_getClipAdjustmentLayer(argsJson) {
|
|
13
|
+
try {
|
|
14
|
+
var args;
|
|
15
|
+
try {
|
|
16
|
+
args = JSON.parse(argsJson);
|
|
17
|
+
} catch (e) {
|
|
18
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (args.trackType !== "video" && args.trackType !== "audio") {
|
|
22
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
|
|
23
|
+
}
|
|
24
|
+
if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
|
|
25
|
+
return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
|
|
26
|
+
}
|
|
27
|
+
if (typeof args.clipIndex !== "number" || args.clipIndex < 0 || Math.floor(args.clipIndex) !== args.clipIndex) {
|
|
28
|
+
return JSON.stringify({ ok: false, error: "clipIndex must be a non-negative integer" });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!app.project) {
|
|
32
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var seq = null;
|
|
36
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
37
|
+
seq = findSequenceByName(args.sequenceName);
|
|
38
|
+
if (!seq) {
|
|
39
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
seq = app.project.activeSequence;
|
|
43
|
+
if (!seq) {
|
|
44
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
var trackCollection = args.trackType === "video" ? seq.videoTracks : seq.audioTracks;
|
|
49
|
+
var numTracks = trackCollection.numTracks;
|
|
50
|
+
if (args.trackIndex >= numTracks) {
|
|
51
|
+
return JSON.stringify({
|
|
52
|
+
ok: false,
|
|
53
|
+
error: "trackIndex " + args.trackIndex + " is out of range — sequence has " + numTracks + " " + args.trackType + " track(s)"
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
var track = trackCollection[args.trackIndex];
|
|
57
|
+
var numClips = track.clips.numItems;
|
|
58
|
+
if (args.clipIndex >= numClips) {
|
|
59
|
+
return JSON.stringify({
|
|
60
|
+
ok: false,
|
|
61
|
+
error: "clipIndex " + args.clipIndex + " is out of range — track " + args.trackIndex + " has " + numClips + " clip(s)"
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
var clip = track.clips[args.clipIndex];
|
|
66
|
+
|
|
67
|
+
var result = {
|
|
68
|
+
sequenceName: seq.name,
|
|
69
|
+
trackType: args.trackType,
|
|
70
|
+
trackIndex: args.trackIndex,
|
|
71
|
+
clipIndex: args.clipIndex,
|
|
72
|
+
clipName: null,
|
|
73
|
+
isAdjustmentLayer: null
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
try { result.clipName = clip.name; } catch (e) { result.clipName = null; }
|
|
77
|
+
try { result.isAdjustmentLayer = clip.isAdjustmentLayer(); } catch (e) { result.isAdjustmentLayer = null; }
|
|
78
|
+
|
|
79
|
+
return JSON.stringify({ ok: true, result: result });
|
|
80
|
+
} catch (e) {
|
|
81
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// Command: get-clip-at-playhead → ppb_getClipAtPlayhead
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// serializeTrackItem, 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_clip_at_playhead` tool (utility.ts): finds every clip (across all
|
|
9
|
+
// tracks, or just video/audio) that covers the sequence's current
|
|
10
|
+
// playhead position.
|
|
11
|
+
|
|
12
|
+
function ppb_getClipAtPlayhead(argsJson) {
|
|
13
|
+
try {
|
|
14
|
+
var args;
|
|
15
|
+
try {
|
|
16
|
+
args = JSON.parse(argsJson);
|
|
17
|
+
} catch (e) {
|
|
18
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var trackType = args.trackType || "both";
|
|
22
|
+
if (trackType !== "video" && trackType !== "audio" && trackType !== "both") {
|
|
23
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\", \"audio\", or \"both\"" });
|
|
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 playheadSeconds = null;
|
|
44
|
+
try {
|
|
45
|
+
playheadSeconds = timeValueToSeconds(seq.getPlayerPosition());
|
|
46
|
+
} catch (e) {
|
|
47
|
+
return JSON.stringify({ ok: false, error: "could not read playhead position: " + e.toString() });
|
|
48
|
+
}
|
|
49
|
+
if (playheadSeconds === null) {
|
|
50
|
+
return JSON.stringify({ ok: false, error: "could not read playhead position" });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
var clips = [];
|
|
54
|
+
|
|
55
|
+
function findAtPlayhead(trackCollection, type) {
|
|
56
|
+
var numTracks = 0;
|
|
57
|
+
try { numTracks = trackCollection.numTracks; } catch (e) { return; }
|
|
58
|
+
for (var t = 0; t < numTracks; t++) {
|
|
59
|
+
var track = trackCollection[t];
|
|
60
|
+
var numClips = 0;
|
|
61
|
+
try { numClips = track.clips.numItems; } catch (e) { continue; }
|
|
62
|
+
for (var c = 0; c < numClips; c++) {
|
|
63
|
+
var clip = track.clips[c];
|
|
64
|
+
var startSeconds = null;
|
|
65
|
+
var endSeconds = null;
|
|
66
|
+
try { startSeconds = timeValueToSeconds(clip.start); } catch (e) { startSeconds = null; }
|
|
67
|
+
try { endSeconds = timeValueToSeconds(clip.end); } catch (e) { endSeconds = null; }
|
|
68
|
+
if (startSeconds === null || endSeconds === null) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (startSeconds <= playheadSeconds && endSeconds > playheadSeconds) {
|
|
72
|
+
var serialized = serializeTrackItem(clip, t, c);
|
|
73
|
+
serialized.trackType = type;
|
|
74
|
+
clips.push(serialized);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (trackType !== "audio") {
|
|
81
|
+
findAtPlayhead(seq.videoTracks, "video");
|
|
82
|
+
}
|
|
83
|
+
if (trackType !== "video") {
|
|
84
|
+
findAtPlayhead(seq.audioTracks, "audio");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return JSON.stringify({
|
|
88
|
+
ok: true,
|
|
89
|
+
result: {
|
|
90
|
+
sequenceName: seq.name,
|
|
91
|
+
playheadSeconds: playheadSeconds,
|
|
92
|
+
clipCount: clips.length,
|
|
93
|
+
clips: clips
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
} catch (e) {
|
|
97
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Command: get-clip-at-position → ppb_getClipAtPosition
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// serializeTrackItem, timeValueToSeconds, ...) 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. Ported from leancoderkavy's
|
|
8
|
+
// premiere-pro-mcp `get_clip_at_position` tool (discovery.ts), which only
|
|
9
|
+
// searches one specific track; here `trackType`/`trackIndex` are optional
|
|
10
|
+
// filters — omitting both scans every video and audio track for whichever
|
|
11
|
+
// clip (if any) covers the given time.
|
|
12
|
+
|
|
13
|
+
function ppb_getClipAtPosition(argsJson) {
|
|
14
|
+
try {
|
|
15
|
+
var args;
|
|
16
|
+
try {
|
|
17
|
+
args = JSON.parse(argsJson);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (typeof args.seconds !== "number" || !isFinite(args.seconds) || args.seconds < 0) {
|
|
23
|
+
return JSON.stringify({ ok: false, error: "seconds must be a non-negative number" });
|
|
24
|
+
}
|
|
25
|
+
if (typeof args.trackType !== "undefined" && args.trackType !== "video" && args.trackType !== "audio") {
|
|
26
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\" if given" });
|
|
27
|
+
}
|
|
28
|
+
if (typeof args.trackIndex !== "undefined") {
|
|
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 if given" });
|
|
31
|
+
}
|
|
32
|
+
if (!args.trackType) {
|
|
33
|
+
return JSON.stringify({ ok: false, error: "trackIndex requires trackType to also be given" });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!app.project) {
|
|
38
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var seq = null;
|
|
42
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
43
|
+
seq = findSequenceByName(args.sequenceName);
|
|
44
|
+
if (!seq) {
|
|
45
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
seq = app.project.activeSequence;
|
|
49
|
+
if (!seq) {
|
|
50
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
var clips = [];
|
|
55
|
+
|
|
56
|
+
function scanTrack(track, trackType, trackIndex) {
|
|
57
|
+
var numClips = 0;
|
|
58
|
+
try { numClips = track.clips.numItems; } catch (e) { return; }
|
|
59
|
+
for (var c = 0; c < numClips; c++) {
|
|
60
|
+
var clip = track.clips[c];
|
|
61
|
+
var startSeconds = null;
|
|
62
|
+
var endSeconds = null;
|
|
63
|
+
try { startSeconds = timeValueToSeconds(clip.start); } catch (e) { startSeconds = null; }
|
|
64
|
+
try { endSeconds = timeValueToSeconds(clip.end); } catch (e) { endSeconds = null; }
|
|
65
|
+
if (startSeconds === null || endSeconds === null) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (args.seconds >= startSeconds && args.seconds < endSeconds) {
|
|
69
|
+
var serialized = serializeTrackItem(clip, trackIndex, c);
|
|
70
|
+
serialized.trackType = trackType;
|
|
71
|
+
clips.push(serialized);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function scanTrackType(trackType) {
|
|
77
|
+
var trackCollection = trackType === "video" ? seq.videoTracks : seq.audioTracks;
|
|
78
|
+
var numTracks = 0;
|
|
79
|
+
try { numTracks = trackCollection.numTracks; } catch (e) { numTracks = 0; }
|
|
80
|
+
|
|
81
|
+
if (typeof args.trackIndex === "number" && args.trackType === trackType) {
|
|
82
|
+
if (args.trackIndex >= numTracks) {
|
|
83
|
+
return "trackIndex " + args.trackIndex + " is out of range — sequence has " + numTracks + " " + trackType + " track(s)";
|
|
84
|
+
}
|
|
85
|
+
scanTrack(trackCollection[args.trackIndex], trackType, args.trackIndex);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
for (var t = 0; t < numTracks; t++) {
|
|
90
|
+
scanTrack(trackCollection[t], trackType, t);
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!args.trackType || args.trackType === "video") {
|
|
96
|
+
var videoErr = scanTrackType("video");
|
|
97
|
+
if (videoErr) {
|
|
98
|
+
return JSON.stringify({ ok: false, error: videoErr });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (!args.trackType || args.trackType === "audio") {
|
|
102
|
+
var audioErr = scanTrackType("audio");
|
|
103
|
+
if (audioErr) {
|
|
104
|
+
return JSON.stringify({ ok: false, error: audioErr });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return JSON.stringify({
|
|
109
|
+
ok: true,
|
|
110
|
+
result: {
|
|
111
|
+
sequenceName: seq.name,
|
|
112
|
+
seconds: args.seconds,
|
|
113
|
+
clipCount: clips.length,
|
|
114
|
+
clips: clips
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
} catch (e) {
|
|
118
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
119
|
+
}
|
|
120
|
+
}
|