Skip to content

Latest commit

 

History

History
1892 lines (1522 loc) · 59.5 KB

File metadata and controls

1892 lines (1522 loc) · 59.5 KB

Adobe Premiere Pro ExtendScript — Comprehensive Reference

Source: Fetched March 2026 from official Adobe/community resources Primary docs: https://ppro-scripting.docsforadobe.dev/ Primary code sample: https://github.com/Adobe-CEP/Samples/tree/master/PProPanel


IMPORTANT: Platform Status (March 2026)

As of November 2025, Adobe has transitioned Premiere Pro to UXP (Unified Extensibility Platform) for new integrations. ExtendScript-based integrations remain supported through September 2026 but no further changes or improvements to the ExtendScript API are planned.

  • New development: use UXP — https://developer.adobe.com/premiere-pro/uxp/ppro_reference/
  • Existing ExtendScript workflows: fully functional until Sep 2026
  • Recommended IDE: VS Code with Adobe's ExtendScript debugging extension (not the old ESTK)
  • Recommended execution: from within CEP panels (not command-line)

1. CONSTANTS & ENUMERATIONS

// Time Display Types (for sequence.videoDisplayFormat / audioDisplayFormat)
var TIMEDISPLAY_24Timecode              = 100;
var TIMEDISPLAY_25Timecode              = 101;
var TIMEDISPLAY_2997DropTimecode        = 102;
var TIMEDISPLAY_2997NonDropTimecode     = 103;
var TIMEDISPLAY_30Timecode              = 104;
var TIMEDISPLAY_50Timecode              = 105;
var TIMEDISPLAY_5994DropTimecode        = 106;
var TIMEDISPLAY_5994NonDropTimecode     = 107;
var TIMEDISPLAY_60Timecode              = 108;
var TIMEDISPLAY_Frames                  = 109;
var TIMEDISPLAY_23976Timecode           = 110;
var TIMEDISPLAY_16mmFeetFrames          = 111;
var TIMEDISPLAY_35mmFeetFrames          = 112;
var TIMEDISPLAY_48Timecode              = 113;
var TIMEDISPLAY_AudioSamplesTimecode    = 200;
var TIMEDISPLAY_AudioMsTimecode         = 201;

// Keyframe Interpolation Modes
var KF_Interp_Mode_Linear   = 0;
var KF_Interp_Mode_Hold     = 4;
var KF_Interp_Mode_Bezier   = 5;
var KF_Interp_Mode_Time     = 6;

// Field Type Constants
var FIELDTYPE_Progressive   = 0;
var FIELDTYPE_UpperFirst    = 1;
var FIELDTYPE_LowerFirst    = 2;

// Audio Channel Types
var AUDIOCHANNELTYPE_Mono           = 0;
var AUDIOCHANNELTYPE_Stereo         = 1;
var AUDIOCHANNELTYPE_51             = 2;
var AUDIOCHANNELTYPE_Multichannel   = 3;
var AUDIOCHANNELTYPE_4Channel       = 4;
var AUDIOCHANNELTYPE_8Channel       = 5;

// VR Projection Types
var VRPROJECTIONTYPE_None               = 0;
var VRPROJECTIONTYPE_Equirectangular    = 1;

// VR Stereoscopic Types
var VRSTEREOSCOPICTYPE_Monoscopic   = 0;
var VRSTEREOSCOPICTYPE_OverUnder    = 1;
var VRSTEREOSCOPICTYPE_SideBySide   = 2;

// Media Type GUIDs (for cache clearing via QE DOM)
var MediaType_VIDEO = "228CDA18-3625-4d2d-951E-348879E4ED93";
var MediaType_AUDIO = "80B8E3D5-6DCA-4195-AEFB-CB5F407AB009";
var MediaType_ANY   = "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF";

// Media Type values for setInPoint/setOutPoint
var MediaType_Audio = 0;
var MediaType_Video = 1;

// Colorspace constants
var Colorspace_601      = 0;
var Colorspace_709      = 1;
var Colorspace_2020     = 2;
var Colorspace_2100HLG  = 3;

// Bit Precision
var BitPrecision_8bit   = 0;
var BitPrecision_10bit  = 1;
var BitPrecision_Float  = 2;
var BitPrecision_HDR    = 3;

// ProjectItemType (accessed as ProjectItemType.CLIP etc.)
// ProjectItemType.CLIP
// ProjectItemType.BIN
// ProjectItemType.ROOT
// ProjectItemType.FILE

2. APPLICATION OBJECT (app)

The global entry point to all Premiere Pro scripting.

Key Properties

  • app.project — the active/front Project object
  • app.projects — collection of all open projects (app.projects.numProjects)
  • app.encoder — the Encoder object for AME integration
  • app.properties — the Properties object for preferences
  • app.sourceMonitor — the Source Monitor object
  • app.production — open Production (if any)
  • app.version — version string, e.g. "14.0"
  • app.build — build string

Key Methods

// Get version info
var info = 'PPro ' + app.version + 'x' + app.build;

// Open a project file
app.openDocument(
    '/path/to/project.prproj',  // path
    false,  // suppress 'Convert Project' dialogs?
    false,  // suppress 'Locate Files' dialogs?
    false,  // suppress warning dialogs?
    false   // prevent adding to MRU list?
);

// Create a new project
var result = app.newProject('/path/to/NewProject'); // returns true on success

// Check if document is open
if (app.isDocumentOpen()) { /* ... */ }

// Get/set workspace
var workspaces = app.getWorkspaces(); // returns array of workspace name strings
app.setWorkspace('Editing');

// Proxy state
app.getEnableProxies(); // returns boolean
app.setEnableProxies(1); // 1=on, 0=off

// Scratch disk
app.setScratchDiskPath(path, ScratchDiskType.FirstAutoSaveFolder);

// QE DOM — enables lower-level "quality engineering" API
app.enableQE();
// After enableQE(), the global `qe` object is available

// Event panel messaging
app.setSDKEventMessage('Here is some information.', 'info');
app.setSDKEventMessage('Here is a warning.', 'warning');
app.setSDKEventMessage('Here is an error.', 'error');

// Make a CEP extension persistent (won't unload when hidden)
app.setExtensionPersistent("com.adobe.MyPanel", 0); // 0 = while testing; 1 = never unload

// Transcode on ingest
app.setEnableTranscodeOnIngest(true); // or false

// Get project view IDs (for selection APIs)
var viewIDs = app.getProjectViewIDs();
var project = app.getProjectFromViewID(viewIDs[0]);
var selection = app.getProjectViewSelection(viewIDs[0]); // returns array of ProjectItems
app.setProjectViewSelection(arrayOfProjectItems, viewIDs[0]);

// Event binding
app.bind('onProjectChanged', myCallbackFxn);
app.bind('onActiveSequenceChanged', myCallbackFxn);
app.bind('onActiveSequenceSelectionChanged', myCallbackFxn);
app.bind('onSequenceActivated', myCallbackFxn);
app.bind('onActiveSequenceStructureChanged', myCallbackFxn);
app.bind('onActiveSequenceTrackItemAdded', myTrackItemAddedFxn);    // callback(track, trackItem)
app.bind('onActiveSequenceTrackItemRemoved', myTrackItemRemovedFxn); // callback(track, trackItem)
app.bind('onSourceClipSelectedInProjectPanel', mySelectionFxn);
app.bind('onItemsAddedToProjectSuccess', myItemsAddedFxn);
app.onItemAddedToProjectSuccess = myFxn; // callback(whichProject, addedProjectItem)

// System compatibility report
SystemCompatibilityReport.CreateReport('/path/to/output.txt');

3. PROJECT OBJECT (app.project)

Represents a single open Premiere Pro project.

Properties

Property Type Description
activeSequence Sequence Currently active sequence (or 0 if none)
name String (read-only) Project filename
path String (read-only) Full file path
documentID String (read-only) UUID
isCloudProject Boolean Whether it's a Team/cloud project
rootItem ProjectItem Root bin of the project
sequences SequenceCollection All sequences (sequences.numSequences)

Key Methods

// Save
app.project.save();
app.project.saveAs('/path/to/NewLocation.prproj');

// Close
app.project.closeDocument(true, false); // saveFirst, promptIfDirty

// Import files
var filePaths = ['/path/to/clip1.mp4', '/path/to/clip2.mov'];
var suppressWarnings = true;
var importAsStills = false;
app.project.importFiles(
    filePaths,
    suppressWarnings,
    app.project.getInsertionBin(), // target bin (or rootItem)
    importAsStills
); // returns true/false

// Import After Effects compositions
var compNames = ['My Comp'];
app.project.importAEComps('/path/to/project.aep', compNames, targetBin);
app.project.importAllAEComps('/path/to/project.aep', targetBin);

// Create sequences
var seq = app.project.createNewSequence('My Sequence', 'someUniqueID');
// From preset (requires QE DOM):
app.enableQE();
qe.project.newSequence('My Sequence', '/path/to/preset.sqpreset');
// From selected project items:
var newSeq = app.project.createNewSequenceFromClips('new sequence', selectedItems, app.project.rootItem);

// Import sequences from another project
var seqIDsToImport = [id1, id2];
app.project.importSequences('/path/to/other.prproj', seqIDsToImport);

// Get insertion bin (where new items go in Project panel)
var bin = app.project.getInsertionBin();

// Consolidate duplicates
app.project.consolidateDuplicates();

// Export formats
app.project.exportAAF(
    app.project.activeSequence, // sequence
    '/path/output.aaf',         // output path
    1,   // mix down video?
    0,   // explode to mono?
    96000, // sample rate
    16,  // bits per sample
    0,   // embed audio? (0=no, 1=yes)
    0,   // audio format (0=aiff, 1=wav)
    0,   // handle frames
    0    // optional: path to .epr preset
);

app.project.exportOMF(
    app.project.activeSequence,
    '/path/output.omf',
    'OMFTitle',
    48000,  // sample rate (48000 or 96000)
    16,     // bits per sample (16 or 24)
    1,      // audio encapsulated (1=yes, 0=no)
    0,      // audio file format (0=AIFF, 1=WAV)
    0,      // trim audio files (0=no, 1=yes)
    0,      // handle frames
    0       // include pan (0=no, 1=yes)
);

app.project.exportFinalCutProXML(outputPath, sequenceObj);

// Project metadata schema
app.project.addPropertyToProjectMetadataSchema('FieldName', 'FieldLabel', 2); // 2 = text type

// Scratch disk
app.project.setScratchDiskPath(newPath, scratchDiskType);

// Project panel display metadata
var xml = app.project.getProjectPanelMetadata();
app.project.setProjectPanelMetadata(xmlString);

// Graphics white luminance (for HDR)
var supported = app.project.getSupportedGraphicsWhiteLuminances(); // returns array
var current   = app.project.getGraphicsWhiteLuminance();
app.project.setGraphicsWhiteLuminance(supportedValues[1]);

// Cloud project info (Team Projects)
// app.project.cloudProjectLocalID

4. SEQUENCE OBJECT

Accessed via app.project.activeSequence or app.project.sequences[i].

Properties

Property Type Description
audioDisplayFormat Enumerated 200=AudioSamples, 201=Milliseconds
audioTracks TrackCollection Audio tracks array
end String End time in ticks (read-only)
frameSizeHorizontal Integer Frame width (read-only)
frameSizeVertical Integer Frame height (read-only)
id Integer Ordinal ID (unstable)
markers MarkerCollection Sequence markers
name String Sequence name (read/write)
projectItem ProjectItem Associated ProjectItem
sequenceID String UUID (stable, use this)
timebase String Ticks per frame (read-only)
videoDisplayFormat Enumerated See TIMEDISPLAY_ constants
videoTracks TrackCollection Video tracks array
zeroPoint String Start time in ticks

Clip Operations

var seq = app.project.activeSequence;
var projectItem = app.project.rootItem.children[0];

// Insert clip at a time (insert edit — pushes downstream clips)
seq.insertClip(projectItem, time_in_seconds, vTrackIndex, aTrackIndex);

// Overwrite clip at a time (destructive — replaces what's there)
seq.overwriteClip(projectItem, time_in_seconds, vTrackIndex, aTrackIndex);

// Insert or append example — insert at end of last clip, or at start
var numVTracks  = seq.videoTracks.numTracks;
var targetTrack = seq.videoTracks[numVTracks - 1];
if (targetTrack.clips.numItems > 0) {
    var lastClip = targetTrack.clips[targetTrack.clips.numItems - 1];
    targetTrack.insertClip(first, lastClip.end.seconds);
} else {
    var timeAtZero = new Time();
    targetTrack.insertClip(first, timeAtZero.seconds);
}

// Insert to top tracks using Sequence method directly
var time    = seq.getPlayerPosition();
var newClip = seq.insertClip(first, time, seq.videoTracks.numTracks - 1, seq.audioTracks.numTracks - 1);

Playback & Navigation

// Current Time Indicator (CTI)
var pos = seq.getPlayerPosition();  // returns Time object
seq.setPlayerPosition(pos.ticks);   // set by ticks string

// In/Out Points
var inSecs  = seq.getInPoint();     // returns seconds as float, or "-400000" if not set
var outSecs = seq.getOutPoint();
var inTime  = seq.getInPointAsTime();   // returns Time object
var outTime = seq.getOutPointAsTime();
seq.setInPoint(inTime.seconds);
seq.setOutPoint(outTime.seconds);

// Work Area
var waIn  = seq.getWorkAreaInPoint();       // seconds
var waOut = seq.getWorkAreaOutPoint();
var waIn  = seq.getWorkAreaInPointAsTime(); // Time object
var waOut = seq.getWorkAreaOutPointAsTime();
seq.setWorkAreaInPoint(seconds);
seq.setWorkAreaOutPoint(seconds);
seq.isWorkAreaEnabled(); // Boolean
seq.setWorkAreaEnabled(true); // or false

// Get selected clips
var selection = seq.getSelection(); // returns array of TrackItems

Sequence Management

// Clone a sequence
var newSeq  = seq.clone();

// Close sequence tab
seq.close();

// Create subsequence from in/out points (respects track targeting)
var ignoreMapping = false;
var newSeq = seq.createSubsequence(ignoreMapping);
newSeq.name = newSeq.name + ', cloned by script.';

// Get/set sequence settings
var settings = seq.getSettings();
// settings properties include:
//   videoFrameRate, videoFieldType, videoPixelAspectRatio
//   videoDisplayFormat, frameSizeHorizontal, frameSizeVertical
//   audioChannelType, audioSampleRate, audioDisplayFormat
//   vrProjection, vrLayout, vrHorzCapturedView, vrVertCapturedView
//   workingColorSpace, workingColorSpaceList

// Change timecode display format
settings.videoDisplayFormat = TIMEDISPLAY_25Timecode;
seq.setSettings(settings);

// Change color space
settings.workingColorSpace = settings.workingColorSpaceList[1];
seq.setSettings(settings);

// Report timecode at current position
var timeAsText = seq.getPlayerPosition().getFormatted(
    settings.videoFrameRate,
    seq.videoDisplayFormat
);

// Zero point (sequence start offset)
seq.setZeroPoint(newZeroPointInTicks);

// Link/unlink selected clips
seq.linkSelection();
seq.unlinkSelection();

