Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

DPX sequence to MOV script with Audio & TC - Batch not working

New Here ,
Jun 29, 2015 Jun 29, 2015

Can please someone here help me out on this topic, i am new to AFX/java scripting and i already spent around 15h on that

subject but it simply does not work-

the background:

we are shooting DPX sequences with a Convergent Design ODYSSEY SSD recorder, thats the only way for it to get perfect

image quality inside the box, i want 4:4:4 and RGB together with minimal compression (and the box is not yet able to do ProRes4444).

For editing/finishing purpose it is way easier to work with .MOV files instead of image sequences (as we are producing around 100.000 DPX files a day,

compared to around 80 .MOV files)

the task:

create a script that imports a DPX sequence from a folder,

imports the corresponding .WAV file with same starting name too,

creates a new timeline in AFX "from DPX sequence selection" (to keep the timcode!)

renders that timeline with a given output module to another given folder

deletes all items and projects afterwards

Somehow, I managed to do that, it works most of the time but function "app.executeCommand(app.findMenuCommandId("New Comp from Selection"

seems to be buggy somehow, does not work everytime or just after you did that at least once manually inside AFX ?

the bonus task (thats where i failed)

create a folder selection dialog that reads all subfolders (with the corresponding DPX sequences inside) to an array

use that array to get the sequence file names and count the number of Sub-directories

do the above (Seq conversion from "the task") to ALL THOSE SUBDIRECTORIES (using the names from the array)

this cant be that complex ... right ???

i tried to implement it but somehow i always get the error "/e/ODYSSEY/S020_AK0787/S020_AK0787_0000000.dpx is not a File or Folder"

(as this is the image sequence that should be imported - there must be some wrong interpretation between the file name with whole filepath and

the import function ?)

Any help is hugely appreciated, i am also willing to donate for help/a working script

(as i cannot afford to enter around 1.000 folders by myself)


i can also provide such a Odyssey file structure for testing/help purposes via wetransfer

thanks

Script below:

_______________________________________________________

var SourceFolder = Folder.selectDialog("Choose SOURCE folder: ");

var SourcePath = decodeURI(SourceFolder.toString()); 

var DestFolder = Folder.selectDialog("Choose DESTINATION folder: ");   

var DestPath = decodeURI(DestFolder.toString()); 

var scriptName = "DPX Sequence TO MOV DNxHD with Audio + TC";

var intendedFootageFPS = 25;

var fileToImport, fileToImport2;sidecarFile, sidecarContents, importOpts, footageItem, filePath, fileBaseName, audioFile, audioFootageItem;

var FolderName, SourcePath;

var scriptName = "Change Render Locations";

function checkForFiles(folderItem, tabString) {

    var theFiles = folderItem.getFiles();

    for(var c = 0; c < theFiles.length; c++){

        //resultArray.push(tabString + theFiles.name + "\r");

        resultArray.push(tabString + theFiles.name);

        //if (theFiles instanceof Folder)

        {

           // checkForFiles(theFiles, tabString + "\t");

        }

    }

}

