How to sort clip name and checkerboard on defined tracks
So here's a challenge. I'm a dialogue editor and looking for ways to speed up certain aspects of my workflow. Would it be possible for SoundFlow to run a script or macro that, for a given selection (ie a scene), will read the clip names (in this case slate numbers) from conform tracks (total 3 or 4 tracks) and copy the clips to specific tracks (DX1 - DX6) placing each clip on a track with lowest number clip on DX1 and highest number on DX6? I'm thinking it'll need a "read all clip names", remember the lowest within range then set of "if" statements e.g. if clip 1 = lowest number place on track DX1. A potential issue here is that not all clip names may be sequential, one or 2 numbers may be skipped before next used slate number in a scene. To further improve this idea, it would be nice to have a command line for "for current scene" and uses a "Scene" track with a clip group per scene to indicate length of current scene. Would clip indexing within a variable be the best way to "learn" the clip names? Thanks in advance.
Linked from:
- Christian Scheuer @chrscheuer2020-10-16 13:12:21.333Z
Hi Iain,
This sounds like a potential very cool piece of automation, but also one that would be fairly complex to set up.
I think I understand most of your intention, but is there any way you could illustrate this with an example screenshot, where this approach has been executed manually? It would be great to see a "before" and "after" of a small section of dialogue tracks where you have applied this process manually, so we can better visualize the steps needed and the potential corner cases.- IIain Anderson @Iain_Anderson
Hi Christian, lovely to have you onboard. Please see attached screenshots for before and after clip split.
Conform track and Dialogue track destinations before clip split...
Here's the track layout after manual clip split.
Hope this helps. Excited to see the outcome of this.
Cheers,
Iain
- In reply tochrscheuer⬆:IIain Anderson @Iain_Anderson
Hey Christian, thanks for your little nuggets of help over the last few days. Here's my first go at a similar idea. Not finished yet but close!
Any suggestions welcome!
Cheers,
Iain
var c = parseFloat(TrCount) sf.ui.proTools.appActivate(); sf.wait({ intervalMs: 100 }); function getclipName() { //Make sure we have no search in Clips list - if we had, Clip Rename won't work (Pro Tools bug) sf.keyboard.press({ keys: 'cmd+shift+d' }); //Clip Clip->Rename... sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] }); //Wait for 'Name' dialog to come up, assign the dialog to dlg variable var dlg = sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({}, 'Could not find "Name" dialog').element; //Find the first text field var textField = dlg.groups.whoseTitle.is('Name').first.textFields.first; //Get the current Name var clipName = textField.value.value; //Close Window dlg.buttons.whoseTitle.is('Cancel').first.elementClick(); //Wait for the dialog to close dlg.elementWaitFor({ waitForNoElement: true }); return clipName; } function getslateNumber() { //Extract slateNumber var str = getclipName(); var slateNumber = str.split("T")[0]; return slateNumber; } function getslateLast() { //Extract last number of slateNumber var str = getslateNumber(); var slateLast = str.slice(-1); return slateLast; } function clipSplit() { sf.ui.proTools.appActivateMainWindow(); const originalTracks = sf.ui.proTools.selectedTrackNames; let slateLast = getslateLast(); sf.ui.proTools.menuClick({ menuPath: ["Edit", "Cut"], }); if (slateLast == "0") { sf.ui.proTools.trackSelectByName({ names: ["Slate 10"], }); } else { sf.ui.proTools.trackSelectByName({ names: ["Slate " + slateLast], }); } sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"], }); sf.ui.proTools.trackSelectByName({ names: originalTracks }); } clipSplit(); for (var counter = 1; counter <= c; counter++) { sf.wait({ intervalMs: 50 }); sf.ui.proTools.clipDoForEachClipInTrack({ action: clipSplit, }); sf.wait({ intervalMs: 50 }); sf.keyboard.press({ keys: 'semicolon' }); sf.wait({ intervalMs: 50 }); }
Christian Scheuer @chrscheuer2020-10-20 22:30:59.278Z
Without having tested my change, I'd refactor it to this:
function getClipName() { //Make sure we have no search in Clips list - if we had, Clip Rename won't work (Pro Tools bug) sf.keyboard.press({ keys: 'cmd+shift+d' }); //Clip Clip->Rename... sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] }); //Wait for 'Name' dialog to come up, assign the dialog to dlg variable var dlg = sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({}, 'Could not find "Name" dialog').element; //Find the first text field var textField = dlg.groups.whoseTitle.is('Name').first.textFields.first; //Get the current Name var clipName = textField.value.value; //Close Window dlg.buttons.whoseTitle.is('Cancel').first.elementClick(); //Wait for the dialog to close dlg.elementWaitFor({ waitForNoElement: true }); return clipName; } function getSlateNumberTrimmed() { //Extract slateNumber var str = getClipName(); var slateNumber = str.split("T")[0]; return slateNumber.replace(/^0*/, ''); } function splitClip() { const originallySelectedTrackNames = sf.ui.proTools.selectedTrackNames; let slateLast = getSlateNumberTrimmed(); sf.ui.proTools.menuClick({ menuPath: ["Edit", "Cut"], }); sf.ui.proTools.trackSelectByName({ names: ["Slate " + slateLast], }); sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"], }); sf.ui.proTools.trackSelectByName({ names: originallySelectedTrackNames }); } function splitClipsOnTrack(trackName) { //Select the track with name trackName sf.ui.proTools.trackSelectByName({ names: [trackName], deselectOthers: true, }); //Loop through all clips in this track, running splitClip sf.ui.proTools.clipDoForEachClipInTrack({ action: splitClip, }); } function main() { sf.ui.proTools.appActivateMainWindow(); //Store originally selected track names let selectedTrackNames = Array.from(sf.ui.proTools.selectedTrackNames); //For each track name, run splitClipsOnTrack selectedTrackNames.forEach(splitClipsOnTrack); } main();
- In reply tochrscheuer⬆:IIain Anderson @Iain_Anderson
Hi Christian, after a lot of head scratching, googling and very useful help from this forum, i think i've got the script pretty close.
This script will read the Scene Number for each clip (that's where my slate number is kept in ProTools besides Clip name), add it to an array, sort that array into ascending order and copy each clip to a track that matches the position of that scene number within the sorted array.
Pretty pleased with the outcome but if there are any handy tips to tidy up the script i'd love to hear them.
My next phase would be to work out a quicker way to get the slate number of all the clips . Suggestions welcome.
Cheers,
Iain
//Make sure we have no search in Clips list - if we had, Clip Rename won't work (Pro Tools bug) sf.keyboard.press({ keys: 'cmd+shift+d' }); //Clip Clip->Rename... sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] }); //Wait for 'Name' dialog to come up, assign the dialog to dlg variable var dlg = sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({}, 'Could not find "Name" dialog').element; //Get the scene number from clip info var sceneNumber = sf.ui.proTools.windows.whoseTitle.is('Name').first.groups.whoseTitle.is('Clip Info').first.children.whoseRole.is("AXStaticText").allItems[11].value.invalidate().value; //Close Window dlg.buttons.whoseTitle.is('Cancel').first.elementClick(); //Wait for the dialog to close dlg.elementWaitFor({ waitForNoElement: true }); return sceneNumber; } function addtoclipSlates() { //Add sceneNumber to clipSlates array var str = getsceneNumber(); //sceneNumber only gets added to array if it doesn't already exist if (!clipSlates.includes(str)) { clipSlates.push(str) }; return clipSlates; } function copytoTrack() { sf.ui.proTools.menuClick({ menuPath: ["Edit", "Copy"], }); //Get sceneNumber var slateNumber = getsceneNumber(); //target track will be the position of the slateNumber in the slatesAscend array var targetTrack = slatesAscend.indexOf(slateNumber) + 1; var dxTrack = "DX " + targetTrack; let pasteTrack = dxTrack; sf.ui.proTools.trackSelectByName({ names: [pasteTrack], }); sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"], }); sf.ui.proTools.trackSelectByName({ names: originalTrack }); return; } sf.ui.proTools.appActivate(); sf.ui.proTools.mainWindow.invalidate(); var clipSlates = []; //Create an empty array sf.ui.proTools.clipDoForEachSelectedClip({ action: addtoclipSlates, }); let numbers = clipSlates; var slatesAscend = numbers.sort((a, b) => a - b); const originalTrack = sf.ui.proTools.selectedTrackNames; sf.ui.proTools.clipDoForEachSelectedClip({ action: copytoTrack, });
- IIain Anderson @Iain_Anderson
And here's a low res screen recording of it in action.
Set to copy clips for now but will change to cut and paste.
Would like to speed up the process of "learing" the slate names but happy otherwise.
Christian Scheuer @chrscheuer2020-10-22 11:23:09.084Z
Really cool Iain!
To get the slate numbers quicker, perhaps automating export the session info to text and then reading that file could do the trick for you? If you switch to Samples first, then the info in the session info text file will be in samples.
There should be a lot of inspiration to find on how to do this in this thread: