No internet connection
  1. Home
  2. How to

Use Soundflow to change each track color in Pro Tools?

By Kenneth Vasko @Kenneth_Vasko
    2025-07-24 03:10:48.996Z

    I have a list of colors someone gives me, for instance:
    Track 1 - RED
    Track 2 - BLUE
    Track 3 - GREEN

    And i haven't been able to come up with a good script to select each track, change the color, and move on to the next track.

    I can get SoundFlow to read the list, like a JSON file, but i can't make it actually change the colors with any sort of rhyme or reason. In some cases i've gotten it to change ALL tracks to one color, or some random one to purple.

    I thought this would be simple but maybe it's much more complex than i'm giving it credit for? Thanks in advance for any insight!

    Solved in post #6, click to view
    • 4 replies
    1. K
      In reply toKenneth_Vasko:
      Kenneth Vasko @Kenneth_Vasko
        2025-07-24 03:45:20.960Z
        
          const exportFile = '/Users/Shared/SessionSync/latest_export.json';
        
          try {
              const data = sf.file.readJson({ path: exportFile }).json;
        
              if (data && data.tracks) {
                  // Rename first (this works)
                  const selectedNames = Array.from(sf.ui.proTools.selectedTrackNames);
                  selectedNames.forEach((oldName, index) => {
                      if (index < data.tracks.length) {
                          sf.app.proTools.renameTrack({
                              oldName: oldName,
                              newName: data.tracks[index].name
                          });
                      }
                  });
        
                  // Apply colors one by one
                  setTimeout(() => {
                      // Try alternative activation methods
                      try {
                          // Method 1: Use app bundle ID
                          sf.ui.app('com.avid.ProTools').appActivateMainWindow();
                      } catch (e) {
                          // Method 2: Use menu click to ensure focus
                          sf.ui.proTools.menuClick({ menuPath: ['Window', 'Edit'] });
                      }
        
                      // Add wait for activation
                      sf.wait({ intervalMs: 200 });
        
                      // Process each track sequentially
                      let currentIndex = 0;
        
                      function processNextTrack() {
                          if (currentIndex < data.tracks.length) {
                              const track = data.tracks[currentIndex];
        
                              if (track.colorParams) {
                                  // Select the track
                                  sf.ui.proTools.trackSelectByName({
                                      names: [track.name]
                                  });
        
                                  // Wait before applying color
                                  sf.wait({ intervalMs: 100 });
        
                                  // Apply color
                                  sf.ui.proTools.colorsSelect({
                                      colorBrightness: track.colorParams.colorBrightness,
                                      colorNumber: track.colorParams.colorNumber
                                  });
        
                                  // Move to next track
                                  currentIndex++;
                                  setTimeout(processNextTrack, 300);
                              } else {
                                  // Skip tracks without color
                                  currentIndex++;
                                  processNextTrack();
                              }
                          }
                      }
        
                      // Start processing
                      processNextTrack();
        
                  }, 2000);
              }
          } catch (error) {
              // Error
          }
        
        '''
        
        1. It would be much easier to fix / refactor your script if you could provide an example of the /Users/Shared/SessionSync/latest_export.json file or the data.tracks object.
          Thanks!

        2. In reply toKenneth_Vasko:
          Matt Friedman @Matt_Friedman
            2025-07-24 15:31:20.714Z2025-07-24 15:47:38.979Z

            That is super over the top. You could just update your existing foreach loop at the top into this:

            const selectedNames = Array.from(sf.ui.proTools.selectedTrackNames);
            selectedNames.forEach((oldName, index) => {
                if (index < data.tracks.length) {
                    const newName = data.tracks[index].name;
                    const colorBrightness = data.tracks[index].colorParams.colorBrightness;
                    const colorNumber = data.tracks[index].colorParams.colorNumber;
            
                    // Select the track
                    sf.app.proTools.selectTracksByName({
                        selectionMode: "Replace",
                        trackNames: [oldName]
                    })
            
                    // Rename the track
                    sf.app.proTools.renameTrack({
                        oldName,
                        newName,
                    });
            
                    // Wait for name to complete (may not be needed)
                    sf.waitFor({
                        callback: () => sf.ui.proTools.selectedTrackNames[0] === newName,
                        timeout: 2000
                    })
            
                    // Change track color
                    sf.ui.proTools.colorsSelect({
                        colorBrightness,
                        colorNumber,
                    });
            
                    // Wait for color to complete (may not be needed)
                    sf.ui.proTools.colorPaletteWindow.elementWaitFor({waitForNoElement: true})
                }
            });
            
            1. K
              In reply toKenneth_Vasko:
              Kenneth Vasko @Kenneth_Vasko
                2025-07-31 01:08:20.149Z

                For anyone else looking, here's a version that works pretty consistently! Thanks all for your contribution/insight.

                if (data && data.tracks) {
                // Ensure Pro Tools has focus
                sf.ui.proTools.appActivateMainWindow();
                sf.wait({ intervalMs: 2000 });

                  // FOOLPROOF SELECTION: Simplified approach
                  function selectAllVisibleTracks() {
                      // First deselect all
                      sf.ui.proTools.trackDeselectAll();
                      sf.wait({ intervalMs: 300 });
                
                      // Get all visible track headers
                      const visibleTracks = sf.ui.proTools.visibleTrackHeaders;
                
                      if (visibleTracks && visibleTracks.length > 0) {
                          // Option+click on the first visible track to select all
                          visibleTracks[0].titleButton.mouseClickElement({ isOption: true });
                      }
                  }
                
                  // Select all tracks
                  selectAllVisibleTracks();
                  sf.wait({ intervalMs: 1000 });
                
                  // Now get the names of ALL selected tracks
                  const selectedNames = Array.from(sf.ui.proTools.selectedTrackNames);
                
                  // Process each track one by one
                  selectedNames.forEach((oldName, index) => {
                      if (index < data.tracks.length) {
                          const track = data.tracks[index];
                
                          // Skip if no color parameters
                          if (!track.colorParams) return;
                
                          // Select the track by its current name
                          sf.app.proTools.selectTracksByName({
                              selectionMode: "Replace",
                              trackNames: [oldName]
                          });
                
                          sf.wait({ intervalMs: 200 });
                
                          // Rename if needed
                          if (oldName !== track.name) {
                              sf.app.proTools.renameTrack({
                                  oldName: oldName,
                                  newName: track.name
                              });
                
                              sf.wait({ intervalMs: 300 });
                          }
                
                          // Apply color
                          sf.ui.proTools.colorsSelect({
                              colorBrightness: track.colorParams.colorBrightness,
                              colorNumber: track.colorParams.colorNumber
                          });
                
                          sf.wait({ intervalMs: 200 });
                      }
                  });
                
                  // Select all tracks at the end to show the result
                  selectAllVisibleTracks();
                

                }

                ReplySolution