// Auto-reframe (requires prior analysis)
if (seq.isDoneAnalyzingForVideoEffects()) {
    var newSeq = seq.autoReframeSequence(
        1,          // numerator (aspect ratio)
        1,          // denominator
        'default',  // motionPreset: 'default', 'faster', 'slower'
        'My Reframed Seq',
        false       // useNestedSequences
    );
}

// Scene edit detection
var result = seq.performSceneEditDetectionOnSelection(
    'ApplyCuts',    // 'ApplyCuts' or 'CreateMarkers'
    true,           // applyCutsToLinkedAudio
    'LowSensitivity' // 'LowSensitivity', 'MediumSensitivity', 'HighSensitivity'
);

Export

// Export as FCP XML
seq.exportAsFinalCutProXML('/path/output.xml', 1); // 1 = suppress UI

// Export as self-contained Premiere project
seq.exportAsProject('/path/output.prproj');

// Render directly from within PPro (blocking)
seq.exportAsMediaDirect(
    '/path/output.mp4',
    '/path/preset.epr',
    app.encoder.ENCODE_WORKAREA  // or ENCODE_IN_TO_OUT, ENCODE_ENTIRE
);

// Create caption track from .srt
var result = seq.createCaptionTrack(srtProjectItem, startAtTime_seconds);

MOGRT Import (see Section 9 for full detail)

// Import a .mogrt into the sequence
var newTrackItem = seq.importMGT(
    '/path/to/template.mogrt', // full path
    seq.getPlayerPosition().ticks, // time in ticks (as string)
    0,  // video track offset from zero-th track
    0   // audio track offset from zero-th track
);

// Import from CC Libraries
var newTrackItem = seq.importMGTFromLibrary(
    'LibraryName',
    'TemplateName',
    seq.getPlayerPosition().ticks,
    0,  // vidTrackOffset
    0   // audTrackOffset
);

5. TRACK OBJECT

Accessed via seq.videoTracks[i] or seq.audioTracks[i].

Properties

Property Type Description
clips TrackItemCollection Clips on this track
id Integer (read-only) Ordinal ID
mediaType String (read-only) "Audio" or "Video"
name String (read-only) Track name
transitions TrackItemCollection Transitions on this track

Methods

var track = seq.videoTracks[0];

// Mute
track.isMuted();        // returns Boolean
track.setMute(1);       // 1 = mute, 0 = unmute

// Target (for subsequence creation, insert edits)
track.isTargeted();
track.setTargeted(true, true); // (isTargeted, updateUI)

// Insert/overwrite clip on this specific track
track.insertClip(projectItem, time_seconds);
track.overwriteClip(projectItem, time_seconds);

// Iterate clips and transitions
for (var i = 0; i < track.clips.numItems; i++) {
    var clip = track.clips[i];
}
for (var j = 0; j < track.transitions.numItems; j++) {
    var transition = track.transitions[j];
}

// Mute all audio tracks randomly (example pattern)
for (var i = 0; i < seq.audioTracks.numTracks; i++) {
    var t = seq.audioTracks[i];
    if (Math.random() > 0.5) {
        t.setMute(t.isMuted() ? 0 : 1);
    }
}

6. TRACKITEM OBJECT

Accessed via track.clips[i].

Properties

Property Type Access Description
components ComponentCollection Read-only Effects/components on this clip
duration Time Read-only Clip duration
start Time Read/write Start time in sequence
end Time Read/write End time in sequence
inPoint Time Read/write Source trim in point
outPoint Time Read/write Source trim out point
name String Read/write Clip name
mediaType String Read-only "Audio" or "Video"
type Number Read-only 1=video, 2=audio
projectItem ProjectItem Read-only Source media
nodeId String Read-only Unique ID
matchName String Read-only Plugin match name
disabled Boolean Read/write Disable playback

Methods

var clip = seq.videoTracks[0].clips[0];

// Speed / retiming
var speed = clip.getSpeed();        // 1.0 = normal
var reversed = clip.isSpeedReversed(); // returns 1 or 0

// Selection
var isSelected = clip.isSelected();
clip.setSelected(true, true); // (isSelected, updateUI)

// Adjustment layer check
clip.isAdjustmentLayer(); // Boolean

// Remove from sequence
clip.remove(
    true, // inRipple — ripple delete (close gap)?
    true  // inAlignToVideo — align to video frames?
);

// Move (shift position by time offset)
clip.move(13); // moves clip to start at 13 seconds

// Trim out point
var oldOut     = clip.outPoint;
oldOut.seconds = oldOut.seconds - 2.0;
clip.outPoint.ticks = oldOut.ticks;

// Get all linked clips (from same source) in sequence
var linkedItems = clip.getLinkedItems();
if (linkedItems) {
    // linkedItems.numItems
}

// Enable all disabled clips example
var clips = seq.videoTracks[0].clips;
for (var i = 0; i < clips.numItems; i++) {
    if (clips[i].disabled === true) {
        clips[i].disabled = false;
    }
}

// Move a clip to ticks = 13
seq.audioTracks[0].clips[0].move(13);
seq.videoTracks[0].clips[0].move(13);

7. PROJECTITEM OBJECT

Accessed via app.project.rootItem.children[i].

Properties

Property Type Description
name String Item name (read/write)
type Enumerated ProjectItemType.CLIP, .BIN, .ROOT, .FILE
nodeId String (read-only) Unique ID
treePath String (read-only) Project path (e.g. \\Project.prproj\\Media\\file.mxf)
children ProjectItemCollection Child items (bins)

Media Management

var item = app.project.rootItem.children[0];

// Get/change media path
var path = item.getMediaPath();
item.canChangeMediaPath(); // Boolean
item.changeMediaPath('/new/path/file.mp4', true); // true=suppressWarnings

// Proxy
item.hasProxy();    // Boolean
item.canProxy();    // Boolean
item.attachProxy('/path/to/proxy.mp4', 0); // 0=proxy, 1=hi-res
item.detachProxy();
var proxyPath = item.getProxyPath();

// Set scale to frame size (important for proxy workflows)
item.setScaleToFrameSize();

// Refresh media representation
item.refreshMedia();

// Offline status
item.isOffline();
item.setOffline();

Clip Operations

// Create a subclip
var startTime = new Time();
startTime.seconds = 0.0;
var endTime = new Time();
endTime.seconds = 3.21;
var newSubClip = item.createSubClip(
    'SubClipName',
    startTime,
    endTime,
    0,  // hasHardBoundaries (0=no)
    1,  // takeVideo
    1   // takeAudio
);

// Type checks
item.isMergedClip();    // Boolean
item.isMulticamClip();  // Boolean
item.isSequence();      // Boolean
item.isAdjustmentLayer(); // Boolean

// Frame rate / PAR overrides
item.setOverrideFrameRate(23.976);
item.setOverridePixelAspectRatio(185, 100); // numerator, denominator

// Start time
var st = item.startTime(); // returns Time object
var newST = new Time();
newST.seconds = 12.345;
item.setStartTime(newST);

In/Out Points

var inPt = item.getInPoint();  // returns Time object
item.setInPoint(seconds, MediaType_Video); // MediaType_Video or MediaType_Audio
item.clearInPoint();
var outPt = item.getOutPoint(MediaType_Video);
item.setOutPoint(seconds, MediaType_Video);
item.clearOutPoint();

Bin Operations

var rootItem = app.project.rootItem;

// Create a bin
var newBin = rootItem.createBin('My Bin');

// Create a smart (search) bin
rootItem.createSmartBin('Smart Bin', 'queryString');

// Delete bin
bin.deleteBin();

// Rename bin
bin.renameBin('New Name');

// Move bin
bin.moveBin(newParentBinProjectItem);

// Rename a project item
item.name = item.name + ', updated.';

// Color label (0-15)
var label = item.getColorLabel();
item.setColorLabel(label + 1);
// 0=Violet, 4=Cerulean, 15=Yellow

// Select item (set as import target)
item.select();

Metadata

// XMP metadata
if (ExternalObject.AdobeXMPScript === undefined) {
    ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
}
var xmpBlob = item.getXMPMetadata();
var xmp = new XMPMeta(xmpBlob);

// Read a property
if (xmp.doesPropertyExist(XMPConst.NS_DM, 'scene')) {
    var val = xmp.getProperty(XMPConst.NS_DM, 'scene').value;
}

// Write a property
xmp.setProperty(XMPConst.NS_DM, 'scene', 'My Scene Value');
xmp.setProperty(XMPConst.NS_DM, 'creator', 'Script Author');

// Array properties (NS_DC creator)
var count = xmp.countArrayItems(XMPConst.NS_DC, 'creator');
for (var z = 0; z < count; z++) {
    var val = xmp.getArrayItem(XMPConst.NS_DC, 'creator', z + 1);
}
xmp.appendArrayItem(XMPConst.NS_DC, 'creator', 'New Creator', null, XMPConst.ARRAY_IS_ORDERED);
xmp.deleteProperty(XMPConst.NS_DC, 'creator');

// Serialize and write back
var xmpAsString = xmp.serialize();
item.setXMPMetadata(xmpAsString);

// Private project metadata
var kPProPrivateProjectMetadataURI = "http://ns.adobe.com/premierePrivateProjectMetaData/1.0/";
var projectMeta = item.getProjectMetadata();
var xmpMeta = new XMPMeta(projectMeta);
xmpMeta.setProperty(kPProPrivateProjectMetadataURI, 'Column.Intrinsic.TapeName', '***TAPENAME***');
xmpMeta.setProperty(kPProPrivateProjectMetadataURI, 'Column.Intrinsic.LogNote', 'My note');
var updatedFields = ['Column.Intrinsic.TapeName', 'Column.Intrinsic.LogNote'];
item.setProjectMetadata(xmpMeta.serialize(), updatedFields);

// Markers
var markers = item.getMarkers(); // returns MarkerCollection

// Footage interpretation
var interp = item.getFootageInterpretation();
interp.frameRate = 23.976;
interp.pixelAspectRatio = 1.0;
// interp also has: alphaUsage, fieldType, vrProjection, vrStereoscopic, etc.
item.setFootageInterpretation(interp);

// Audio channel mapping
var mapping = item.getAudioChannelMapping();
mapping.audioChannelsType = AUDIOCHANNELTYPE_Stereo;
mapping.audioClipsNumber = 1;
mapping.setMappingForChannel(0, 4); // (channelIndex, sourceIndex)
mapping.setMappingForChannel(1, 5);
item.setAudioChannelMapping(mapping);

// Color space
var cs = item.getColorSpace();
// cs.name, cs.transferCharacteristic, cs.primaries, cs.matrixEquation
var origCs = item.getOriginalColorSpace();
var lutID = item.getEmbeddedLUTID();
var inputLutID = item.getInputLUTID();
var overrideList = item.getOverrideColorSpaceList();
item.setOverrideColorSpace('Rec. 709');

// Video components (effects on master clip)
var compCollection = item.videoComponents();

// Find items with same media path
var matches = item.findItemsMatchingMediaPath('/path/to/media.mp4', false);

8. COMPONENT & COMPONENTPARAM OBJECTS

These are the building blocks for effects and MoGRT parameter access.

Component Object

Accessed via trackItem.components[i].

var clip = seq.videoTracks[0].clips[0];
var components = clip.components;

for (var i = 0; i < components.numItems; i++) {
    var comp = components[i];
    // comp.displayName — localized display name
    // comp.matchName   — internal plugin name (stable identifier)
    // comp.properties  — ComponentParamCollection
}

// Component indices typically:
// 0 = the clip itself (Intrinsic Effects / Motion)
// 1 = Opacity
// 2+ = applied effects

// Access Gaussian Blur (if applied as first effect)
var blur = components[2];
var blurProps = blur.properties;
for (var j = 0; j < blurProps.numItems; j++) {
    // blurProps[j].displayName
}
var blurriness = blurProps[0]; // first param

ComponentParam Object

Accessed via component.properties[i] or component.properties.getParamForDisplayName(name).

var param = blurProps[0]; // or use getParamForDisplayName

// displayName (read-only, localized string)
var name = param.displayName;

// --- GET VALUES ---
var val = param.getValue();                  // current (non-time-variant) value
var valAtTime = param.getValueAtTime(2.5);   // interpolated value at 2.5s
var valAtKey  = param.getValueAtKey(time);   // value at exact keyframe

// Color parameters
var colorVal = param.getColorValue(); // returns [alpha, red, blue, green]
var alpha = colorVal[0], red = colorVal[1], blue = colorVal[2], green = colorVal[3];

// --- SET VALUES ---
var updateUI = true;
param.setValue(newValue, updateUI);

// Color
param.setColorValue(255, 33, 222, 111, updateUI); // a, r, g, b

// --- KEYFRAMING ---
param.areKeyframesSupported();   // Boolean
param.isTimeVarying();           // Boolean

// Enable keyframing
if (!param.isTimeVarying()) {
    param.setTimeVarying(true);
}

// Add/remove keyframes
var time = new Time();
time.seconds = 2.0;
param.addKey(time);
param.setValueAtKey(time, 25.0, updateUI);
param.removeKey(19);           // remove keyframe at 19s
param.removeKeyRange(0, 5, updateUI); // remove all keys between 0–5s

// Get all keyframe times
var allKeys = param.getKeys(); // returns array of Time objects
for (var k = 0; k < allKeys.length; k++) {
    var thisKey = allKeys[k];
    // thisKey.seconds, thisKey.ticks
}

// Interpolation at a keyframe
// KF_Interp_Mode_Linear=0, Hold=4, Bezier=5, Time=6
param.setInterpolationTypeAtKey(time, KF_Interp_Mode_Hold, updateUI);

// Keyframe navigation
var nearestKey = param.findNearestKey(4.0, 0.1); // (time, threshold) returns Time or undefined
var nextKey    = param.findNextKey(time);         // returns Time or undefined
var prevKey    = param.findPreviousKey(time);

// Scan forward
var keyTime = param.findNearestKey(0.0, 0.1);
while (keyTime !== undefined) {
    // use keyTime.seconds
    keyTime = param.findNextKey(keyTime);
}

9. MOGRT / MOTION GRAPHICS TEMPLATE — COMPLETE GUIDE

Overview

  • .mogrt files are Motion Graphics Templates, primarily created in After Effects
  • The API is designed for AE-created MOGRTs; Premiere Pro-created MOGRTs are not fully supported via scripting
  • Import gives you a TrackItem; call .getMGTComponent() on that item to access template parameters
  • Parameters are ComponentParam objects — use getParamForDisplayName() to find by name
  • Text parameters may return JSON strings from getValue() — see handling below

Step-by-Step: Import and Modify MOGRT

// STEP 1: Get the active sequence
var activeSeq = app.project.activeSequence;
if (!activeSeq) {
    throw new Error('No active sequence');
}

// STEP 2: Set the target time
var targetTime = activeSeq.getPlayerPosition(); // insert at CTI
// OR set a specific time:
// var targetTime = new Time();
// targetTime.seconds = 5.0;

// STEP 3: Import the .mogrt into the sequence
var newTrackItem = activeSeq.importMGT(
    '/path/to/template.mogrt', // full path to .mogrt file
    targetTime.ticks,           // time in ticks (string)
    0,                          // video track offset (0 = first video track)
    0                           // audio track offset (0 = first audio track)
);

if (!newTrackItem) {
    throw new Error('importMGT failed');
}

// STEP 4: Get the MGT component
var moComp = newTrackItem.getMGTComponent();
if (!moComp) {
    throw new Error('getMGTComponent failed');
}

