Skip to content

Instantly share code, notes, and snippets.

@johndyer
Last active November 9, 2018 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johndyer/84bdc1a0c18a428703d6d67922dfd17f to your computer and use it in GitHub Desktop.
Save johndyer/84bdc1a0c18a428703d6d67922dfd17f to your computer and use it in GitHub Desktop.
Export still from Adobe Premiere Pro CC based on markers
/*
name: DTS Export Markers
description: exports markers into JPGs and creates XML in a format DTS's video player can read
author: John Dyer
created: 2017-04-07
updated: 2017-04-11
version 1.0.1
references:
http://cssdk.s3-website-us-east-1.amazonaws.com/sdk/2.1/docs/WebHelp/references/csawlib/com/adobe/premiere/package-detail.html
https://github.com/Adobe-CEP/Samples/blob/master/PProPanel/jsx/Premiere.jsx
Change Log
2017-04-11 - 1.0.1
* Filenames now based on Sequence name rather than Project name
* Tried using a Folder dialog prompt but decided not to
* Discovered the JPG output only likes to go to /Volume/ but not other locations
*/
// get the project and markers objects
var project = app.project;
var activeSequence = project.activeSequence;
var markers = activeSequence.markers;
// find the path to the project and it's name
var projectPath = app.project.path;
projectPath = projectPath.substring(0, projectPath.lastIndexOf('/')) + '/slides/';
/*
OPTIONAL: Ask user for output directory
var userChosenPath = Folder.selectDialog("Choose output folder");
userChosenPath += "/";
*/
var outputPath = projectPath;
// create output directory if it doens't exist
var outputFolder = new Folder(outputPath);
if (!outputFolder.exists) {
outputFolder.create();
}
// convert sequence name (CCC_UUU_VVV_otherstuff to just CCC_UUU_VVV)
var sequenceFilename = activeSequence.name;
var filenameParts = sequenceFilename.split('_');
var slideFilenamePrefix = filenameParts[0] + '_' + filenameParts[1] + '_' + filenameParts[2];
// start the XML output (DTS specific)
var xmlOutput = '<?xml version="1.0" encoding="utf-8"?>\n<slides>\n';
var xmlFilename = slideFilenamePrefix + '_slides.xml';
// spin through the markers and make XML
var numMarkers = markers.numMarkers;
if (numMarkers > 0) {
var marker_number = 1;
for(var current_marker = markers.getFirstMarker();
current_marker !== undefined;
current_marker = markers.getNextMarker(current_marker)){
var timecode = convertSecondsToTimecode( parseFloat( current_marker.start.seconds ), true),
slideFilename = slideFilenamePrefix + '_s' + padLeft(marker_number.toString(), '0', 3) + '.jpg';
// add to XML
xmlOutput += '\t<cue timeCode="' + timecode + '" slideFileName="' + slideFilename + '" />\n';
// create thumbnail
activeSequence.setPlayerPosition(current_marker.start.ticks);
exportThumbnail (outputPath + slideFilename);
marker_number = marker_number + 1;
}
}
xmlOutput += '</slides>';
// SAVE output
var file = new File(outputPath + xmlFilename);
file.encoding = "UTF8";
file.open("w", "TEXT", "????");
file.write(xmlOutput);
file.close();
// DONE!!
function exportThumbnail(imageFilePath) {
app.enableQE();
var activeSequence = qe.project.getActiveSequence(); // note: make sure a sequence is active in PPro UI
if (activeSequence) {
var time = activeSequence.CTI.timecode; // CTI = Current Time Indicator.
activeSequence.exportFrameJPEG(time, imageFilePath);
} else {
$.writeln("Active sequence required.");
}
}
function convertSecondsToTimecode(seconds, forceHours) {
//seconds = Math.round(seconds);
var hours = null,
minutes = Math.floor(seconds / 60);
if (seconds < 60) {
minutes = 0;
}
if (minutes >= 60) {
hours = Math.floor(minutes / 60);
minutes = minutes % 60;
} else {
hours = 0;
}
var printHours = (hours == null) ? '00' : (hours >= 10) ? hours : "0" + hours;
var printMinutes = (minutes >= 10) ? minutes : "0" + minutes;
var printSeconds = seconds % 60;
printSeconds = (printSeconds >= 10) ? printSeconds.toString() : "0" + printSeconds;
if (printSeconds.length > 4) {
printSeconds = printSeconds.substring(0,4);
}
return ((hours > 0 || forceHours === true) ? printHours + ':' : '') + printMinutes + ':' + printSeconds;
}
function padLeft(value, charToPad, length) {
return (value.toString().length < length) ? padLeft(charToPad+value, charToPad, length):value;
}
@sml920505
Copy link

hi how to install this jsx in adobe Pr? thanks

@sml920505
Copy link

sml920505 commented Nov 9, 2018

I found your blog blog
and tried the Extendscript toolkit...
but when I click the "run button"
the code only automated export the .xml file in "/slides",
like
"

<?xml version="1.0" encoding="utf-8"?>
<slides>
	<cue timeCode="00:00:06.2" slideFileName="让人有代入感,和自己产生关联的广告 - YouTube_undefined_undefined_s001.jpg" />
	<cue timeCode="00:00:07.4" slideFileName="让人有代入感,和自己产生关联的广告 - YouTube_undefined_undefined_s002.jpg" />
	<cue timeCode="00:00:11.6" slideFileName="让人有代入感,和自己产生关联的广告 - YouTube_undefined_undefined_s003.jpg" />
	<cue timeCode="00:00:15.5" slideFileName="让人有代入感,和自己产生关联的广告 - YouTube_undefined_undefined_s004.jpg" />
	<cue timeCode="00:00:18.8" slideFileName="让人有代入感,和自己产生关联的广告 - YouTube_undefined_undefined_s005.jpg" />
	<cue timeCode="00:00:23.0" slideFileName="让人有代入感,和自己产生关联的广告 - YouTube_undefined_undefined_s006.jpg" />
</slides>

but I can't find any image file in the /slides ...
I am using the Adobe Pr 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment