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
premiere_cli/log.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Send a log message to the Premiere Bridge CEP panel, if it's open."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
import urllib.error
|
|
7
|
+
import urllib.request
|
|
8
|
+
|
|
9
|
+
DEFAULT_PORT = 47823
|
|
10
|
+
VALID_LEVELS = {"info", "warn", "error"}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def log(message: str, level: str = "info", source: str | None = None, port: int = DEFAULT_PORT) -> None:
|
|
14
|
+
"""POST a log message to the Premiere Bridge panel's /log endpoint.
|
|
15
|
+
|
|
16
|
+
Raises ValueError for an invalid level, ConnectionError if the panel
|
|
17
|
+
isn't reachable, or RuntimeError if the panel rejects the message.
|
|
18
|
+
"""
|
|
19
|
+
if level not in VALID_LEVELS:
|
|
20
|
+
raise ValueError(f"level must be one of {sorted(VALID_LEVELS)}, got {level!r}")
|
|
21
|
+
|
|
22
|
+
payload = {"message": message, "level": level}
|
|
23
|
+
if source:
|
|
24
|
+
payload["source"] = source
|
|
25
|
+
|
|
26
|
+
data = json.dumps(payload).encode("utf-8")
|
|
27
|
+
request = urllib.request.Request(
|
|
28
|
+
f"http://127.0.0.1:{port}/log",
|
|
29
|
+
data=data,
|
|
30
|
+
headers={"Content-Type": "application/json"},
|
|
31
|
+
method="POST",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
with urllib.request.urlopen(request, timeout=2) as response:
|
|
36
|
+
body = json.loads(response.read().decode("utf-8"))
|
|
37
|
+
except urllib.error.HTTPError as exc:
|
|
38
|
+
body = json.loads(exc.read().decode("utf-8"))
|
|
39
|
+
raise RuntimeError(f"panel rejected the log message: {body.get('error', 'unknown error')}") from exc
|
|
40
|
+
except OSError as exc:
|
|
41
|
+
raise ConnectionError(
|
|
42
|
+
f"could not reach the Premiere Bridge panel on port {port} "
|
|
43
|
+
f"(is the panel open in Premiere Pro?): {exc}"
|
|
44
|
+
) from exc
|
|
45
|
+
|
|
46
|
+
if not body.get("ok"):
|
|
47
|
+
raise RuntimeError(f"panel rejected the log message: {body.get('error', 'unknown error')}")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def main() -> None:
|
|
51
|
+
parser = argparse.ArgumentParser(description="Send a log message to the Premiere Bridge CEP panel.")
|
|
52
|
+
parser.add_argument("message", help="Text to display in the panel's log")
|
|
53
|
+
parser.add_argument("--level", choices=sorted(VALID_LEVELS), default="info", help="Log level (default: info)")
|
|
54
|
+
parser.add_argument("--source", default=None, help="Name of the script/tool sending this message")
|
|
55
|
+
parser.add_argument("--port", type=int, default=DEFAULT_PORT, help=f"Bridge panel port (default: {DEFAULT_PORT})")
|
|
56
|
+
args = parser.parse_args()
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
log(args.message, level=args.level, source=args.source, port=args.port)
|
|
60
|
+
except (ConnectionError, RuntimeError, ValueError) as exc:
|
|
61
|
+
print(f"Error: {exc}", file=sys.stderr)
|
|
62
|
+
sys.exit(1)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
if __name__ == "__main__":
|
|
66
|
+
main()
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<ExtensionManifest Version="7.0" ExtensionBundleId="com.generativegamedev.premierebridge" ExtensionBundleVersion="1.0.0" ExtensionBundleName="Premiere Bridge">
|
|
3
|
+
<ExtensionList>
|
|
4
|
+
<Extension Id="com.generativegamedev.premierebridge.panel" Version="1.0.0" />
|
|
5
|
+
</ExtensionList>
|
|
6
|
+
<ExecutionEnvironment>
|
|
7
|
+
<HostList>
|
|
8
|
+
<Host Name="PPRO" Version="[14.0,99.9]" />
|
|
9
|
+
</HostList>
|
|
10
|
+
<LocaleList>
|
|
11
|
+
<Locale Code="All" />
|
|
12
|
+
</LocaleList>
|
|
13
|
+
<RequiredRuntimeList>
|
|
14
|
+
<RequiredRuntime Name="CSXS" Version="11.0" />
|
|
15
|
+
</RequiredRuntimeList>
|
|
16
|
+
</ExecutionEnvironment>
|
|
17
|
+
<DispatchInfoList>
|
|
18
|
+
<Extension Id="com.generativegamedev.premierebridge.panel">
|
|
19
|
+
<DispatchInfo>
|
|
20
|
+
<Resources>
|
|
21
|
+
<MainPath>./index.html</MainPath>
|
|
22
|
+
<ScriptPath>./host/index.jsx</ScriptPath>
|
|
23
|
+
<CEFCommandLine>
|
|
24
|
+
<Parameter>--enable-nodejs</Parameter>
|
|
25
|
+
<Parameter>--mixed-context</Parameter>
|
|
26
|
+
</CEFCommandLine>
|
|
27
|
+
</Resources>
|
|
28
|
+
<Lifecycle>
|
|
29
|
+
<AutoVisible>true</AutoVisible>
|
|
30
|
+
</Lifecycle>
|
|
31
|
+
<UI>
|
|
32
|
+
<Type>Panel</Type>
|
|
33
|
+
<Menu>Premiere Bridge</Menu>
|
|
34
|
+
<Geometry>
|
|
35
|
+
<Size>
|
|
36
|
+
<Height>600</Height>
|
|
37
|
+
<Width>400</Width>
|
|
38
|
+
</Size>
|
|
39
|
+
<MinSize>
|
|
40
|
+
<Height>200</Height>
|
|
41
|
+
<Width>300</Width>
|
|
42
|
+
</MinSize>
|
|
43
|
+
<MaxSize>
|
|
44
|
+
<Height>2000</Height>
|
|
45
|
+
<Width>2000</Width>
|
|
46
|
+
</MaxSize>
|
|
47
|
+
</Geometry>
|
|
48
|
+
</UI>
|
|
49
|
+
</DispatchInfo>
|
|
50
|
+
</Extension>
|
|
51
|
+
</DispatchInfoList>
|
|
52
|
+
</ExtensionManifest>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
html, body {
|
|
2
|
+
margin: 0;
|
|
3
|
+
padding: 0;
|
|
4
|
+
height: 100%;
|
|
5
|
+
background: #1e1e1e;
|
|
6
|
+
color: #d4d4d4;
|
|
7
|
+
font-family: -apple-system, "Segoe UI", sans-serif;
|
|
8
|
+
font-size: 12px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
#toolbar {
|
|
12
|
+
padding: 6px 8px;
|
|
13
|
+
border-bottom: 1px solid #333;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#clear-button {
|
|
17
|
+
background: #2d2d2d;
|
|
18
|
+
color: #d4d4d4;
|
|
19
|
+
border: 1px solid #444;
|
|
20
|
+
border-radius: 3px;
|
|
21
|
+
padding: 4px 10px;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#clear-button:hover {
|
|
26
|
+
background: #3a3a3a;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#log-view {
|
|
30
|
+
height: calc(100% - 37px);
|
|
31
|
+
overflow-y: auto;
|
|
32
|
+
padding: 6px 8px;
|
|
33
|
+
box-sizing: border-box;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.log-line {
|
|
37
|
+
white-space: pre-wrap;
|
|
38
|
+
word-break: break-word;
|
|
39
|
+
padding: 2px 0;
|
|
40
|
+
font-family: "SF Mono", Menlo, monospace;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.log-info {
|
|
44
|
+
color: #d4d4d4;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.log-warn {
|
|
48
|
+
color: #e5c07b;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.log-error {
|
|
52
|
+
color: #e06c75;
|
|
53
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// Command: add-adjustment-layer → ppb_addAdjustmentLayer
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (ensureQEEnabled,
|
|
4
|
+
// findSequenceByName, TICKS_PER_SECOND, activateSequenceForQE, ...) are
|
|
5
|
+
// already defined there.
|
|
6
|
+
//
|
|
7
|
+
// Ported from leancoderkavy/premiere-pro-mcp's utility.ts
|
|
8
|
+
// add_adjustment_layer, adapted to PREMIERE_API_NOTES.md's PPro 2026
|
|
9
|
+
// finding: the legacy `qeSeq.addAdjustmentLayer(track)` one-call path was
|
|
10
|
+
// REMOVED in Premiere 2026 — this build only has
|
|
11
|
+
// `qe.project.newAdjustmentLayer()`, which creates a project-level
|
|
12
|
+
// adjustment-layer ProjectItem but does NOT place it on the timeline by
|
|
13
|
+
// itself. This command is therefore two independently-verified steps:
|
|
14
|
+
// 1. Create the project item (qe.project.newAdjustmentLayer()) —
|
|
15
|
+
// verified by a root-bin children-count increase, matching the new
|
|
16
|
+
// item by name containing "adjustment" (case-insensitive) among the
|
|
17
|
+
// newly-appeared items (never trusting the call's own return value).
|
|
18
|
+
// 2. Place it on the timeline at startSeconds on the given video track
|
|
19
|
+
// via qeTrack.insert()/insertClip() — verified by the target track's
|
|
20
|
+
// QE item count increasing.
|
|
21
|
+
// Either step can succeed independently of the other — both are reported
|
|
22
|
+
// so a caller can tell "item created but not placed" apart from total
|
|
23
|
+
// failure.
|
|
24
|
+
function ppb_addAdjustmentLayer(argsJson) {
|
|
25
|
+
try {
|
|
26
|
+
var args;
|
|
27
|
+
try {
|
|
28
|
+
args = JSON.parse(argsJson);
|
|
29
|
+
} catch (e) {
|
|
30
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!app.project) {
|
|
34
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var seq = null;
|
|
38
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
39
|
+
seq = findSequenceByName(args.sequenceName);
|
|
40
|
+
if (!seq) {
|
|
41
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
seq = app.project.activeSequence;
|
|
45
|
+
if (!seq) {
|
|
46
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
var trackIndex = typeof args.trackIndex === "number" ? args.trackIndex : 0;
|
|
51
|
+
if (trackIndex >= seq.videoTracks.numTracks) {
|
|
52
|
+
return JSON.stringify({ ok: false, error: "trackIndex " + trackIndex + " is out of range — sequence has " + seq.videoTracks.numTracks + " video track(s)" });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
ensureQEEnabled();
|
|
57
|
+
activateSequenceForQE(seq);
|
|
58
|
+
} catch (e) {
|
|
59
|
+
return JSON.stringify({ ok: false, error: "app.enableQE()/sequence activation failed: " + e.toString() });
|
|
60
|
+
}
|
|
61
|
+
if (typeof qe === "undefined" || !qe.project) {
|
|
62
|
+
return JSON.stringify({ ok: false, error: "QE DOM not available after enableQE()" });
|
|
63
|
+
}
|
|
64
|
+
var qeSeq = qe.project.getActiveSequence();
|
|
65
|
+
if (!qeSeq) {
|
|
66
|
+
return JSON.stringify({ ok: false, error: "qe.project.getActiveSequence() returned nothing after activating the sequence" });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (typeof qe.project.newAdjustmentLayer !== "function") {
|
|
70
|
+
return JSON.stringify({ ok: false, error: "qe.project.newAdjustmentLayer() is not available on this Premiere build" });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// --- Step 1: create the project item ---
|
|
74
|
+
var rootChildren = app.project.rootItem.children;
|
|
75
|
+
var namesBefore = {};
|
|
76
|
+
for (var b = 0; b < rootChildren.numItems; b++) {
|
|
77
|
+
var beforeName = null;
|
|
78
|
+
try { beforeName = rootChildren[b].name; } catch (e) { beforeName = null; }
|
|
79
|
+
namesBefore[b + ":" + beforeName] = true;
|
|
80
|
+
}
|
|
81
|
+
var countBefore = rootChildren.numItems;
|
|
82
|
+
|
|
83
|
+
var createError = null;
|
|
84
|
+
try {
|
|
85
|
+
qe.project.newAdjustmentLayer();
|
|
86
|
+
} catch (e) {
|
|
87
|
+
createError = e.toString();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
var countAfter = app.project.rootItem.children.numItems;
|
|
91
|
+
var itemCreated = createError === null && countAfter > countBefore;
|
|
92
|
+
|
|
93
|
+
if (!itemCreated) {
|
|
94
|
+
return JSON.stringify({
|
|
95
|
+
ok: false,
|
|
96
|
+
error: createError !== null
|
|
97
|
+
? ("qe.project.newAdjustmentLayer() failed: " + createError)
|
|
98
|
+
: "newAdjustmentLayer() did not throw, but the project's root item count did not increase",
|
|
99
|
+
countBefore: countBefore,
|
|
100
|
+
countAfter: countAfter
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
var adjItem = null;
|
|
105
|
+
var freshChildren = app.project.rootItem.children;
|
|
106
|
+
for (var c = freshChildren.numItems - 1; c >= 0; c--) {
|
|
107
|
+
var it = freshChildren[c];
|
|
108
|
+
var itName = null;
|
|
109
|
+
try { itName = it.name; } catch (e) { itName = null; }
|
|
110
|
+
if (itName && itName.toLowerCase().indexOf("adjustment") !== -1) {
|
|
111
|
+
adjItem = it;
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (!adjItem) {
|
|
116
|
+
return JSON.stringify({
|
|
117
|
+
ok: false,
|
|
118
|
+
error: "project item count increased after newAdjustmentLayer() but no item with \"adjustment\" in its name could be found",
|
|
119
|
+
countBefore: countBefore,
|
|
120
|
+
countAfter: countAfter
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// --- Step 2: place it on the timeline ---
|
|
125
|
+
var startSeconds = typeof args.startSeconds === "number" ? args.startSeconds : 0;
|
|
126
|
+
var startTicksString = String(Math.round(startSeconds * TICKS_PER_SECOND));
|
|
127
|
+
|
|
128
|
+
var qeTrack = null;
|
|
129
|
+
try {
|
|
130
|
+
qeTrack = qeSeq.getVideoTrackAt(trackIndex);
|
|
131
|
+
} catch (e) {
|
|
132
|
+
qeTrack = null;
|
|
133
|
+
}
|
|
134
|
+
if (!qeTrack) {
|
|
135
|
+
return JSON.stringify({
|
|
136
|
+
ok: false,
|
|
137
|
+
error: "QE video track " + trackIndex + " not found — the adjustment-layer project item was created but not placed on the timeline",
|
|
138
|
+
itemCreated: true,
|
|
139
|
+
projectItem: { name: adjItem.name, nodeId: adjItem.nodeId }
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
var placeCountBefore = null;
|
|
144
|
+
try { placeCountBefore = qeTrack.numItems; } catch (e) { placeCountBefore = null; }
|
|
145
|
+
|
|
146
|
+
var placeError = null;
|
|
147
|
+
var placeAttempts = [];
|
|
148
|
+
var placed = false;
|
|
149
|
+
try {
|
|
150
|
+
qeTrack.insert(adjItem, startTicksString);
|
|
151
|
+
placeAttempts.push({ form: "qeTrack.insert(item, ticksString)", success: true });
|
|
152
|
+
placed = true;
|
|
153
|
+
} catch (e1) {
|
|
154
|
+
placeAttempts.push({ form: "qeTrack.insert(item, ticksString)", success: false, error: e1.toString() });
|
|
155
|
+
try {
|
|
156
|
+
qeTrack.insertClip(adjItem, startTicksString);
|
|
157
|
+
placeAttempts.push({ form: "qeTrack.insertClip(item, ticksString)", success: true });
|
|
158
|
+
placed = true;
|
|
159
|
+
} catch (e2) {
|
|
160
|
+
placeAttempts.push({ form: "qeTrack.insertClip(item, ticksString)", success: false, error: e2.toString() });
|
|
161
|
+
placeError = e2.toString();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
var placeCountAfter = null;
|
|
166
|
+
try { placeCountAfter = qeTrack.numItems; } catch (e) { placeCountAfter = null; }
|
|
167
|
+
var placedVerified = placeCountBefore !== null && placeCountAfter !== null && placeCountAfter > placeCountBefore;
|
|
168
|
+
|
|
169
|
+
return JSON.stringify({
|
|
170
|
+
ok: itemCreated && placedVerified,
|
|
171
|
+
result: {
|
|
172
|
+
sequenceName: seq.name,
|
|
173
|
+
trackIndex: trackIndex,
|
|
174
|
+
startSeconds: startSeconds,
|
|
175
|
+
durationSeconds: typeof args.durationSeconds === "number" ? args.durationSeconds : null,
|
|
176
|
+
itemCreated: itemCreated,
|
|
177
|
+
projectItem: { name: adjItem.name, nodeId: adjItem.nodeId },
|
|
178
|
+
placed: placed,
|
|
179
|
+
placedVerified: placedVerified,
|
|
180
|
+
placeCountBefore: placeCountBefore,
|
|
181
|
+
placeCountAfter: placeCountAfter,
|
|
182
|
+
placeAttempts: placeAttempts,
|
|
183
|
+
placeError: placedVerified ? null : placeError,
|
|
184
|
+
note: "durationSeconds is not applied here — no confirmed API trims an inserted QE clip's length directly; use set-item-in-out or trim via the standard DOM after placement if a specific duration is required"
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
} catch (e) {
|
|
188
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// Command: add-audio-keyframes → ppb_addAudioKeyframes
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// findVolumeLevelProperty, timeValueToSeconds, TICKS_PER_SECOND, ...) are
|
|
5
|
+
// already defined there.
|
|
6
|
+
//
|
|
7
|
+
// Standard-DOM mutation. Ported from leancoderkavy's premiere-pro-mcp
|
|
8
|
+
// `add_audio_keyframes` tool (audio.ts). Per PREMIERE_API_NOTES.md:
|
|
9
|
+
// prop.setTimeVarying(true) is REQUIRED before addKey()/setValueAtKey(),
|
|
10
|
+
// and keyframe times are in SEQUENCE time (not clip-relative) — so each
|
|
11
|
+
// `seconds` value (documented as clip-relative, matching the reference's
|
|
12
|
+
// own "time_seconds ... relative to clip start" description) is offset by
|
|
13
|
+
// the clip's own start time before being converted to ticks.
|
|
14
|
+
//
|
|
15
|
+
// dB->linear conversion uses the SAME hetpatel-calibrated formula as
|
|
16
|
+
// set-clip-volume/adjust-audio-levels (linear = 10^((dB-15)/20)) so dB
|
|
17
|
+
// values are interchangeable across all three audio commands. Unified at
|
|
18
|
+
// integration 2026-07-17 — the reference tool's own code used a raw
|
|
19
|
+
// 10^(db/20), which disagreed with its sibling volume tools. The
|
|
20
|
+
// calibration itself is still UNVERIFIED against this Premiere build.
|
|
21
|
+
function ppb_addAudioKeyframes(argsJson) {
|
|
22
|
+
try {
|
|
23
|
+
var args;
|
|
24
|
+
try {
|
|
25
|
+
args = JSON.parse(argsJson);
|
|
26
|
+
} catch (e) {
|
|
27
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (args.trackType !== "video" && args.trackType !== "audio") {
|
|
31
|
+
return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
|
|
32
|
+
}
|
|
33
|
+
if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
|
|
34
|
+
return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
|
|
35
|
+
}
|
|
36
|
+
if (typeof args.clipIndex !== "number" || args.clipIndex < 0 || Math.floor(args.clipIndex) !== args.clipIndex) {
|
|
37
|
+
return JSON.stringify({ ok: false, error: "clipIndex must be a non-negative integer" });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
var keyframes;
|
|
41
|
+
if (typeof args.keyframes === "string") {
|
|
42
|
+
try {
|
|
43
|
+
keyframes = JSON.parse(args.keyframes);
|
|
44
|
+
} catch (e) {
|
|
45
|
+
return JSON.stringify({ ok: false, error: "keyframes could not be parsed as JSON: " + e.toString() });
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
return JSON.stringify({ ok: false, error: "keyframes must be a JSON string of [{seconds, db}, ...]" });
|
|
49
|
+
}
|
|
50
|
+
if (!(keyframes && typeof keyframes.length === "number")) {
|
|
51
|
+
return JSON.stringify({ ok: false, error: "keyframes must decode to a JSON array" });
|
|
52
|
+
}
|
|
53
|
+
if (keyframes.length === 0) {
|
|
54
|
+
return JSON.stringify({ ok: false, error: "keyframes array is empty — at least one keyframe is required" });
|
|
55
|
+
}
|
|
56
|
+
for (var v = 0; v < keyframes.length; v++) {
|
|
57
|
+
var kf = keyframes[v];
|
|
58
|
+
if (!kf || typeof kf.seconds !== "number" || typeof kf.db !== "number") {
|
|
59
|
+
return JSON.stringify({ ok: false, error: "keyframes[" + v + "] must be {seconds: number, db: number}" });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!app.project) {
|
|
64
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
var seq = null;
|
|
68
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
69
|
+
seq = findSequenceByName(args.sequenceName);
|
|
70
|
+
if (!seq) {
|
|
71
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
seq = app.project.activeSequence;
|
|
75
|
+
if (!seq) {
|
|
76
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
var trackCollection = args.trackType === "video" ? seq.videoTracks : seq.audioTracks;
|
|
81
|
+
var numTracks = trackCollection.numTracks;
|
|
82
|
+
if (args.trackIndex >= numTracks) {
|
|
83
|
+
return JSON.stringify({
|
|
84
|
+
ok: false,
|
|
85
|
+
error: "trackIndex " + args.trackIndex + " is out of range — sequence has " + numTracks + " " + args.trackType + " track(s)"
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
var track = trackCollection[args.trackIndex];
|
|
90
|
+
var numClips = track.clips.numItems;
|
|
91
|
+
if (args.clipIndex >= numClips) {
|
|
92
|
+
return JSON.stringify({
|
|
93
|
+
ok: false,
|
|
94
|
+
error: "clipIndex " + args.clipIndex + " is out of range — track " + args.trackIndex + " has " + numClips + " clip(s)"
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
var clip = track.clips[args.clipIndex];
|
|
99
|
+
var clipName = null;
|
|
100
|
+
try { clipName = clip.name; } catch (e) { clipName = null; }
|
|
101
|
+
|
|
102
|
+
var clipStartSeconds = 0;
|
|
103
|
+
try { clipStartSeconds = timeValueToSeconds(clip.start) || 0; } catch (e) { clipStartSeconds = 0; }
|
|
104
|
+
|
|
105
|
+
var levelProp = findVolumeLevelProperty(clip);
|
|
106
|
+
if (!levelProp) {
|
|
107
|
+
return JSON.stringify({ ok: false, error: "could not find Volume/Level property on clip — is this an audio clip?" });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
var setTimeVaryingError = null;
|
|
111
|
+
try {
|
|
112
|
+
levelProp.setTimeVarying(true);
|
|
113
|
+
} catch (e) {
|
|
114
|
+
setTimeVaryingError = e.toString();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
var results = [];
|
|
118
|
+
var succeeded = 0;
|
|
119
|
+
for (var i = 0; i < keyframes.length; i++) {
|
|
120
|
+
var seconds = keyframes[i].seconds;
|
|
121
|
+
var db = keyframes[i].db;
|
|
122
|
+
var linear = Math.pow(10, (db - 15) / 20);
|
|
123
|
+
if (linear < 0.0000001) {
|
|
124
|
+
linear = 0.0000001;
|
|
125
|
+
}
|
|
126
|
+
var sequenceSeconds = clipStartSeconds + seconds;
|
|
127
|
+
var ticksString = String(Math.round(sequenceSeconds * TICKS_PER_SECOND));
|
|
128
|
+
|
|
129
|
+
var entry = { seconds: seconds, db: db, linear: linear, sequenceSeconds: sequenceSeconds, addKeySuccess: false, setValueSuccess: false };
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
levelProp.addKey(ticksString);
|
|
133
|
+
entry.addKeySuccess = true;
|
|
134
|
+
} catch (e1) {
|
|
135
|
+
entry.addKeyError = e1.toString();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
levelProp.setValueAtKey(ticksString, linear, true);
|
|
140
|
+
entry.setValueSuccess = true;
|
|
141
|
+
} catch (e2) {
|
|
142
|
+
try {
|
|
143
|
+
levelProp.setValueAtTime(ticksString, linear);
|
|
144
|
+
entry.setValueSuccess = true;
|
|
145
|
+
entry.setValueMethod = "setValueAtTime";
|
|
146
|
+
} catch (e3) {
|
|
147
|
+
entry.setValueError = e2.toString() + " / " + e3.toString();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (entry.addKeySuccess && entry.setValueSuccess) {
|
|
152
|
+
succeeded++;
|
|
153
|
+
}
|
|
154
|
+
results.push(entry);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
var result = {
|
|
158
|
+
sequenceName: seq.name,
|
|
159
|
+
trackType: args.trackType,
|
|
160
|
+
trackIndex: args.trackIndex,
|
|
161
|
+
clipIndex: args.clipIndex,
|
|
162
|
+
clipName: clipName,
|
|
163
|
+
setTimeVaryingError: setTimeVaryingError,
|
|
164
|
+
keyframesRequested: keyframes.length,
|
|
165
|
+
keyframesSucceeded: succeeded,
|
|
166
|
+
keyframes: results,
|
|
167
|
+
calibrationNote: "dB->linear uses the reference tool's own UNCALIBRATED formula " +
|
|
168
|
+
"(10^(db/20), floored at 1e-7) — a DIFFERENT formula from set-clip-volume.jsx's " +
|
|
169
|
+
"hetpatel-calibrated one. Neither has been verified against this Premiere build."
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
return JSON.stringify({ ok: true, result: result });
|
|
173
|
+
} catch (e) {
|
|
174
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Command: add-custom-metadata-field → ppb_addCustomMetadataField
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context.
|
|
4
|
+
//
|
|
5
|
+
// Ported from leancoderkavy/premiere-pro-mcp's project.ts
|
|
6
|
+
// add_custom_metadata_field. Calls app.project.
|
|
7
|
+
// addPropertyToProjectMetadataSchema(name, label, type) per
|
|
8
|
+
// PREMIERE_API_NOTES.md's Markers/metadata/misc section. `type` is a raw
|
|
9
|
+
// int enum per the reference tool: 0 = Integer, 1 = Real, 2 = String,
|
|
10
|
+
// 3 = Boolean.
|
|
11
|
+
//
|
|
12
|
+
// NOTE (per this task's brief): this is PROJECT-WIDE schema mutation, not
|
|
13
|
+
// a per-item field — it adds a new column to every item's metadata in
|
|
14
|
+
// this project, and is NOT removable from script (no
|
|
15
|
+
// removePropertyFromProjectMetadataSchema-equivalent exists in any
|
|
16
|
+
// reference repo studied). There is no reliable read-back API for the
|
|
17
|
+
// metadata schema itself (get-project-panel-metadata reads the Project
|
|
18
|
+
// panel's column *display* configuration, not the schema), so
|
|
19
|
+
// verification here is call-level only (the call didn't throw) —
|
|
20
|
+
// documented honestly rather than a fabricated "verified" flag.
|
|
21
|
+
|
|
22
|
+
function ppb_addCustomMetadataField(argsJson) {
|
|
23
|
+
try {
|
|
24
|
+
var args;
|
|
25
|
+
try {
|
|
26
|
+
args = JSON.parse(argsJson);
|
|
27
|
+
} catch (e) {
|
|
28
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!args.name || typeof args.name !== "string") {
|
|
32
|
+
return JSON.stringify({ ok: false, error: "name is required" });
|
|
33
|
+
}
|
|
34
|
+
var label = (typeof args.label === "string" && args.label.length > 0) ? args.label : args.name;
|
|
35
|
+
var type = typeof args.type === "number" ? args.type : 2; // default: String
|
|
36
|
+
|
|
37
|
+
if (!app.project) {
|
|
38
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
39
|
+
}
|
|
40
|
+
if (typeof app.project.addPropertyToProjectMetadataSchema !== "function") {
|
|
41
|
+
return JSON.stringify({ ok: false, error: "addPropertyToProjectMetadataSchema is not available on this Premiere build" });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
app.project.addPropertyToProjectMetadataSchema(args.name, label, type);
|
|
46
|
+
} catch (e) {
|
|
47
|
+
return JSON.stringify({ ok: false, error: "addPropertyToProjectMetadataSchema() failed: " + e.toString() });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return JSON.stringify({
|
|
51
|
+
ok: true,
|
|
52
|
+
result: {
|
|
53
|
+
added: true,
|
|
54
|
+
name: args.name,
|
|
55
|
+
label: label,
|
|
56
|
+
type: type,
|
|
57
|
+
note: "project-wide metadata schema change — this field is added to every item's metadata in this project and cannot be removed from script (no reference repo we studied has a removal API); verification here is call-level only, no read-back API exists for the schema itself"
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
} catch (e) {
|
|
61
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
62
|
+
}
|
|
63
|
+
}
|