No internet connection
  1. Home
  2. How to

How to select specific type of tracks inside a folder

By Nacho @NSXOR
    2020-04-02 19:16:47.922Z

    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!

    Solved in post #9, click to view
    • 14 replies

    There are 14 replies. Estimated reading time: 12 minutes

    1. Hi 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.

      1. NNacho @NSXOR
          2020-04-02 19:32:09.610Z

          Thanks! I'm trying to route them to an existing Routing Folder, not a new one

          1. In reply tochrscheuer:
            NNacho @NSXOR
              2020-04-02 19:35:39.272Z

              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

              1. Gotcha, thanks for the clarification - that makes perfect sense.

            • S
              In reply toNSXOR:
              Sebastian @Sebastian
                2020-04-20 13:37:38.604Z

                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.

                1. Hi 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.

                  1. NNacho @NSXOR
                      2020-04-20 15:49:57.823Z

                      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?

                      1. Great 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();
                        
                        ReplySolution
                        1. NNacho @NSXOR
                            2020-04-20 16:11:40.010Z

                            This is working perfectly over here, you have no idea what a time saver this is in my workflow!! THANK YOU!

                            1. In reply tochrscheuer:
                              NNacho @NSXOR
                                2020-05-02 17:19:00.124Z2020-05-02 19:18:25.369Z

                                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) 
                                
                                1. Hi 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)?

                                  1. NNacho @NSXOR
                                      2020-05-04 13:15:54.122Z

                                      Here it is:

                                      1. Thanks, Nacho. Try replacing the getTrackDepth function with this:

                                        /**
                                         * @param {AxPtTrackHeader} track
                                         */
                                        function getTrackDepth(track) {
                                            try {
                                                return Math.floor((track.titleButton.frame.x - track.frame.x) / 15);
                                            } catch (err) {
                                                return 0;
                                            }
                                        }
                                        
                                        1. NNacho @NSXOR
                                            2020-05-13 14:57:53.747Z

                                            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)