premiere-cli 0.3.0__tar.gz → 0.3.1__tar.gz
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-0.3.0/src/premiere_cli.egg-info → premiere_cli-0.3.1}/PKG-INFO +1 -1
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/pyproject.toml +1 -1
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/__init__.py +1 -1
- premiere_cli-0.3.1/src/premiere_cli/panel/host/commands/export-frame.jsx +257 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/js/main.js +1 -1
- {premiere_cli-0.3.0 → premiere_cli-0.3.1/src/premiere_cli.egg-info}/PKG-INFO +1 -1
- premiere_cli-0.3.0/src/premiere_cli/panel/host/commands/export-frame.jsx +0 -381
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/LICENSE +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/README.md +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/setup.cfg +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/cli.py +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/init_project.py +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/log.py +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/.debug +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/CSXS/manifest.xml +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/css/style.css +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/add-adjustment-layer.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/add-audio-keyframes.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/add-custom-metadata-field.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/add-keyframe.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/add-marker-to-project-item.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/add-marker.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/add-text-overlay.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/add-to-render-queue.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/add-to-timeline.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/add-track.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/add-transition.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/adjust-audio-levels.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/apply-audio-effect.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/apply-effect.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/apply-lut.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/attach-custom-property.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/auto-reframe-sequence.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/batch-add-transitions.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/batch-apply-effect.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/batch-rename-clips.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/batch-set-clips-enabled.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/clear-item-in-out.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/clear-sequence-in-out.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/close-all-source-clips.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/close-sequence.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/close-source-monitor.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/color-correct.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/copy-effect-values.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/copy-effects-between-clips.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/create-bars-and-tone.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/create-bin.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/create-caption-track.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/create-sequence-from-clips.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/create-sequence-from-preset.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/create-sequence.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/create-smart-bin.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/create-subclip.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/create-subsequence.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/debug-qe-inspect.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/debug-qe-try-mutate.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/delete-marker.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/deselect-all-clips.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/detach-proxy.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/duplicate-clip.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/duplicate-sequence.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/encode-file.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/encode-project-item.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/export-aaf.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/export-fcp-xml.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/export-omf.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/export-sequence-as-project.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/export-sequence.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/extract-audio-track.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/extract-selection.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/find-items-by-media-path.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/freeze-frame.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-active-sequence.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-all-project-paths.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-bin-contents.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-clip-adjustment-layer.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-clip-at-playhead.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-clip-at-position.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-clip-links.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-clip-markers.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-clip-speed.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-color-label.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-color-space.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-duplicate-media.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-effect-properties.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-encoder-presets.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-export-file-extension.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-footage-interpretation.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-full-clip-info.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-full-project-overview.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-full-sequence-info.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-graphics-white-luminance.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-insertion-bin.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-item-metadata.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-keyframes.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-mogrt-component.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-next-edit-point.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-offline-media.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-open-projects.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-premiere-state.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-project-info.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-project-item-info.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-project-panel-metadata.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-qe-clip-info.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-render-queue-status.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-sequence-count.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-sequence-in-out.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-sequence-markers-by-type.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-source-monitor-info.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-source-monitor-position.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-target-tracks.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-timeline-gaps.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-timeline-summary.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-total-clip-count.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-track-info.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-unused-media.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-used-media-report.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-value-at-time.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-version-info.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-work-area.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-workspaces.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/get-xmp-metadata.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/import-ae-comps.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/import-fcp-xml.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/import-folder.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/import-image-sequence.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/import-media.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/import-mogrt-from-library.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/import-mogrt.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/import-sequences-from-project.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/insert-from-source.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/inspect-dom-object.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/invert-selection.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/is-work-area-enabled.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/lift-selection.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/link-selection.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/list-available-audio-effects.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/list-available-audio-transitions.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/list-available-effects.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/list-available-transitions.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/list-markers.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/list-project-items.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/lock-track.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/manage-proxies.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/match-frame.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/move-clip-to-track.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/move-clip.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/move-items-to-bin.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/move-playhead-to-edit.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/move-playhead.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/nest-clips.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/open-in-source.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/open-project.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/overwrite-clip-at.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/overwrite-from-source.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/play-source-monitor.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/play-timeline.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/razor-all-tracks.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/redo.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/refresh-media.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/relink-media.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/remove-all-effects.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/remove-effect-by-name.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/remove-effect.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/remove-from-timeline.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/remove-keyframe-range.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/remove-keyframe.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/remove-selected-clips.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/remove-track-intervals.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/remove-transition.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/rename-bin.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/rename-clip.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/rename-project-item.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/rename-track.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/replace-clip-media.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/replace-clip.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/reverse-clip.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/ripple-delete-clip.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/roll-edit.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/save-project-as.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/save-project.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/scene-edit-detection.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/search-project-items.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/select-all-clips.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/select-clips-by-color.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/select-clips-by-name.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/select-clips-in-range.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/select-disabled-clips.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/select-project-item.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-active-project.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-active-sequence.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-all-tracks-targeted.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-anti-alias-quality.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-blend-mode.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-clip-anchor-point.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-clip-enabled.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-clip-opacity.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-clip-pan.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-clip-position.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-clip-properties.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-clip-rotation.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-clip-scale.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-clip-selection.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-clip-speed.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-clip-volume.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-color-label.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-color-value.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-effect-property.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-footage-interpretation.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-frame-blend.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-graphics-white-luminance.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-item-in-out.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-item-metadata.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-item-offline.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-item-start-time.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-keyframe-interpolation.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-override-frame-rate.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-override-pixel-aspect-ratio.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-poster-frame.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-project-panel-metadata.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-scale-to-frame-size.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-scale-width-height.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-sequence-in-out.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-sequence-settings.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-source-in-out.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-target-track.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-time-interpolation.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-track-mute.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-track-visibility.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-transcode-on-ingest.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-uniform-scale.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-work-area.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-workspace.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/set-xmp-metadata.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/slide-edit.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/slip-edit.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/split-clip.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/stabilize-clip.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/stop-playback.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/trim-clip.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/undo.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/unlink-selection.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/unnest-sequence.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/commands/update-marker.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/index.jsx +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/host/presets/default-4k-25fps.sqpreset +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/index.html +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel/js/cs-interface.js +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/panel_install.py +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/templates/empty-project/Adobe Premiere Pro Auto-Save/Untitled--8627e8e5-eccf-e7ea-8c87-b4de7f17596a-2026-07-10_12-30-47.prproj +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli/templates/empty-project/Untitled.prproj +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli.egg-info/SOURCES.txt +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli.egg-info/dependency_links.txt +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli.egg-info/entry_points.txt +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli.egg-info/requires.txt +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/src/premiere_cli.egg-info/top_level.txt +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/tests/test_cli.py +0 -0
- {premiere_cli-0.3.0 → premiere_cli-0.3.1}/tests/test_log.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: premiere-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Drive Adobe Premiere Pro from the command line: a Python CLI plus a bundled CEP bridge panel exposing Premiere's scripting APIs over local HTTP
|
|
5
5
|
License: CC-BY-SA-4.0
|
|
6
6
|
Project-URL: Repository, https://github.com/stefanwebb/premiere-cli
|
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
|
6
6
|
name = "premiere-cli"
|
|
7
7
|
# Keep in lockstep with premiere_cli.__version__ and PANEL_VERSION in
|
|
8
8
|
# src/premiere_cli/panel/js/main.js.
|
|
9
|
-
version = "0.3.
|
|
9
|
+
version = "0.3.1"
|
|
10
10
|
description = "Drive Adobe Premiere Pro from the command line: a Python CLI plus a bundled CEP bridge panel exposing Premiere's scripting APIs over local HTTP"
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
license = {text = "CC-BY-SA-4.0"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// Command: export-frame → ppb_exportFrame
|
|
2
|
+
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
+
// same global ExtendScript context — shared helpers (findSequenceByName,
|
|
4
|
+
// findBundledPresetByRelativePath, trySetSequenceRange, getSequenceFps,
|
|
5
|
+
// timecodeToSeconds, ...) are already defined there.
|
|
6
|
+
|
|
7
|
+
// A bundled still-image preset for the AME single-frame export below —
|
|
8
|
+
// confirmed present on this machine's Premiere Pro 2026 install at this
|
|
9
|
+
// relative path; re-verify after a Premiere version upgrade, same caveat
|
|
10
|
+
// as extract-audio-track's FORMAT_PRESET_RELATIVE_PATHS. "Match Source"
|
|
11
|
+
// means the preset inherits the sequence's own frame size, so no
|
|
12
|
+
// width/height override is needed when using it.
|
|
13
|
+
var STILL_IMAGE_PRESET_RELATIVE_PATH =
|
|
14
|
+
"Contents/MediaIO/systempresets/3F3F3F3F_504E4720/PNG Sequence (Match Source).epr";
|
|
15
|
+
|
|
16
|
+
// Premiere treats a still-image preset as a one-frame image *sequence*,
|
|
17
|
+
// appending a frame number to the base name ("frame.png" → "frame0.png",
|
|
18
|
+
// confirmed live; padding may vary by preset/duration). Finds whichever
|
|
19
|
+
// variant was actually written and renames it to the exact requested path
|
|
20
|
+
// so callers reliably get the file where they asked for it.
|
|
21
|
+
//
|
|
22
|
+
// Known variants are checked DIRECTLY by path, not found via a directory
|
|
23
|
+
// scan: enumerating the parent directory returns an empty list on this
|
|
24
|
+
// machine for some directories (e.g. /tmp — same macOS TCC/sandboxing
|
|
25
|
+
// behavior already documented for /Applications in
|
|
26
|
+
// findBundledPresetByRelativePath's notes in host/index.jsx) even though
|
|
27
|
+
// the files themselves are readable at their exact paths. A directory
|
|
28
|
+
// scan runs only as a last resort, for variant names not in the known
|
|
29
|
+
// list.
|
|
30
|
+
function locateAndNormalizeExportedFrame(outputPath) {
|
|
31
|
+
var exact = new File(outputPath);
|
|
32
|
+
if (exact.exists && exact.length > 0) {
|
|
33
|
+
return exact;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
var fullName = decodeURI(exact.name);
|
|
37
|
+
var dot = fullName.lastIndexOf(".");
|
|
38
|
+
var base = dot === -1 ? fullName : fullName.substring(0, dot);
|
|
39
|
+
var ext = dot === -1 ? "" : fullName.substring(dot);
|
|
40
|
+
var parentPath = exact.path;
|
|
41
|
+
|
|
42
|
+
function normalize(produced) {
|
|
43
|
+
if (produced.length <= 0) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
if (produced.fsName !== exact.fsName) {
|
|
48
|
+
produced.rename(fullName);
|
|
49
|
+
}
|
|
50
|
+
} catch (e) {
|
|
51
|
+
// rename best-effort — still report the file under whatever name it has
|
|
52
|
+
return produced;
|
|
53
|
+
}
|
|
54
|
+
return exact.exists ? exact : produced;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
var knownVariants = [
|
|
58
|
+
parentPath + "/" + base + "0" + ext, // AME frame-number suffix
|
|
59
|
+
parentPath + "/" + base + "00" + ext,
|
|
60
|
+
parentPath + "/" + base + "000" + ext,
|
|
61
|
+
parentPath + "/" + base + "0000" + ext
|
|
62
|
+
];
|
|
63
|
+
for (var v = 0; v < knownVariants.length; v++) {
|
|
64
|
+
var candidate = new File(knownVariants[v]);
|
|
65
|
+
if (candidate.exists && candidate.length > 0) {
|
|
66
|
+
return normalize(candidate);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Last resort: scan the parent directory (returns nothing at all in
|
|
71
|
+
// enumeration-blocked directories — see comment above).
|
|
72
|
+
var dir = exact.parent;
|
|
73
|
+
if (!dir || !dir.exists) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
var matches = dir.getFiles(function (item) {
|
|
78
|
+
if (item instanceof Folder) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
var name = decodeURI(item.name);
|
|
82
|
+
if (name.indexOf(base) !== 0) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
var lowerExt = ext.toLowerCase();
|
|
86
|
+
return lowerExt === "" || name.toLowerCase().substring(name.length - lowerExt.length) === lowerExt;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
if (!matches || matches.length === 0) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return normalize(matches[0]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Exports a single frame of a sequence, at a given timecode, to a PNG file.
|
|
97
|
+
//
|
|
98
|
+
// qe.project.getActiveSequence().exportFramePNG was tried first in an
|
|
99
|
+
// earlier version of this command (guessing at its version-dependent arg
|
|
100
|
+
// order per PREMIERE_API_NOTES.md), judging success only by whether a file
|
|
101
|
+
// was produced. That check is NOT sufficient: confirmed live 2026-07-20
|
|
102
|
+
// that on this Premiere build, exportFramePNG ignores its position
|
|
103
|
+
// argument in every arg-order variant tried (ticksString, Time object,
|
|
104
|
+
// output-path-as-position, ticks-then-path, path-then-ticks) and always
|
|
105
|
+
// exports whatever frame is currently rendered in the Program Monitor,
|
|
106
|
+
// regardless of the requested timecode — while still writing a real file
|
|
107
|
+
// and returning normally, so the file-existence check reported false
|
|
108
|
+
// positives. Two exports requested 30 seconds apart came back
|
|
109
|
+
// pixel-identical. Neither seq.setPlayerPosition() (standard DOM) nor
|
|
110
|
+
// qeSequence.setCTI() (QE DOM) changed this.
|
|
111
|
+
//
|
|
112
|
+
// This command now exports exclusively via Adobe Media Encoder's
|
|
113
|
+
// exportAsMediaDirect() — the same documented, blocking mechanism
|
|
114
|
+
// ppb_extractAudioTrack already uses successfully — narrowing the
|
|
115
|
+
// sequence's in/out points to exactly one frame around the target
|
|
116
|
+
// timecode. Confirmed live to produce genuinely different, timecode-
|
|
117
|
+
// correct frames (verified via pixel diff, not just file existence).
|
|
118
|
+
function ppb_exportFrame(argsJson) {
|
|
119
|
+
try {
|
|
120
|
+
var args;
|
|
121
|
+
try {
|
|
122
|
+
args = JSON.parse(argsJson);
|
|
123
|
+
} catch (e) {
|
|
124
|
+
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!args.outputPath || typeof args.outputPath !== "string") {
|
|
128
|
+
return JSON.stringify({ ok: false, error: "outputPath is required" });
|
|
129
|
+
}
|
|
130
|
+
var timecodeRe = /^\d{2,3}:\d{2}:\d{2}$/;
|
|
131
|
+
if (!args.timecode || typeof args.timecode !== "string" || !timecodeRe.test(args.timecode)) {
|
|
132
|
+
return JSON.stringify({ ok: false, error: "timecode must be a \"MM:SS:FF\" string" });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (!app.project) {
|
|
136
|
+
return JSON.stringify({ ok: false, error: "no project open" });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
var seq = null;
|
|
140
|
+
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
141
|
+
seq = findSequenceByName(args.sequenceName);
|
|
142
|
+
if (!seq) {
|
|
143
|
+
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
seq = app.project.activeSequence;
|
|
147
|
+
if (!seq) {
|
|
148
|
+
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (app.project.activeSequence !== seq) {
|
|
153
|
+
app.project.activeSequence = seq;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
var fps = getSequenceFps(seq);
|
|
157
|
+
var timeSeconds = timecodeToSeconds(args.timecode, fps);
|
|
158
|
+
|
|
159
|
+
var width = null;
|
|
160
|
+
var height = null;
|
|
161
|
+
try {
|
|
162
|
+
var settings = seq.getSettings();
|
|
163
|
+
width = settings.videoFrameWidth;
|
|
164
|
+
height = settings.videoFrameHeight;
|
|
165
|
+
} catch (e) {
|
|
166
|
+
// best-effort only — reported in the result, not required for export
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
var result = {
|
|
170
|
+
sequenceName: seq.name,
|
|
171
|
+
timecode: args.timecode,
|
|
172
|
+
timeSeconds: timeSeconds,
|
|
173
|
+
outputPath: args.outputPath,
|
|
174
|
+
width: width,
|
|
175
|
+
height: height
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// Clear any stale leftover from an earlier failed run — the exact
|
|
179
|
+
// requested path plus every known frame-numbered variant Premiere
|
|
180
|
+
// might write it under (see locateAndNormalizeExportedFrame) — so a
|
|
181
|
+
// leftover file's mere existence can't be mistaken for this run's
|
|
182
|
+
// output.
|
|
183
|
+
for (var staleRound = 0; staleRound < 8; staleRound++) {
|
|
184
|
+
var stale = locateAndNormalizeExportedFrame(args.outputPath);
|
|
185
|
+
if (stale === null) {
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
stale.remove();
|
|
190
|
+
} catch (e) {
|
|
191
|
+
// best-effort — a failed cleanup doesn't block the export attempt
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
var amePresetPath = findBundledPresetByRelativePath(STILL_IMAGE_PRESET_RELATIVE_PATH);
|
|
197
|
+
if (!amePresetPath) {
|
|
198
|
+
return JSON.stringify({
|
|
199
|
+
ok: false,
|
|
200
|
+
error: "no bundled still-image preset found for the Media Encoder export"
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
var originalInPoint = null;
|
|
205
|
+
var originalOutPoint = null;
|
|
206
|
+
try {
|
|
207
|
+
originalInPoint = seq.getInPoint();
|
|
208
|
+
originalOutPoint = seq.getOutPoint();
|
|
209
|
+
} catch (e) {
|
|
210
|
+
// best-effort only — if these can't be read, we simply won't restore them
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
var frameDurationSeconds = 1 / fps;
|
|
214
|
+
var ameProducedFile = null;
|
|
215
|
+
var ameError = null;
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
var rangeOutcome = trySetSequenceRange(seq, timeSeconds, timeSeconds + frameDurationSeconds);
|
|
219
|
+
if (!rangeOutcome.ok) {
|
|
220
|
+
ameError = "could not set sequence in/out points with any known argument form (seconds, ticks string, Time object)";
|
|
221
|
+
} else {
|
|
222
|
+
try {
|
|
223
|
+
seq.exportAsMediaDirect(args.outputPath, amePresetPath, 1 /* ENCODE_IN_TO_OUT */);
|
|
224
|
+
} catch (e) {
|
|
225
|
+
ameError = "exportAsMediaDirect failed: " + e.toString();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
} finally {
|
|
229
|
+
if (originalInPoint !== null && originalOutPoint !== null) {
|
|
230
|
+
try {
|
|
231
|
+
trySetSequenceRange(seq, originalInPoint.seconds, originalOutPoint.seconds);
|
|
232
|
+
} catch (e) {
|
|
233
|
+
// best-effort
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (ameError === null) {
|
|
239
|
+
ameProducedFile = locateAndNormalizeExportedFrame(args.outputPath);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (ameProducedFile === null) {
|
|
243
|
+
return JSON.stringify({
|
|
244
|
+
ok: false,
|
|
245
|
+
error: "Media Encoder export failed" + (ameError ? ": " + ameError : " (no file produced)")
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
result.method = "ame";
|
|
250
|
+
result.presetPath = amePresetPath;
|
|
251
|
+
result.fileSizeBytes = ameProducedFile.length;
|
|
252
|
+
|
|
253
|
+
return JSON.stringify({ ok: true, result: result });
|
|
254
|
+
} catch (e) {
|
|
255
|
+
return JSON.stringify({ ok: false, error: e.toString() });
|
|
256
|
+
}
|
|
257
|
+
}
|
|
@@ -5,7 +5,7 @@ const PORT = 47823;
|
|
|
5
5
|
// Kept in lockstep with the premiere-cli Python package version —
|
|
6
6
|
// `premiere-cli doctor` compares the two and warns when the installed
|
|
7
7
|
// panel is stale relative to the CLI that ships it.
|
|
8
|
-
const PANEL_VERSION = '0.3.
|
|
8
|
+
const PANEL_VERSION = '0.3.1';
|
|
9
9
|
const VALID_LEVELS = ['info', 'warn', 'error'];
|
|
10
10
|
|
|
11
11
|
// main.js is loaded via a plain <script src="js/main.js"> tag, not
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: premiere-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Drive Adobe Premiere Pro from the command line: a Python CLI plus a bundled CEP bridge panel exposing Premiere's scripting APIs over local HTTP
|
|
5
5
|
License: CC-BY-SA-4.0
|
|
6
6
|
Project-URL: Repository, https://github.com/stefanwebb/premiere-cli
|
|
@@ -1,381 +0,0 @@
|
|
|
1
|
-
// Command: export-frame → ppb_exportFrame
|
|
2
|
-
// Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
|
|
3
|
-
// same global ExtendScript context — shared helpers (ensureQEEnabled,
|
|
4
|
-
// findSequenceByName, findBundledPresetByRelativePath, trySetSequenceRange,
|
|
5
|
-
// getSequenceFps, timecodeToSeconds, ...) are already defined there.
|
|
6
|
-
|
|
7
|
-
// A bundled still-image preset for the ppb_exportFrame AME fallback (see
|
|
8
|
-
// below) — confirmed present on this machine's Premiere Pro 2026 install
|
|
9
|
-
// at this relative path; re-verify after a Premiere version upgrade, same
|
|
10
|
-
// caveat as extract-audio-track's FORMAT_PRESET_RELATIVE_PATHS. "Match
|
|
11
|
-
// Source" means the preset inherits the sequence's own frame size, so no
|
|
12
|
-
// width/height override is needed when using it.
|
|
13
|
-
var STILL_IMAGE_PRESET_RELATIVE_PATH =
|
|
14
|
-
"Contents/MediaIO/systempresets/3F3F3F3F_504E4720/PNG Sequence (Match Source).epr";
|
|
15
|
-
|
|
16
|
-
// The QE exportFramePNG call (see ppb_exportFrame) and the AME
|
|
17
|
-
// image-sequence export below can both write under a name other than the
|
|
18
|
-
// exact path requested — QE appends ".png" even to an already-.png-
|
|
19
|
-
// suffixed path ("frame.png" → "frame.png.png", confirmed live), and
|
|
20
|
-
// Premiere treats a still-image preset as a one-frame image *sequence*,
|
|
21
|
-
// appending a frame number to the base name ("frame.png" → "frame0.png",
|
|
22
|
-
// confirmed live; padding may vary by preset/duration). Finds whichever
|
|
23
|
-
// variant was actually written and renames it to the exact requested
|
|
24
|
-
// path so callers reliably get the file where they asked for it.
|
|
25
|
-
//
|
|
26
|
-
// Known variants are checked DIRECTLY by path, not found via a directory
|
|
27
|
-
// scan: enumerating the parent directory returns an empty list on this
|
|
28
|
-
// machine for some directories (e.g. /tmp — same macOS TCC/sandboxing
|
|
29
|
-
// behavior already documented for /Applications in
|
|
30
|
-
// findBundledPresetByRelativePath's notes in host/index.jsx) even though
|
|
31
|
-
// the files themselves are readable at their exact paths. A directory
|
|
32
|
-
// scan runs only as a last resort, for variant names not in the known
|
|
33
|
-
// list.
|
|
34
|
-
function locateAndNormalizeExportedFrame(outputPath) {
|
|
35
|
-
var exact = new File(outputPath);
|
|
36
|
-
if (exact.exists && exact.length > 0) {
|
|
37
|
-
return exact;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
var fullName = decodeURI(exact.name);
|
|
41
|
-
var dot = fullName.lastIndexOf(".");
|
|
42
|
-
var base = dot === -1 ? fullName : fullName.substring(0, dot);
|
|
43
|
-
var ext = dot === -1 ? "" : fullName.substring(dot);
|
|
44
|
-
var parentPath = exact.path;
|
|
45
|
-
|
|
46
|
-
function normalize(produced) {
|
|
47
|
-
if (produced.length <= 0) {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
try {
|
|
51
|
-
if (produced.fsName !== exact.fsName) {
|
|
52
|
-
produced.rename(fullName);
|
|
53
|
-
}
|
|
54
|
-
} catch (e) {
|
|
55
|
-
// rename best-effort — still report the file under whatever name it has
|
|
56
|
-
return produced;
|
|
57
|
-
}
|
|
58
|
-
return exact.exists ? exact : produced;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
var knownVariants = [
|
|
62
|
-
outputPath + ".png", // QE double-extension quirk
|
|
63
|
-
parentPath + "/" + base + "0" + ext, // AME frame-number suffix
|
|
64
|
-
parentPath + "/" + base + "00" + ext,
|
|
65
|
-
parentPath + "/" + base + "000" + ext,
|
|
66
|
-
parentPath + "/" + base + "0000" + ext
|
|
67
|
-
];
|
|
68
|
-
for (var v = 0; v < knownVariants.length; v++) {
|
|
69
|
-
var candidate = new File(knownVariants[v]);
|
|
70
|
-
if (candidate.exists && candidate.length > 0) {
|
|
71
|
-
return normalize(candidate);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Last resort: scan the parent directory (returns nothing at all in
|
|
76
|
-
// enumeration-blocked directories — see comment above).
|
|
77
|
-
var dir = exact.parent;
|
|
78
|
-
if (!dir || !dir.exists) {
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
var matches = dir.getFiles(function (item) {
|
|
83
|
-
if (item instanceof Folder) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
var name = decodeURI(item.name);
|
|
87
|
-
if (name.indexOf(base) !== 0) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
var lowerExt = ext.toLowerCase();
|
|
91
|
-
return lowerExt === "" || name.toLowerCase().substring(name.length - lowerExt.length) === lowerExt;
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
if (!matches || matches.length === 0) {
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return normalize(matches[0]);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Exports a single frame of a sequence, at a given timecode, to a PNG file.
|
|
102
|
-
// qeSeq.exportFramePNG's argument order is version-dependent (per
|
|
103
|
-
// PREMIERE_API_NOTES.md) and can silently write nothing on some builds —
|
|
104
|
-
// this brute-forces a short list of plausible signatures and judges success
|
|
105
|
-
// only by checking the filesystem for a real output file afterward, never
|
|
106
|
-
// by trusting the call's own return value (same pattern as
|
|
107
|
-
// remove-track-intervals' rippleDelete()/remove() guessing).
|
|
108
|
-
function ppb_exportFrame(argsJson) {
|
|
109
|
-
try {
|
|
110
|
-
var args;
|
|
111
|
-
try {
|
|
112
|
-
args = JSON.parse(argsJson);
|
|
113
|
-
} catch (e) {
|
|
114
|
-
return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (!args.outputPath || typeof args.outputPath !== "string") {
|
|
118
|
-
return JSON.stringify({ ok: false, error: "outputPath is required" });
|
|
119
|
-
}
|
|
120
|
-
var timecodeRe = /^\d{2,3}:\d{2}:\d{2}$/;
|
|
121
|
-
if (!args.timecode || typeof args.timecode !== "string" || !timecodeRe.test(args.timecode)) {
|
|
122
|
-
return JSON.stringify({ ok: false, error: "timecode must be a \"MM:SS:FF\" string" });
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (!app.project) {
|
|
126
|
-
return JSON.stringify({ ok: false, error: "no project open" });
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
var seq = null;
|
|
130
|
-
if (args.sequenceName && typeof args.sequenceName === "string") {
|
|
131
|
-
seq = findSequenceByName(args.sequenceName);
|
|
132
|
-
if (!seq) {
|
|
133
|
-
return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
|
|
134
|
-
}
|
|
135
|
-
} else {
|
|
136
|
-
seq = app.project.activeSequence;
|
|
137
|
-
if (!seq) {
|
|
138
|
-
return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// QE DOM only ever operates on the active sequence tab — switch to it
|
|
143
|
-
// rather than erroring if the resolved sequence isn't already active
|
|
144
|
-
// (same approach as ppb_removeTrackIntervals).
|
|
145
|
-
if (app.project.activeSequence !== seq) {
|
|
146
|
-
app.project.activeSequence = seq;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
ensureQEEnabled();
|
|
151
|
-
} catch (e) {
|
|
152
|
-
return JSON.stringify({ ok: false, error: "app.enableQE() failed: " + e.toString() });
|
|
153
|
-
}
|
|
154
|
-
if (typeof qe === "undefined" || !qe.project) {
|
|
155
|
-
return JSON.stringify({ ok: false, error: "QE DOM not available after enableQE()" });
|
|
156
|
-
}
|
|
157
|
-
var qeSequence = qe.project.getActiveSequence();
|
|
158
|
-
if (!qeSequence) {
|
|
159
|
-
return JSON.stringify({ ok: false, error: "qe.project.getActiveSequence() returned nothing after activating the sequence" });
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
var fps = getSequenceFps(seq);
|
|
163
|
-
var timeSeconds = timecodeToSeconds(args.timecode, fps);
|
|
164
|
-
|
|
165
|
-
var width = null;
|
|
166
|
-
var height = null;
|
|
167
|
-
try {
|
|
168
|
-
var settings = seq.getSettings();
|
|
169
|
-
width = settings.videoFrameWidth;
|
|
170
|
-
height = settings.videoFrameHeight;
|
|
171
|
-
} catch (e) {
|
|
172
|
-
// best-effort only — width/height-based attempts below are simply skipped if unreadable
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// --- Snapshot playhead position, to restore afterward regardless of outcome ---
|
|
176
|
-
var originalPosition = null;
|
|
177
|
-
try {
|
|
178
|
-
originalPosition = seq.getPlayerPosition();
|
|
179
|
-
} catch (e) {
|
|
180
|
-
originalPosition = null;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
var positionAttempts = [];
|
|
184
|
-
var ticksString = String(Math.round(timeSeconds * TICKS_PER_SECOND));
|
|
185
|
-
var timeObj = null;
|
|
186
|
-
try {
|
|
187
|
-
timeObj = new Time();
|
|
188
|
-
timeObj.seconds = timeSeconds;
|
|
189
|
-
} catch (e) {
|
|
190
|
-
timeObj = null;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
var positionSet = false;
|
|
194
|
-
try {
|
|
195
|
-
seq.setPlayerPosition(ticksString);
|
|
196
|
-
positionAttempts.push({ form: "ticksString", success: true });
|
|
197
|
-
positionSet = true;
|
|
198
|
-
} catch (e) {
|
|
199
|
-
positionAttempts.push({ form: "ticksString", success: false, error: e.toString() });
|
|
200
|
-
}
|
|
201
|
-
if (!positionSet && timeObj !== null) {
|
|
202
|
-
try {
|
|
203
|
-
seq.setPlayerPosition(timeObj);
|
|
204
|
-
positionAttempts.push({ form: "TimeObject", success: true });
|
|
205
|
-
positionSet = true;
|
|
206
|
-
} catch (e) {
|
|
207
|
-
positionAttempts.push({ form: "TimeObject", success: false, error: e.toString() });
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
var result = {
|
|
212
|
-
sequenceName: seq.name,
|
|
213
|
-
timecode: args.timecode,
|
|
214
|
-
timeSeconds: timeSeconds,
|
|
215
|
-
outputPath: args.outputPath,
|
|
216
|
-
width: width,
|
|
217
|
-
height: height
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
try {
|
|
221
|
-
if (!positionSet) {
|
|
222
|
-
return JSON.stringify({
|
|
223
|
-
ok: false,
|
|
224
|
-
error: "could not move the playhead to the requested timecode with any known argument form (ticks string, Time object)",
|
|
225
|
-
attempts: positionAttempts
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// Clear any stale leftovers from an earlier failed run — the exact
|
|
230
|
-
// requested path plus every known name variant Premiere might have
|
|
231
|
-
// written it under (see locateAndNormalizeExportedFrame) — so a
|
|
232
|
-
// leftover file's mere existence can't be mistaken for this run's
|
|
233
|
-
// output. Loops because multiple variants can coexist (e.g. one QE
|
|
234
|
-
// double-extension file AND one AME frame-numbered file).
|
|
235
|
-
for (var staleRound = 0; staleRound < 8; staleRound++) {
|
|
236
|
-
var stale = locateAndNormalizeExportedFrame(args.outputPath);
|
|
237
|
-
if (stale === null) {
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
try {
|
|
241
|
-
stale.remove();
|
|
242
|
-
} catch (e) {
|
|
243
|
-
// best-effort — a failed cleanup doesn't block the export attempt
|
|
244
|
-
break;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// --- Path 1: QE DOM's exportFramePNG. Version-inconsistent arg
|
|
249
|
-
// order (per PREMIERE_API_NOTES.md) and confirmed live to sometimes
|
|
250
|
-
// return false / write nothing regardless of a syntactically
|
|
251
|
-
// correct call — verify by scanning the filesystem afterward, never
|
|
252
|
-
// by trusting the call's return value.
|
|
253
|
-
var guesses = [];
|
|
254
|
-
guesses.push({ args: [args.outputPath], call: [args.outputPath] });
|
|
255
|
-
if (width !== null && height !== null) {
|
|
256
|
-
guesses.push({ args: [args.outputPath, String(width), String(height)], call: [args.outputPath, String(width), String(height)] });
|
|
257
|
-
}
|
|
258
|
-
// Confirmed live on this Premiere build: passing the output path as
|
|
259
|
-
// BOTH arguments succeeds where sensible width/height strings do
|
|
260
|
-
// not — an undocumented quirk of this exportFramePNG build, kept as
|
|
261
|
-
// a guess rather than relied on, since other builds may differ.
|
|
262
|
-
guesses.push({ args: [args.outputPath, args.outputPath], call: [args.outputPath, args.outputPath] });
|
|
263
|
-
if (timeObj !== null) {
|
|
264
|
-
guesses.push({ args: ["<Time seconds=" + timeSeconds + ">", args.outputPath], call: [timeObj, args.outputPath] });
|
|
265
|
-
}
|
|
266
|
-
guesses.push({ args: [ticksString, args.outputPath], call: [ticksString, args.outputPath] });
|
|
267
|
-
|
|
268
|
-
var attempts = [];
|
|
269
|
-
var succeededWithArgs = null;
|
|
270
|
-
var qeProducedFile = null;
|
|
271
|
-
|
|
272
|
-
for (var g = 0; g < guesses.length && succeededWithArgs === null; g++) {
|
|
273
|
-
var guess = guesses[g];
|
|
274
|
-
try {
|
|
275
|
-
qeSequence.exportFramePNG.apply(qeSequence, guess.call);
|
|
276
|
-
} catch (e) {
|
|
277
|
-
attempts.push({ args: guess.args, success: false, error: e.toString() });
|
|
278
|
-
continue;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
var producedFile = locateAndNormalizeExportedFrame(args.outputPath);
|
|
282
|
-
if (producedFile !== null) {
|
|
283
|
-
attempts.push({ args: guess.args, success: true });
|
|
284
|
-
succeededWithArgs = guess.args;
|
|
285
|
-
qeProducedFile = producedFile;
|
|
286
|
-
} else {
|
|
287
|
-
attempts.push({ args: guess.args, success: false, error: "no file produced" });
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
if (succeededWithArgs !== null) {
|
|
292
|
-
result.method = "qe";
|
|
293
|
-
result.attempts = attempts;
|
|
294
|
-
result.succeededWithArgs = succeededWithArgs;
|
|
295
|
-
result.fileSizeBytes = qeProducedFile.length;
|
|
296
|
-
return JSON.stringify({ ok: true, result: result });
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// --- Path 2: every QE guess failed — fall back to a one-frame
|
|
300
|
-
// export through Adobe Media Encoder via the standard DOM's
|
|
301
|
-
// exportAsMediaDirect(), the same documented, blocking mechanism
|
|
302
|
-
// ppb_extractAudioTrack already uses successfully. Narrows the
|
|
303
|
-
// sequence's in/out points to exactly one frame (using the
|
|
304
|
-
// sequence's own frame duration, seq.timebase) around the target
|
|
305
|
-
// timecode, then restores the original in/out points afterward.
|
|
306
|
-
var amePresetPath = findBundledPresetByRelativePath(STILL_IMAGE_PRESET_RELATIVE_PATH);
|
|
307
|
-
if (!amePresetPath) {
|
|
308
|
-
return JSON.stringify({
|
|
309
|
-
ok: false,
|
|
310
|
-
error: "exportFramePNG failed with all known arg-order variants, and no bundled still-image preset was found for the Media Encoder fallback",
|
|
311
|
-
attempts: attempts
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
var originalInPoint = null;
|
|
316
|
-
var originalOutPoint = null;
|
|
317
|
-
try {
|
|
318
|
-
originalInPoint = seq.getInPoint();
|
|
319
|
-
originalOutPoint = seq.getOutPoint();
|
|
320
|
-
} catch (e) {
|
|
321
|
-
// best-effort only — if these can't be read, we simply won't restore them
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
var frameDurationSeconds = 1 / fps;
|
|
325
|
-
var ameProducedFile = null;
|
|
326
|
-
var ameError = null;
|
|
327
|
-
|
|
328
|
-
try {
|
|
329
|
-
var rangeOutcome = trySetSequenceRange(seq, timeSeconds, timeSeconds + frameDurationSeconds);
|
|
330
|
-
if (!rangeOutcome.ok) {
|
|
331
|
-
ameError = "could not set sequence in/out points with any known argument form (seconds, ticks string, Time object)";
|
|
332
|
-
} else {
|
|
333
|
-
try {
|
|
334
|
-
seq.exportAsMediaDirect(args.outputPath, amePresetPath, 1 /* ENCODE_IN_TO_OUT */);
|
|
335
|
-
} catch (e) {
|
|
336
|
-
ameError = "exportAsMediaDirect failed: " + e.toString();
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
} finally {
|
|
340
|
-
if (originalInPoint !== null && originalOutPoint !== null) {
|
|
341
|
-
try {
|
|
342
|
-
trySetSequenceRange(seq, originalInPoint.seconds, originalOutPoint.seconds);
|
|
343
|
-
} catch (e) {
|
|
344
|
-
// best-effort
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
if (ameError === null) {
|
|
350
|
-
ameProducedFile = locateAndNormalizeExportedFrame(args.outputPath);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (ameProducedFile === null) {
|
|
354
|
-
return JSON.stringify({
|
|
355
|
-
ok: false,
|
|
356
|
-
error: "exportFramePNG failed with all known arg-order variants, and the Media Encoder fallback also failed" +
|
|
357
|
-
(ameError ? ": " + ameError : " (no file produced)"),
|
|
358
|
-
attempts: attempts
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
result.method = "ame";
|
|
363
|
-
result.attempts = attempts;
|
|
364
|
-
result.presetPath = amePresetPath;
|
|
365
|
-
result.fileSizeBytes = ameProducedFile.length;
|
|
366
|
-
|
|
367
|
-
return JSON.stringify({ ok: true, result: result });
|
|
368
|
-
} finally {
|
|
369
|
-
// Always restore the original playhead position, even if export threw.
|
|
370
|
-
if (originalPosition !== null) {
|
|
371
|
-
try {
|
|
372
|
-
seq.setPlayerPosition(originalPosition.ticks);
|
|
373
|
-
} catch (e) {
|
|
374
|
-
// best-effort — restoration failure doesn't change the command's outcome
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
} catch (e) {
|
|
379
|
-
return JSON.stringify({ ok: false, error: e.toString() });
|
|
380
|
-
}
|
|
381
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|