function AFXConvert(FolderName) {  

   

     app.newProject();

//     fileToImport = File.openDialog("Select file from the DPX sequence", "*.dpx", false);

//    if (!fileToImport || !fileToImport.exists) {

//    }

    app.beginUndoGroup(scriptName);  

     app.project.showWindow = true;

    

     fileToImport2 = (SourcePath + "/"+ e + "/" + e + "_0000000.dpx");

     alert("Folder Import Name " + fileToImport2);

         

     importOpts = new ImportOptions(fileToImport2);

    importOpts.sequence = true;    // import as sequence

    importOpts.forceAlphabetical = true;    // force alphabetical order (to work around 3709647)

  

    

    app.project.importFile(importOpts);

   

     app.executeCommand(app.findMenuCommandId("New Comp from Selection"));

     //app.executeCommand(app.findMenuCommandId("New Comp from Selection")); //sometimes it works better with 2  or 3x ???

     //app.executeCommand(app.findMenuCommandId("New Comp from Selection"));

    footageItem.name = decodeURI(fileToImport2.name).replace(/\.\d+\.png/, "");    // remove the numeric part for the footage item name

    footageItem.mainSource.conformFrameRate = 25;

    // if matching audio recording (WAV file), import that

   

    filePath = footageItem.file.path;

    fileBaseName = (footageItem.file.name).replace("_0000000.dpx","");

    audioFile = new File(filePath + "/" + fileBaseName + ".WAV");

    audioFootageItem = app.project.importFile(new ImportOptions(audioFile));

    comp = app.project.item(1).layers.add(audioFootageItem);

    audioFootageItem.selected = true;

    

    comp.selected = true;        

    comp = app.project.item(1);

    comp.openInViewer();

    app.project.item(1).layer(2).moveToBeginning();

   

    app.endUndoGroup();

   

    app.project.renderQueue.items.add(comp);

    app.project.renderQueue.item(1);

    app.project.renderQueue.item(1).outputModule(1).file = new File("D:/" + e + ".MOV");

    //alert("d:/" + fileBaseName + ".MOV");

    app.project.renderQueue.item(1).outputModule(1).applyTemplate("QUICKTIME DNxHD 365 RGB444 Audio");       

    app.project.renderQueue.item(1).outputModule(1).postRenderAction.NONE;  

    app.project.renderQueue.render(1);

    app.project.renderQueue.item(1).remove()

    app.project.item(1).remove();

    app.project.item(1).remove();

    app.project.item(1).remove();

   

}

//----------------------------------------------------------------------------------------------------------------------------

//PROGRAM START

//----------------------------------------------------------------------------------------------------------------------------

app.project.close(CloseOptions.DO_NOT_SAVE_CHANGES);

if(SourceFolder != null){

    var resultArray = new Array(1);   //clear old array to 1 entry    

    var resultArray = new Array();   

    checkForFiles(SourceFolder, "");

    $.writeln(resultArray.toString().replace("",""));

    //alert(resultArray);

    var FolderCount = resultArray.length; 

    alert("Number of folders: " + FolderCount);   

    }

    if(DestFolder != null){     //Makes sure root folder choice was not canceled 

      var d1 = resultArray.toString();          

    } 

//----ENCODING LOOP  ----------------------------------------------------------

var e = resultArray.shift();

for(var k=0; k<FolderCount; k++){         

              alert("Array/Folder Counter: " + k +":" + e);

              //resultArray.toString(resultArray);            

              fObj = Folder(DestPath + "/"+ e);

              fObj.create();             

              AFXConvert(e);

              var e = resultArray.shift();

             

     }           

TOPICS
Scripting
1.2K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Jul 02, 2015 Jul 02, 2015

It's not exactly what you describe, but it may be a good foundation to modify from. I put this together for my own internal batch processing of DPX sequences into Quicktime movies. There are three variables at the top that need to be manually changed for the render output names and structure. I've also only used this on Mac, so I'm not sure if it works on Windows properly yet.