// STEP 5: List all parameters (useful for discovery)
var params = moComp.properties;
for (var z = 0; z < params.numItems; z++) {
    var thisParam = params[z];
    if (thisParam) {
        app.setSDKEventMessage('Param ' + (z+1) + ': ' + thisParam.displayName, 'info');
    }
}

// STEP 6: Access a parameter by display name and set its value
var srcTextParam = params.getParamForDisplayName('Source Text'); // use exact display name
if (srcTextParam) {
    srcTextParam.setValue('New value set by script!', true);
}

// For non-text numeric params (e.g. opacity, scale):
var opacityParam = params.getParamForDisplayName('Opacity');
if (opacityParam) {
    opacityParam.setValue(0.75, true); // 0.0 – 1.0 or 0–100 depending on param
}

From Official Adobe PProPanel Sample (verbatim):

importMoGRT: function () {
    var activeSeq = app.project.activeSequence;
    if (activeSeq) {
        var filterString = "";
        if (Folder.fs === 'Windows') {
            filterString = "Motion Graphics Templates:*.mogrt";
        }
        var mogrtToImport = File.openDialog("Choose MoGRT",
                                            filterString,
                                            false);
        if (mogrtToImport) {
            var targetTime      = activeSeq.getPlayerPosition();
            var vidTrackOffset  = 0;
            var audTrackOffset  = 0;
            var newTrackItem    = activeSeq.importMGT(mogrtToImport.fsName,
                                                      targetTime.ticks,
                                                      vidTrackOffset,
                                                      audTrackOffset);
            if (newTrackItem) {
                var moComp = newTrackItem.getMGTComponent();
                if (moComp) {
                    var params = moComp.properties;
                    for (var z = 0; z < params.numItems; z++) {
                        var thisParam = params[z];
                        if (thisParam) {
                            app.setSDKEventMessage('Parameter ' + (z+1) + ' name: ' + thisParam.name + '.', 'info');
                        }
                    }
                    var srcTextParam = params.getParamForDisplayName("Source Text");
                    if (srcTextParam) {
                        var val = srcTextParam.getValue();
                        srcTextParam.setValue("New value set by PProPanel!");
                    }
                }
            }
        } else {
            app.setSDKEventMessage('Unable to import specified .mogrt file.', 'info');
        }
    } else {
        app.setSDKEventMessage('No active sequence.', 'info');
    }
},

Handling Text Parameters (JSON format)

Some text parameters return a JSON string from getValue(). Parse and modify it:

var textParam = moComp.properties.getParamForDisplayName('Title');
if (textParam) {
    var rawVal = textParam.getValue();

    // Check if it's JSON
    try {
        var parsedVal = JSON.parse(rawVal);
        // JSON structure typically has:
        // {
        //   "textEditValue": "Current Text",
        //   "fontEditValue": "Arial",
        //   "fontSizeEditValue": 48,
        //   "fontTextRunLength": [12]  // array matching text segments
        // }
        parsedVal.textEditValue = 'My New Text';
        parsedVal.fontTextRunLength = [parsedVal.textEditValue.length];
        textParam.setValue(JSON.stringify(parsedVal), true);
    } catch(e) {
        // Not JSON — set directly
        textParam.setValue('My New Text', true);
    }
}

Accessing a MOGRT Already on the Timeline

// Access MOGRT from an existing track item
var clip = seq.videoTracks[4].clips[0];  // adjust indices as needed
var mgt  = clip.getMGTComponent();
if (mgt) {
    var prop = mgt.properties.getParamForDisplayName('Small Text');
    if (prop) {
        prop.setValue('test', true);
    }
}

Import from CC Libraries

var newTrackItem = seq.importMGTFromLibrary(
    'My CC Library',      // library name
    'My Template Name',   // template name within library
    targetTime.ticks,
    0,  // vidTrackOffset
    0   // audTrackOffset
);

Known Limitations

  1. Only After Effects-created .mogrt files are fully supported. Premiere Pro-created MOGRTs have limited scripting support.
  2. No media replacement APIs exist inside MOGRTs via ExtendScript.
  3. Scripts cannot be embedded in or invoked from .mogrt files themselves.
  4. The getMGTComponent() method is on TrackItem, not ProjectItem — you must insert the MOGRT first.

10. MARKER OBJECT

Sequence Markers

var markers = seq.markers; // or projectItem.getMarkers()
var numMarkers = markers.numMarkers;

// Iterate markers
for (var m = markers.getFirstMarker(); m !== undefined; m = markers.getNextMarker(m)) {
    app.setSDKEventMessage('Marker name: ' + m.name, 'info');
    app.setSDKEventMessage('Marker GUID: ' + m.guid, 'info');
    app.setSDKEventMessage('Starts at: ' + m.start.seconds + 's', 'info');
    if (m.end.seconds > 0) {
        app.setSDKEventMessage('Duration: ' + (m.end.seconds - m.start.seconds) + 's', 'info');
    }
}

// Create a comment marker
var newCommentMarker = markers.createMarker(12.345); // time in seconds
newCommentMarker.name     = 'Marker Name';
newCommentMarker.comments = 'My comment text.';
newCommentMarker.end      = newCommentMarker.start.seconds + 5.0;
// newCommentMarker.setTypeAsChapter();
// newCommentMarker.setTypeAsWebLink("http://...", "frame target");
// newCommentMarker.setTypeAsSegmentation();
// newCommentMarker.setTypeAsComment(); // default

// Create a web link marker
var newWebMarker = markers.createMarker(14.345);
newWebMarker.name     = 'Web Marker';
newWebMarker.end      = newWebMarker.start.seconds + 3.0;
newWebMarker.setTypeAsWebLink("http://www.adobe.com", "frame target");

// Marker color (added in Premiere Pro 13.x)
// Color indices: 0=Green, 1=Red, 2=Orange, 3=Yellow, 4=White, 5=Blue, 6=Lavender, 7=Cyan
var oldColor = m.getColorByIndex();
m.setColorByIndex(oldColor + 1 > 7 ? 0 : oldColor + 1);

// Marker properties (read-only)
// m.guid    — unique ID string
// m.type    — "Comment", "Chapter", "Segmentation", "WebLink"
// m.getWebLinkURL()
// m.getWebLinkFrameTarget()

// Export frames at each marker position
var firstMarker = markers.getFirstMarker();
if (firstMarker) {
    seq.setPlayerPosition(firstMarker.start.ticks);
    // export frame...
    var currentMarker;
    var previousMarker = firstMarker;
    for (var i = 0; i < numMarkers - 1; i++) {
        currentMarker = markers.getNextMarker(previousMarker);
        if (currentMarker) {
            seq.setPlayerPosition(currentMarker.start.ticks);
            previousMarker = currentMarker;
            // export frame...
        }
    }
}

Clip Markers

var projectItem = app.project.rootItem.children[0];
if (projectItem.type == ProjectItemType.CLIP || projectItem.type == ProjectItemType.FILE) {
    var markers = projectItem.getMarkers();
    var newMarker = markers.createMarker(12.345);
    newMarker.name     = 'Clip Marker';
    newMarker.comments = 'Comments here.';
    newMarker.end      = newMarker.start.seconds + 5.0;
}

11. ENCODER OBJECT (app.encoder)

Used for rendering via Adobe Media Encoder.

Bug Note: app.encoder is broken on Premiere Pro 14.3.1–15 on Mac only. Fixed in version 22+.

Encoder Constants

app.encoder.ENCODE_ENTIRE      // render entire timeline
app.encoder.ENCODE_IN_TO_OUT   // render in/out range
app.encoder.ENCODE_WORKAREA    // render work area

Render Methods

// Bind progress/completion callbacks
app.encoder.bind('onEncoderJobComplete',  function(jobID, outputFilePath) { /* ... */ });
app.encoder.bind('onEncoderJobError',     function(jobID, errorMessage)   { /* ... */ });
app.encoder.bind('onEncoderJobProgress',  function(jobID, progress)       { /* ... */ });
app.encoder.bind('onEncoderJobQueued',    function(jobID)                  { /* ... */ });
app.encoder.bind('onEncoderJobCanceled',  function(jobID)                  { /* ... */ });

// Launch AME
app.encoder.launchEncoder(); // asynchronous; returns 0 on success

// Render a Sequence
var jobID = app.encoder.encodeSequence(
    app.project.activeSequence,   // Sequence object
    '/path/output.mp4',           // output path
    '/path/preset.epr',           // .epr preset path
    app.encoder.ENCODE_WORKAREA,  // range type
    1                             // removeUponCompletion (1=yes)
);

// Render a ProjectItem
var jobID = app.encoder.encodeProjectItem(
    projectItem,
    '/path/output.mp4',
    '/path/preset.epr',
    app.encoder.ENCODE_IN_TO_OUT,
    1
);

// Render an external file with optional in/out
var srcIn = new Time();
srcIn.seconds = 1.0;
var srcOut = new Time();
srcOut.seconds = 3.0;
var jobID = app.encoder.encodeFile(
    '/path/source.mp4',
    '/path/output.mp4',
    '/path/preset.epr',
    0,       // removeUponCompletion
    srcIn,   // optional in point (omit to encode entire file)
    srcOut   // optional out point
);

// Start the AME queue
app.encoder.startBatch();

// XMP sidecar control
app.encoder.setSidecarXMPEnabled(0);   // 0=disabled, 1=enabled
app.encoder.setEmbeddedXMPEnabled(0);

// List available exporters and presets (write to file)
var exporters = app.encoder.getExporters();
for (var i = 0; i < exporters.length; i++) {
    var exporter = exporters[i];
    // exporter.name, exporter.classID, exporter.fileType
    var presets = exporter.getPresets();
    for (var j = 0; j < presets.length; j++) {
        // presets[j].matchName, presets[j].name
    }
}

// Get last export folder
var lastFolder = app.encoder.lastExportMediaFolder();

Render from Within PPro (blocking — no AME required)

var seq = app.project.activeSequence;
if (seq) {
    seq.exportAsMediaDirect(
        '/path/output.mp4',
        '/path/preset.epr',
        app.encoder.ENCODE_WORKAREA
    );
    // Compute sequence duration in ticks (254016000000 ticks/second):
    var seqDuration = app.project.activeSequence.end - app.project.activeSequence.zeroPoint;
}

Export Current Frame as PNG

function exportCurrentFrameAsPNG(presetPath) {
    var seq = app.project.activeSequence;
    if (seq) {
        var currentSeqSettings = seq.getSettings();
        var currentTime        = seq.getPlayerPosition();
        var oldInPoint         = seq.getInPointAsTime();
        var oldOutPoint        = seq.getOutPointAsTime();
        var offsetTime         = currentTime.seconds + 0.033; // ~1 frame at 30fps

        seq.setInPoint(currentTime.seconds);
        seq.setOutPoint(offsetTime);

        var timeAsText  = currentTime.getFormatted(currentSeqSettings.videoFrameRate, seq.videoDisplayFormat);
        var removeColons = /:|;/ig;
        var tidyTime    = timeAsText.replace(removeColons, '_');
        var outputPath  = new File("~/Desktop/output/frames");
        var outputFile  = outputPath.fsName + '/' + seq.name + '___' + tidyTime + '.png';

        var removeUponCompletion  = 1;
        var startQueueImmediately = false;
        var jobID = app.encoder.encodeSequence(
            seq,
            outputFile,
            presetPath,
            app.encoder.ENCODE_IN_TO_OUT,
            removeUponCompletion,
            startQueueImmediately
        );

        seq.setInPoint(oldInPoint.seconds);
        seq.setOutPoint(oldOutPoint.seconds);
    }
}

12. PROPERTIES OBJECT (app.properties)

var prop = 'MZ.Prefs.ShowQuickstartDialog';
var exists    = app.properties.doesPropertyExist(prop);     // Boolean
var isReadOnly = app.properties.isPropertyReadOnly(prop);   // Boolean
var value     = app.properties.getProperty(prop);           // String

// Set a property
app.properties.setProperty(
    prop,
    '0',   // new value (string)
    1,     // persistent across sessions (1=yes, 0=no)
    false  // create if not exists (true=yes)
);

// Clear a property
app.properties.clearProperty(prop);

// Useful property keys:
// 'MZ.Prefs.ShowQuickstartDialog' — startup dialog
// 'FE.Prefs.ImportWorkspace' — import workspace with projects
// 'BE.Prefs.Audio.AutoPeakGeneration' — auto audio peak generation

13. SOURCE MONITOR OBJECT (app.sourceMonitor)

// Open file path in Source Monitor
app.sourceMonitor.openFilePath('/path/to/file.mp4');

// Open project item in Source Monitor
app.sourceMonitor.openProjectItem(projectItem);

// Playback
app.sourceMonitor.play(1.0);   // speed: -4.0 to 4.0, 1.0=normal forward
var pos = app.sourceMonitor.getPosition(); // returns Time object
// pos.seconds

// Close clips
app.sourceMonitor.closeClip();      // front clip
app.sourceMonitor.closeAllClips();  // all clips

// QE DOM scrubbing
app.enableQE();
qe.source.player.startScrubbing();
qe.source.player.scrubTo('00;00;00;11');
qe.source.player.endScrubbing();
qe.source.player.step();
qe.source.player.play(1.0); // speed between -4.0 and 4.0

14. QE DOM (Quality Engineering DOM)

The QE DOM is an undocumented lower-level API. Enable it with app.enableQE() — this makes the global qe object available.

app.enableQE();

// Active sequence (QE version)
var qeSeq = qe.project.getActiveSequence();

// New sequence from preset
qe.project.newSequence('My Sequence', '/path/to/preset.sqpreset');

// Delete preview files
qe.project.deletePreviewFiles(MediaType_ANY); // or MediaType_VIDEO, MediaType_AUDIO

// Get output file extension for a given preset
var ext = qeSeq.getExportFileExtension('/path/preset.epr');

// Console/debug logging
qe.executeConsoleCommand("con.openlog /path/to/log.txt");
qe.executeConsoleCommand("con.closelog");

// Debug database
var val = qe.getDebugDatabaseEntry("CreateLogFilesThatDoNotExist");
qe.setDebugDatabaseEntry("CreateLogFilesThatDoNotExist", "true");

// Team Projects (cloud)
var production = qe.ea.getProductionByID(localHubID);
var remoteID = production.getRemoteProductionID();

15. TIME OBJECT

// Create a Time object
var t = new Time();
t.seconds = 5.5;     // set via seconds (float)
// t.ticks          // ticks string (254016000000 ticks per second)

// Get formatted timecode string
var formatted = t.getFormatted(frameRate, displayFormat);
// e.g.: seq.getPlayerPosition().getFormatted(settings.videoFrameRate, seq.videoDisplayFormat)

// Ticks constant: 254016000000 ticks = 1 second
var seqDurationTicks = seq.end - seq.zeroPoint; // arithmetic on ticks strings

16. COMPLETE PRACTICAL CODE EXAMPLES

Example A: Import Files and Add to Sequence

// Import files
var importThese = ['/path/clip1.mp4', '/path/clip2.mov'];
var success = app.project.importFiles(
    importThese,
    true,                            // suppress warnings
    app.project.getInsertionBin(),
    false                            // not numbered stills
);

// Get newly imported item and insert into sequence
var seq = app.project.activeSequence;
var item = app.project.rootItem.children[0];
if (seq && item && !item.isSequence() && item.type !== ProjectItemType.BIN) {
    var numTracks = seq.videoTracks.numTracks;
    var targetTrack = seq.videoTracks[numTracks - 1];
    if (targetTrack.clips.numItems > 0) {
        var lastClip = targetTrack.clips[targetTrack.clips.numItems - 1];
        targetTrack.insertClip(item, lastClip.end.seconds);
    } else {
        var t = new Time();
        targetTrack.insertClip(item, t.seconds); // t.seconds = 0 by default
    }
}

Example B: Create a Sequence and Add Clips

// Create a new sequence
var newSeq = app.project.createNewSequence('My New Sequence', 'unique-id-xyz');

// Or from preset via QE
app.enableQE();
qe.project.newSequence('From Preset', '/path/to/preset.sqpreset');

// Create sequence from selected project items
var viewIDs = app.getProjectViewIDs();
var selectedItems = app.getProjectViewSelection(viewIDs[0]);
if (selectedItems && selectedItems.length > 0) {
    var newSeq = app.project.createNewSequenceFromClips(
        'New Sequence From Clips',
        selectedItems,
        app.project.rootItem
    );
}

Example C: Walk All Project Items Recursively

function walkBin(parentItem, callback) {
    for (var i = 0; i < parentItem.children.numItems; i++) {
        var child = parentItem.children[i];
        if (!child) continue;
        if (child.type === ProjectItemType.BIN) {
            walkBin(child, callback); // recurse into bin
        } else {
            callback(child);
        }
    }
}

walkBin(app.project.rootItem, function(item) {
    app.setSDKEventMessage('Item: ' + item.name + ' path: ' + item.getMediaPath(), 'info');
});

Example D: Walk All Clips in a Sequence

var seq = app.project.activeSequence;
var trackGroups = [seq.videoTracks, seq.audioTracks];

for (var g = 0; g < 2; g++) {
    var group = trackGroups[g];
    for (var t = 0; t < group.numTracks; t++) {
        var track = group[t];
        for (var c = 0; c < track.clips.numItems; c++) {
            var clip = track.clips[c];
            var srcName = (clip.projectItem ? clip.projectItem.name : '<null>');
            app.setSDKEventMessage(
                'Track ' + t + ' Clip ' + c + ': ' + clip.name +
                ' source=' + srcName +
                ' start=' + clip.start.seconds + 's' +
                ' speed=' + clip.getSpeed(),
                'info'
            );
        }
    }
}

Example E: Effect Keyframing (Gaussian Blur example)

var clip       = seq.videoTracks[0].clips[0];
var components = clip.components;
// Assumes Gaussian Blur is applied as first effect (index 2)
var blur       = components[2];
var blurProps  = blur.properties;
var blurriness = blurProps[0]; // first property = blurriness

var updateUI = true;

// Enable time-varying
if (!blurriness.isTimeVarying()) {
    blurriness.setTimeVarying(true);
}

// Add keyframes
var t1 = new Time(); t1.seconds = 0.0;
var t2 = new Time(); t2.seconds = 5.0;
blurriness.addKey(t1);
blurriness.setValueAtKey(t1, 0, updateUI);
blurriness.addKey(t2);
blurriness.setValueAtKey(t2, 50, updateUI);

// Set interpolation
blurriness.setInterpolationTypeAtKey(t1, KF_Interp_Mode_Bezier, updateUI);
blurriness.setInterpolationTypeAtKey(t2, KF_Interp_Mode_Bezier, updateUI);

// Find keyframe nearest 4s (±0.1s tolerance)
var nearestKey = blurriness.findNearestKey(4.0, 0.1);
if (nearestKey !== undefined) {
    app.setSDKEventMessage('Found keyframe at ' + nearestKey.seconds, 'info');
}

// Color parameter example
// var colorParam = components[2].properties[N];
// var colorVal = colorParam.getColorValue();  // [alpha, red, blue, green]
// colorParam.setColorValue(255, 33, 222, 111, updateUI); // a, r, g, b

Example F: Render with AME (full workflow)

function renderActiveSequence(outputPresetPath) {
    var seq = app.project.activeSequence;
    if (!seq) { return; }

    app.enableQE();
    var qeSeq = qe.project.getActiveSequence();

    // Launch AME
    var ameStatus = BridgeTalk.getStatus("ame");
    if (ameStatus === "ISNOTINSTALLED") { return; }
    if (ameStatus === 'ISNOTRUNNING') {
        app.encoder.launchEncoder();
    }

    // Bind callbacks
    app.encoder.bind('onEncoderJobComplete',  function(jobID, path) {
        app.setSDKEventMessage('Complete: ' + path, 'info');
    });
    app.encoder.bind('onEncoderJobError',     function(jobID, err) {
        app.setSDKEventMessage('Error: ' + err, 'error');
    });
    app.encoder.bind('onEncoderJobQueued',    function(jobID) {
        app.encoder.startBatch();
    });

    // Determine output path
    var outFolder = Folder.selectDialog("Choose output directory");
    if (!outFolder) { return; }

    var outPreset = new File(outputPresetPath);
    var outputFormatExtension = qeSeq.getExportFileExtension(outPreset.fsName);
    var fullPathToFile = outFolder.fsName + '/' + seq.name + '.' + outputFormatExtension;

    // Disable metadata sidecar files
    app.encoder.setSidecarXMPEnabled(0);
    app.encoder.setEmbeddedXMPEnabled(0);

    var jobID = app.encoder.encodeSequence(
        seq,
        fullPathToFile,
        outPreset.fsName,
        app.encoder.ENCODE_WORKAREA,
        1 // removeUponCompletion
    );
    outPreset.close();
}

Example G: Project Consolidation / Collect and Copy

var pmo = app.projectManager.options;
if (pmo && app.project.sequences.numSequences) {
    var outFolder = Folder.selectDialog("Choose output directory.");
    if (outFolder) {
        pmo.clipTranscoderOption    = pmo.CLIP_TRANSCODE_MATCH_SEQUENCE;
        pmo.clipTransferOption      = pmo.CLIP_TRANSFER_TRANSCODE;
        pmo.convertAECompsToClips   = false;
        pmo.convertSyntheticsToClips = false;
        pmo.copyToPreventAlphaLoss  = false;
        pmo.destinationPath         = outFolder.fsName;
        pmo.excludeUnused           = false;
        pmo.handleFrameCount        = 0;
        pmo.includeAllSequences     = true;
        pmo.includeConformedAudio   = true;
        pmo.includePreviews         = true;
        pmo.renameMedia             = false;

        var result    = app.projectManager.process(app.project);
        var errorList = app.projectManager.errors;
    }
}

Example H: Multi-Project Management

// Open a second project without closing the current one
app.openDocument('/path/to/other.prproj', false, false, false, false);

// Iterate all open projects
var viewIDs = app.getProjectViewIDs();
for (var a = 0; a < app.projects.numProjects; a++) {
    var proj = app.getProjectFromViewID(viewIDs[a]);
    app.setSDKEventMessage('Open project: ' + proj.name + ' id=' + proj.documentID, 'info');
}

// Close all projects except the active one
var closeThese = [];
for (var a = 0; a < viewIDs.length; a++) {
    var proj = app.getProjectFromViewID(viewIDs[a]);
    if (proj.documentID !== app.project.documentID) {
        closeThese.push(proj);
    }
}
for (var b = 0; b < closeThese.length; b++) {
    closeThese[b].closeDocument();
}

Example I: Save Project Copy Without Switching Active Project

function saveProjectCopy(destFolderPath) {
    var originalPath = app.project.path;
    var outputName   = app.project.name.replace('.prproj', '_copy.prproj');
    var fullOutPath  = destFolderPath + '/' + outputName;

    app.project.saveAs(fullOutPath);

    // saveAs switches focus to the copy; switch back
    var viewIDs = app.getProjectViewIDs();
    for (var a = 0; a < app.projects.numProjects; a++) {
        var proj = app.getProjectFromViewID(viewIDs[a]);
        if (proj.path === fullOutPath) {
            app.openDocument(originalPath, true, true, true, true);
            proj.closeDocument();
            break;
        }
    }
}

Example J: Proxy Ingest Workflow

function ingestWithProxies(outputPresetPath) {
    app.encoder.bind('onEncoderJobComplete',  onProxyJobComplete);
    app.encoder.bind('onEncoderJobQueued',    function(jobID) { app.encoder.startBatch(); });

    var filesToImport = File.openDialog("Choose source files", "", true);
    if (!filesToImport) return;

    var importPaths = [];
    for (var i = 0; i < filesToImport.length; i++) {
        var srcPath     = filesToImport[i].fsName;
        var proxyPath   = srcPath.replace(/\.[^.]+$/, '_PROXY.mp4');
        importPaths[i]  = srcPath;
        app.encoder.encodeFile(srcPath, proxyPath, outputPresetPath, 0);
    }

    app.project.importFiles(importPaths, true, app.project.getInsertionBin(), false);
}

function onProxyJobComplete(jobID, outputFilePath) {
    // attach the newly created proxy to the project item
    var matches = app.project.rootItem;
    // ... find the item and call item.attachProxy(outputFilePath, 0);
}

Example K: Subsequence Creation

function createSubsequenceFromInOut() {
    var seq = app.project.activeSequence;
    if (!seq) return;

    // Ensure at least one targeted track
    var targetFound = false;
    for (var a = 0; a < seq.videoTracks.numTracks && !targetFound; a++) {
        if (seq.videoTracks[a].isTargeted()) targetFound = true;
    }
    if (!targetFound) {
        seq.videoTracks[0].setTargeted(true, true);
    }

    var NOT_SET = "-400000";
    var cloneAnyway = true;
    if (seq.getInPoint() === NOT_SET && seq.getOutPoint() === NOT_SET) {
        cloneAnyway = confirm("No in/out set. Clone entire sequence?", false, "Confirm");
    }
    if (cloneAnyway) {
        var ignoreMapping = false;
        var newSeq = seq.createSubsequence(ignoreMapping);
        newSeq.name = newSeq.name + ', cloned by script.';
    }
}

17. EXTENDSCRIPT BOILERPLATE / PANEL STRUCTURE

Basic CEP Panel Structure

A CEP extension consists of:

  • manifest.xml — declares the extension ID, host apps, version ranges
  • index.html — the panel UI (HTML/CSS/JS)
  • .jsx file — the ExtendScript code executed in PPro's engine

Calling ExtendScript from the CEP panel HTML/JS:

// In your panel's JavaScript (index.html side):
var csInterface = new CSInterface();

// Call an ExtendScript function
csInterface.evalScript('$._PPP_.getActiveSequenceName()', function(result) {
    console.log('Active sequence: ' + result);
});

// Pass parameters
csInterface.evalScript('$._PPP_.importMoGRT()', function(result) {
    console.log(result);
});

ExtendScript file pattern (the $.namespace pattern):

// Premiere.jsx (runs inside Premiere Pro's ExtendScript engine)
$._PPP_ = {

    getVersionInfo: function() {
        return 'PPro ' + app.version + 'x' + app.build;
    },

    getActiveSequenceName: function() {
        if (app.project.activeSequence) {
            return app.project.activeSequence.name;
        } else {
            return "No active sequence.";
        }
    },

    updateEventPanel: function(message) {
        app.setSDKEventMessage(message, 'info');
    },

    keepPanelLoaded: function() {
        app.setExtensionPersistent("com.adobe.MyPanel", 0);
    }
    // ... etc.
};

CEP Extension Directory Locations

  • Mac: /Library/Application Support/Adobe/CEP/extensions/YourPanel/
  • Windows: C:\Program Files (x86)\Common Files\Adobe\CEP\extensions\YourPanel\

Debugging

// Use VS Code with Adobe's ExtendScript Debugger extension
// Or use BridgeTalk to send to After Effects for debugging:
var bt    = new BridgeTalk();
bt.target = 'aftereffects';
bt.body   = 'alert("Items in AE project: " + app.project.rootFolder.numItems); app.quit();';
bt.send();

// Platform detection
if (Folder.fs === 'Macintosh') {
    var sep = '/';
} else {
    var sep = '\\';
}

// Running Windows check
var runningOnWindows = (Folder.fs === 'Windows');

18. FILE I/O PATTERNS IN EXTENDSCRIPT

// Get user home directory name
var homeDir = new File('~/');
var userName = homeDir.displayName;
homeDir.close();

// File picker dialogs
var filterString = Folder.fs === 'Windows' ? "All files:*.*" : "";
var fileToOpen = File.openDialog("Choose file", filterString, false);  // false=single
var files      = File.openDialog("Choose files", filterString, true);  // true=multiple
var folder     = Folder.selectDialog("Choose output directory");

// Read a file
var inFile = new File('/path/to/file.txt');
inFile.encoding = "UTF8";
inFile.open("r", "TEXT", "????");
var contents = inFile.read();
inFile.close();

// Write a file
var outFile = new File('/path/to/output.txt');
outFile.encoding = "UTF8";
outFile.open("w", "TEXT", "????");
outFile.write("content here");
outFile.writeln("line with newline");
outFile.close();

// Check existence
var f = new File('/path/to/file.txt');
if (f.exists) { /* ... */ }

// Desktop path
var desktop = new File("~/Desktop");
var desktopPath = desktop.fsName;
desktop.close();

// File in project directory
var projFile   = new File(app.project.path);
var projDir    = projFile.parent;
var outputPath = projDir + '/' + 'output.xml';
projFile.close();

19. COLLECTIONS — NUMITEMS / NUMTRACKS REFERENCE

Collection Count Property Element Access
ProjectItemCollection .numItems [i]
SequenceCollection .numSequences [i]
TrackCollection (videoTracks/audioTracks) .numTracks [i]
TrackItemCollection (clips/transitions) .numItems [i]
ComponentCollection .numItems [i]
ComponentParamCollection .numItems [i]
MarkerCollection .numMarkers via getFirstMarker() / getNextMarker()
app.projects .numProjects [i]

20. KNOWN ISSUES & GOTCHAS

  1. Ticks vs seconds: Time.ticks is a string (large integer, base-10). Time.seconds is a float. The setPlayerPosition(), importMGT(), etc. take ticks as string. The arithmetic seq.end - seq.zeroPoint works on ticks strings. 1 second = 254,016,000,000 ticks.

  2. app.encoder broken on Mac 14.3.1–15: Use version 22+ for reliable AME integration on Mac.

  3. MOGRT API is After Effects only: Premiere Pro-created MOGRTs do not have scripting support for parameter access.

  4. MOGRT text params are JSON: Many text parameters return a JSON string from getValue(). Parse with JSON.parse(), modify textEditValue and fontTextRunLength, then JSON.stringify() back.

  5. Sequence id vs sequenceID: id is unstable (changes on reopen). Always use sequenceID (UUID) for stable references.

  6. getInPoint() sentinel value: Returns the string "-400000" when no in point is set.

  7. setScaleToFrameSize() scope: This setting only applies to the next insertion; it does not retroactively affect clips already in sequences.

  8. createSubsequence() needs targeting: It uses track targeting (or explicit clip selection) to determine which clips to include. Ensure the right tracks are targeted before calling.

  9. app.enableQE() is undocumented: The QE DOM is not officially documented. Use carefully; it may change between PPro versions.

  10. UXP transition: No new ExtendScript API features will be added. Plan migration to UXP for any long-term projects targeting Premiere Pro beyond September 2026.


SOURCES