// Replace highlighted footage with footage from a folder of your choice - useful for conforming an online from an AVID edit imported via Automatic Duck! // Orginally created by Dan Sollis, 22nd April 2009. // Updated 9th March 2011 to replace deprecated File I/O dialog code and add user options for search string lengths. // revised 29 April 2012 to add recursive search through subfolders // // For more info, visit WWW.DIGITALDISTORTION.NET // Footage being replaced must have the same name - or portion of name - as the replacement files (string search length defined by user) // create undo group { app.beginUndoGroup("replace selected footage"); // setup recursive function to find footage function searchAndReplaceFile(projectItemToBeReplaced, searchLocation,nameSearchLengthMax, filenameExtension) { // get name of project item for search string and make lowercase var fileSearchString = projectItemToBeReplaced.name.toLowerCase(); // shorten search string to user defined length - helpful when AVID or other systems decide to mangle original long filenames in a project! fileSearchString = fileSearchString.substring(0,(nameSearchLengthMax+1)); // list all files in search location and add to array var onlineFileArray = searchLocation.getFiles(); // iterate through all and search for file with matching name, or folder for (var p = 0; p < onlineFileArray.length; p++) { var curFileItem = onlineFileArray[p]; // if item in file array is a a file if(curFileItem instanceof File) { // get name of file and make lower case to simplify search var curFileItemName = curFileItem.name.toLowerCase(); // if the filename of the online file exists as a string in the name of the offline proxy AND contains the correct file extension... if (curFileItemName.indexOf(fileSearchString) != -1 && curFileItemName.indexOf(filenameExtension) != -1) { //...then replace the project item with this new file onlineFileArray[p].open("r"); projectItemToBeReplaced.replace(curFileItem); writeLn ("replaced item " + projectItemToBeReplaced.name + " with " + curFileItemName); } } else if (curFileItem instanceof Folder) { writeLn ("searching folder " + curFileItem.name); searchAndReplaceFile(projectItemToBeReplaced, curFileItem, nameSearchLengthMax, filenameExtension); } } } // get highlighted project items var footageToReplace = app.project.selection; // get source of replacement media var replacementMediaFolder = Folder.selectDialog("Point me to the folder containing the replacement media"); // ask user for length of search strings var filenameSearchLengthMax = parseInt(prompt("How many characters in the filename should be used for searching? (default is 16)", filenameSearchLengthMax)); // catch errors - zero or less, non numeric entry if (filenameSearchLengthMax <= 0 || filenameSearchLengthMax == "undefined") { filenameSearchLengthMax = 16; } // reduce searchLength by 1, so it works with indexing starting at 0 filenameSearchLengthMax -= 1; // ask user for file extension type (and check if they add a "." before or leave blank) var filenameExtension = prompt("what file extension does the replacement media have? eg. '.mxf', '.mov'", filenameExtension); if (filenameExtension.indexOf(".") == -1) { filenameExtension = "." + filenameExtension } else if (filenameExtension == "undefined") { filenameExtension = "" } // main loop - calls recursive function for (var i = 0; i < footageToReplace.length; i++) { // check if current project item is footage, otherwise skip if (footageToReplace[i] instanceof FootageItem) { // Call a recursive function!! find the matching footage file on disk (if there is one) using the supplied item name searchAndReplaceFile(footageToReplace[i], replacementMediaFolder, filenameSearchLengthMax,filenameExtension); } } app.endUndoGroup(); }