I'm trying to figure out how to select all audio tracks inside a folder and color them and route them to the routing folder they are in.
Is this possible? Thanks!
Linked from:
Christian Scheuer @chrscheuer2020-04-02 19:31:16.404ZHi Ignacio,
Yes I believe we could do this. However when you click "Move To New Folder", you should already get an option to click "Route Tracks to New Folder" which should take care of one of the issues.
- NNacho @NSXOR
Thanks! I'm trying to route them to an existing Routing Folder, not a new one
- In reply tochrscheuer⬆:NNacho @NSXOR
The whole thing I'm trying to accomplish is, when prepping a mixing session, to be able to drag and drop audio tracks into folders on my template and have one button on my stream deck color them and route them to the folder they are in
Christian Scheuer @chrscheuer2020-04-02 19:38:56.357ZGotcha, thanks for the clarification - that makes perfect sense.
- SIn reply toNSXOR⬆:Sebastian @Sebastian
Hi, is there a macro for doing this? I have the same situatuion as Ignacio. Selcting tracks and then putting them into already existing routing folders. And as an extra, coloure them in the colour of the routing folder.
Christian Scheuer @chrscheuer2020-04-20 15:14:55.378ZHi everybody.
This script will select all audio tracks in the currently selected folder:
/** * @param {AxPtTrackHeader} track */ function getTrackDepth(track) { return Math.floor((track.titleButton.frame.x - track.frame.x) / 15); } function getTrackFolderStructure() { var root = { children: [] }; var stack = []; stack[0] = root; var flatList = sf.ui.proTools.visibleTrackHeaders.map(t => ({ track: t, depth: getTrackDepth(t) })); for (var i = 0; i < flatList.length; i++) { var flatItem = flatList[i]; var node = { name: flatItem.track.normalizedTrackName, type: flatItem.track.title.value.match(/ - (.*)$/)[1].trim().replace(/track$/i, '').trim().toLowerCase(), track: flatItem.track, children: [] }; stack[flatItem.depth] = node; stack[flatItem.depth - 1].children.push(node); } return root; } function findNearestParentFolder(root, trackName) { var folderStack = []; function walk(node) { var isFolder = node.type && node.type.indexOf('folder') >= 0; if (isFolder) { folderStack.push(node); } if (node.name === trackName) { return folderStack.slice(-1)[0]; } for (var i = 0; i < node.children.length; i++) { var res = walk(node.children[i]); if (res) return res; } if (isFolder) { folderStack.pop(); } } return walk(root); } /** * @return {AxPtTrackHeader[]} */ function getTracksInCurrentFolderOfType(trackType) { sf.ui.proTools.mainWindow.invalidate(); var root = getTrackFolderStructure(); var nearestFolder = findNearestParentFolder(root, sf.ui.proTools.selectedTrack.normalizedTrackName); if (!nearestFolder) return []; return nearestFolder.children.filter(i => i.type === trackType).map(i => i.track); } function selectTracksInCurrentFolderOfType(trackType) { sf.ui.proTools.trackSelectByName({ names: getTracksInCurrentFolderOfType('audio').map(t => t.normalizedTrackName), }); } selectTracksInCurrentFolderOfType('audio');Please note the folder has to be expanded and all tracks visible for it to work.
- NNacho @NSXOR
Thanks Christian, that's awesome, I added
// --------------------- Open Selected Folder sf.ui.proTools.selectedTrack.folderTrackSetOpen({ targetValue: "Enable", });Before the script so I don't have to manually open the folder.
Is there a way to get the folder's input bus as a variable, then run your script to select the audio tracks, and then assign the audio tracks output to the Folder's input bus?
Christian Scheuer @chrscheuer2020-04-20 16:05:14.659ZGreat idea, Nacho.
This script should combine the elements we have so far:
/** * @param {AxPtTrackHeader} track */ function getTrackDepth(track) { return Math.floor((track.titleButton.frame.x - track.frame.x) / 15); } function getTrackFolderStructure() { var root = { children: [] }; var stack = []; stack[0] = root; var flatList = sf.ui.proTools.visibleTrackHeaders.map(t => ({ track: t, depth: getTrackDepth(t) })); for (var i = 0; i < flatList.length; i++) { var flatItem = flatList[i]; var node = { name: flatItem.track.normalizedTrackName, type: flatItem.track.title.value.match(/ - (.*)$/)[1].trim().replace(/track$/i, '').trim().toLowerCase(), track: flatItem.track, children: [] }; stack[flatItem.depth] = node; stack[flatItem.depth - 1].children.push(node); } return root; } function findNearestParentFolder(root, trackName) { var folderStack = []; function walk(node) { var isFolder = node.type && node.type.indexOf('folder') >= 0; if (isFolder) { folderStack.push(node); } if (node.name === trackName) { return folderStack.slice(-1)[0]; } for (var i = 0; i < node.children.length; i++) { var res = walk(node.children[i]); if (res) return res; } if (isFolder) { folderStack.pop(); } } return walk(root); } /** * @return {AxPtTrackHeader[]} */ function getTracksInCurrentFolderOfType(trackType) { sf.ui.proTools.mainWindow.invalidate(); var root = getTrackFolderStructure(); var nearestFolder = findNearestParentFolder(root, sf.ui.proTools.selectedTrack.normalizedTrackName); if (!nearestFolder) return []; return nearestFolder.children.filter(i => i.type === trackType).map(i => i.track); } function selectTracksInCurrentFolderOfType(trackType) { sf.ui.proTools.trackSelectByName({ names: getTracksInCurrentFolderOfType('audio').map(t => t.normalizedTrackName), }); } function getInputPathOfSelectedTrack() { sf.ui.proTools.appActivateMainWindow(); var path = sf.ui.proTools.selectedTrack.inputPathButton.popupMenuFetchAllItems().menuItems.filter(mi => mi.element.isMenuChecked)[0].names; sf.ui.proTools.appActivateMainWindow(); return path; } function main() { //Make sure current folder is open sf.ui.proTools.selectedTrack.folderTrackSetOpen({ targetValue: "Enable", }); //Get the input path of this folder var folderInputPath = getInputPathOfSelectedTrack(); //Select all audio tracks in folder selectTracksInCurrentFolderOfType('audio'); //Route all selected tracks to the folder sf.ui.proTools.selectedTrack.trackOutputSelect({ outputPath: folderInputPath, selectForAllSelectedTracks: true, }); } main();- NNacho @NSXOR
This is working perfectly over here, you have no idea what a time saver this is in my workflow!! THANK YOU!
- In reply tochrscheuer⬆:NNacho @NSXOR
I've been using this for a while and today out of nowhere I'm getting
02.05.2020 12:17:57.40 <info> [Backend]: >> Command: Select Audio Tracks Inside a folder [user:ck932123000040t10jz2ifd8v:ck9pw17gr0000yk10oi13377i] 02.05.2020 12:17:57.41 <info> [Backend]: Executing FolderTrackSetOpenAction 02.05.2020 12:17:57.49 <info> [Backend]: Clicking with mouse here: 72, 30 02.05.2020 12:17:57.49 <info> [Backend]: AppEvent com.avid.ProTools->Activate calling command user:ck8kk2h8f00052210iz1q4lyo:ck8kk2kwa00062210v5yyudu9 02.05.2020 12:17:57.64 <info> [Backend]: Clicking with mouse here: 793, 251 02.05.2020 12:17:57.68 <info> [Backend]: PopupMenu full role:AXMenu 02.05.2020 12:17:57.78 <info> [Backend]: Clicking with mouse here: 72, 30 02.05.2020 12:17:59.78 <info> [Backend]: Javascript error with innerexception of type: null TypeError: track is null (Select Audio Tracks Inside a folder line 7)
Christian Scheuer @chrscheuer2020-05-04 10:55:13.103ZHi Nacho. We need some more info to go on here to understand why that's happening.
Can you show us a screen recording of this happening (often tells us more than descriptions)?- NNacho @NSXOR
Here it is:
Christian Scheuer @chrscheuer2020-05-07 14:12:56.466ZThanks, Nacho. Try replacing the
getTrackDepthfunction with this:/** * @param {AxPtTrackHeader} track */ function getTrackDepth(track) { try { return Math.floor((track.titleButton.frame.x - track.frame.x) / 15); } catch (err) { return 0; } }- NNacho @NSXOR
Thank you Christian, I'm still getting the same error only in some sessions. In some other sessions it works fine.
13.05.2020 09:57:33.54 [Backend]: Javascript error with innerexception: null
TypeError: track is null
(Order EG line 45)