{

try{

/*

    MANUALLY TYPE IN THE VALUES FOR THE NEXT VARIABLES--------------------

*/

var renderSettingChoice = "Best Settings";

var outputModuleChoice = "Client_LowRezPreview";

var fileNameExpression = "[projectName]_[compName].[fileExtension]";    //Uses After Effects "Output To" syntax

/*

    END USER INPUT--------------------------------------------------------------------------------

*/

var os = ($.os.indexOf("Mac") != (-1));    //True is MAC, false is PC

var sep = (os == true) ? "/" : "\\";

var dpxFolder = Folder.selectDialog("Choose folder containing source DPX folders.");

var renderToFolder = Folder.selectDialog("Select folder to render to.");

var globalFPS = 25;

if(dpxFolder != null){

    if(renderToFolder != null){

        //Declare Variables

        var allSubFolders, allSubFoldersLen, curFolder, dpxFrames, dpxFramesLen, curDPXFrame, nameSplit, dpxFramesCollect, dpxFramesCollectLen, dpxName, dpxDuration, dpxStartFrame, dpxFPS, io, dpxImported, newDPXComp, newQueueItem, fullFilePath;

        allSubFolders = dpxFolder.getFiles();    //Get all files inside folder

        allSubFoldersLen = allSubFolders.length;

        dpxFramesCollect = new Array();

      

        app.beginUndoGroup("Convert DPX to QT");

            //Process Main folder

            for(var f=0; f<allSubFoldersLen; f++){

                dpxFramesCollect.length = 0;

                curFolder = allSubFolders;

                dpxName = curFolder.displayName;

                //Begin per DPX seq processing

                if(curFolder instanceof Folder){    //Verify item is a folder object otherwise skip to next item

                    dpxFrames = curFolder.getFiles();    //Get all DPX frames

                    dpxFramesLen = dpxFrames.length;

                    for(var d=0; d<dpxFramesLen; d++){

                        curDPXFrame = dpxFrames;

                        nameSplit = curDPXFrame.displayName.split(".");

                        ext = nameSplit[nameSplit.length-1];

                        if(ext == "DPX" || ext = "dpx"){    //Verify file is a DPX frame

                            dpxFramesCollect.push(curDPXFrame);

                        }

                    }

                    dpxFramesCollectLen = dpxFramesCollect.length;

                    dpxFramesCollect.sort();

                    if(dpxFramesCollectLen > 0){    //Checks if more than 0 DPX frames exists.

                        firstFrame = dpxFramesCollect[0];

                        dpxFPS = globalFPS;

                      

                        io = new ImportOptions(firstFrame);

                        io.sequence = true;

                        dpxImported = app.project.importFile(io);

                        dpxImported.mainSource.conformFrameRate = dpxFPS;

                      

                        newDPXComp = app.project.items.addComp(dpxName, dpxImported.width, dpxImported.height, dpxImported.pixelAspect, dpxImported.duration, dpxFPS);    //Makes new comp

                            dpxStartFrame = (Number(firstFrame.displayName.split(".")[1]) * newDPXComp.frameDuration) + 0.01;     //0.01 helps fix (mostly) the frameDuration math

                            newDPXComp.displayStartTime = dpxStartFrame;

                        newDPXComp.layers.add(dpxImported);    //Adds footage to comp

                        newQueueItem = app.project.renderQueue.items.add(newDPXComp);    //Adds comp to renderqueue

                        newQueueItem.applyTemplate(renderSettingChoice);

                        newQueueItem.outputModule(1).applyTemplate(outputModuleChoice);

                        fullFilePath = renderToFolder.toString() + sep + dpxName;

                        if(!fullFilePath.exists){    //Creates render folder if it does not already exist

                            Folder(fullFilePath).create();

                        }

                        newQueueItem.outputModule(1).file = File(fullFilePath + sep + fileNameExpression);    //Sets Output To file

                    }

                }

            }

        app.endUndoGroup();

    }else{

        alert("Folder selection for rendering was canceled.");

    }

}else{

    alert("DPX folder selection was canceled.");

}

}catch(e){alert(e.line.toString() + "\n" + e.toString())}

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 03, 2015 Jul 03, 2015

Thank you David, appreciate it!

I will check it out on the weekend and report back to you 🙂

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 06, 2015 Jul 06, 2015

This will not work if the filename has any periods in it:

nameSplit = curDPXFrame.displayName.split(".");

This is a much better way to detect an extension in a filename:

nameSplit = curDPXFrame.displayName.match(/[^\.]+$/);

And this will match regardless of case:

if(ext.toUpperCase() == "DPX"){ 

Cheers,
Lloyd

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Jul 06, 2015 Jul 06, 2015
This will not work if the filename has any periods in it:

Which is why I added the next variable that grabs the last item in that split, but of course neither option will work if the extension is hidden and not part of the name.

ext = nameSplit[nameSplit.length-1];


.match(/[^\.]+$/);

As much as I love to use Regular Expressions, their syntax can be extremely confusing for new learners. Which is why I steer away from it most times. It is powerful stuff though, I will not deny that.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 24, 2017 Feb 24, 2017
LATEST

I'm currently trying to batch some DPX's in folders to Quicktimes (using the folder names as filenames). David's Script looked really useful, but I had a few error messages when I tried to run it (first due to the position of the Undogroup, then afterwards due to it not ignoring mac .DS_Store system files).  I've done some small bug fixes now and here's the updated script, which seems to work OK. I've also moved the "GlobalFPS" variable into the user variable section at the top (should really make that a dialog box too, I guess)

Here's the updated script (tested in CC2017):

{

try{

/*

    MANUALLY TYPE IN THE VALUES FOR THE NEXT VARIABLES--------------------

*/

var renderSettingChoice = "Best Settings";

var outputModuleChoice = "ProRes4444 trillions";  // type in the name of the default output module you want to assign here

var fileNameExpression = "[projectName]_[compName].[fileExtension]";    //Uses After Effects "Output To" syntax

var globalFPS = 24;  // moved this into the user variables - set the correct frame rate here

/*

    END USER INPUT--------------------------------------------------------------------------------

*/

var os = ($.os.indexOf("Mac") != (-1));    //True is MAC, false is PC

var sep = (os == true) ? "/" : "\\";

var dpxFolder = Folder.selectDialog("Choose folder containing source DPX folders.");

var renderToFolder = Folder.selectDialog("Select folder to render to.");

if(dpxFolder != null){

    if(renderToFolder != null){

    

        app.beginUndoGroup("Convert DPX to QT");

        //Declare Variables

        var allSubFolders, allSubFoldersLen, curFolder, dpxFrames, dpxFramesLen, curDPXFrame, nameSplit, dpxFramesCollect, dpxFramesCollectLen, dpxName, dpxDuration, dpxStartFrame, dpxFPS, io, dpxImported, newDPXComp, newQueueItem, fullFilePath;

        allSubFolders = dpxFolder.getFiles();    //Get all files inside folder

        allSubFoldersLen = allSubFolders.length;

        dpxFramesCollect = new Array();

      

            //Process Main folder

            for(var f=0; f<allSubFoldersLen; f++){

                dpxFramesCollect.length = 0;

                curFolder = allSubFolders;

                dpxName = curFolder.displayName;

                //Begin per DPX seq processing

                if(curFolder instanceof Folder){    //Verify item is a folder object otherwise skip to next item

                    dpxFrames = curFolder.getFiles();    //Get all DPX frames

                    dpxFramesLen = dpxFrames.length;

                    for(var d=0; d<dpxFramesLen; d++){

                        curDPXFrame = dpxFrames;

                        nameSplit = curDPXFrame.displayName.split(".");

                        ext = nameSplit[nameSplit.length-1];

                        if(ext == "DPX" || ext = "dpx" && ext != "DS_Store"){    //Verify file is a DPX frame

                            dpxFramesCollect.push(curDPXFrame);

                        }

                    }

                    dpxFramesCollectLen = dpxFramesCollect.length;

                    dpxFramesCollect.sort();

                    if(dpxFramesCollectLen > 0){    //Checks if more than 0 DPX frames exists.

                        firstFrame = dpxFramesCollect[0];

                        dpxFPS = globalFPS;

                      

                        io = new ImportOptions(firstFrame);

                        io.sequence = true;

                        dpxImported = app.project.importFile(io);

                        dpxImported.mainSource.conformFrameRate = dpxFPS;

                      

                        newDPXComp = app.project.items.addComp(dpxName, dpxImported.width, dpxImported.height, dpxImported.pixelAspect, dpxImported.duration, dpxFPS);    //Makes new comp

                            dpxStartFrame = (Number(firstFrame.displayName.split(".")[1]) * newDPXComp.frameDuration) + 0.01;    //0.01 helps fix (mostly) the frameDuration math

                            newDPXComp.displayStartTime = dpxStartFrame;

                        newDPXComp.layers.add(dpxImported);    //Adds footage to comp

                        newQueueItem = app.project.renderQueue.items.add(newDPXComp);    //Adds comp to renderqueue

                        newQueueItem.applyTemplate(renderSettingChoice);

                        newQueueItem.outputModule(1).applyTemplate(outputModuleChoice);

                        fullFilePath = renderToFolder.toString() + sep + dpxName;

                        if(!fullFilePath.exists){    //Creates render folder if it does not already exist

                            Folder(fullFilePath).create();

                        }

                        newQueueItem.outputModule(1).file = File(fullFilePath + sep + fileNameExpression);    //Sets Output To file

                    }

                }

            }

        app.endUndoGroup();

    }else{

        alert("Folder selection for rendering was canceled.");

    }

}else{

    alert("DPX folder selection was canceled.");

}

}catch(e){alert(e.line.toString() + "\n" + e.toString())}

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines