No internet connection
  1. Home
  2. Macro and Script Help

Improving Stability of Track Workflow Automation Script in Pro Tools

By STEPHANE BRIAND @STEPHANE_BRIAND
    2025-06-05 16:43:18.510Z2025-06-05 21:01:13.428Z

    Hi,

    I’m reaching out for assistance with a SoundFlow script I’ve written to automate several actions in Pro Tools. While the core functionality is in place, the script is currently unstable and doesn’t consistently execute all the intended steps. I’d really appreciate your help in making it more reliable and efficient.

    Here’s what the script is meant to do:

    Change the color of selected tracks to a desired one.
    Move the selected track(s) to a specific folder track.
    Assign the selected track(s) to a specific group.

    Below is the current version of the script:

    sf.ui.proTools.appActivateMainWindow();
    
    sf.ui.proTools.colorsSelect({
        colorBrightness: "Light",
        colorNumber: 9,
    });
    
    sf.ui.proTools.selectedTrack.trackOutputSelect({
        outputPath: ["bus", "bus menu 1-128", "01_STEM (Stereo)"],
        selectForAllSelectedTracks: true,
    });
    
    sf.ui.proTools.selectedTrack.titleButton.popupMenuSelect({
        isRightClick: true,
        menuPath: ["Move to...", "01_STEM"]
    });
    
    sf.keyboard.press({
        keys: "ctrl+cmd+g",
    });
    sf.ui.proTools.windows.whoseTitle.is('Modify Groups').first.popupButtons.whoseTitle.is('GroupIDView').first.popupMenuSelect({
        menuPath: ["4", "b - VCA 01 (VCA 01)"],
        targetValue: "Enable",
    });
    sf.ui.proTools.windows.whoseTitle.is("Modify Groups").first.buttons.whoseTitle.is("Add").first.elementClick();
    sf.ui.proTools.windows.whoseTitle.is("Modify Groups").first.buttons.whoseTitle.is("OK").first.elementClick();
    

    Could you help me identify what might be causing the instability and how best to improve the flow, especially with handling UI delays or element availability?

    Thanks in advance for your support!

    • 2 replies
    1. Chris Shaw @Chris_Shaw2025-06-08 20:48:01.020Z2025-06-09 18:33:35.340Z

      Hey @STEPHANE_BRIAND,

      I refactored the script so that it can be reused by changing the constants at the start of the script.
      I make use of the menuSelector function inside of the popupMenuSelect functions to filter the popup menu items so it selects the menu path of your desired folder input, "Move to..." folder, and VCA group name.
      Additionally there are a couple of mainWindow.invalidate() calls to refresh the cache to ensure stability and I swapped keyboard presses with menu select commands.

      // CONSTANTS
      const targetFolderName = "01_STEM"
      const targetVcaName = "VCA 01"
      
      /**
       * @typedef {Object} TrackColor
       * @property {"Light" | "Medium" | "Dark"} colorBrightness - Brightness level of the track color.
       * @property {number} colorNumber - Numeric identifier for the track color (typically 1–127).
       */
      
      /** @type {TrackColor} */
      const newTrackColor = {
          colorBrightness: "Light",
          colorNumber: 9,
      };
      
      
      // Main //
      sf.ui.proTools.appActivateMainWindow();
      sf.ui.proTools.mainWindow.invalidate();
      
      sf.ui.proTools.selectedTrack.trackScrollToView()
      
      // Set selected tracks' color
      sf.ui.proTools.colorsSelect(newTrackColor);
      
      // Set track outputs to folder input
      sf.ui.proTools.selectedTrack.outputPathButton.popupMenuSelect({
          menuPath:[`track`,`${targetFolderName}*`],
          useWildcards:true,
          isShift: true,
          isOption: true
      })
      
      // We need to refresh main window cache because values have changed
      sf.ui.proTools.mainWindow.invalidate()
      
      // Move tracks to target folder by finding popup menu item that contains target folder's name
      sf.ui.proTools.selectedTrack.titleButton.popupMenuSelect({
          isRightClick: true,
          menuSelector: items => items.find(i => i.path[0] == "Move to..." && i.path[1] && i.path[1].endsWith(targetFolderName)),
      },);
      
      // Tracks have moved so we need to refresh the main window cache
      sf.ui.proTools.mainWindow.invalidate()
      
      // Open Modify Groups window
      sf.ui.proTools.mainWindow.groupListPopupButton.popupMenuSelect({
          menuPath: ["Modify Groups"]
      })
      
      // Define Modify Groups window
      const modifyGroupsWindow = sf.ui.proTools.windows.whoseTitle.is('Modify Groups').first;
      
      // Wait for Modify Groups window
      modifyGroupsWindow.elementWaitFor()
      
      // Define Modify Groups window buttons
      const groupAddButton = modifyGroupsWindow.buttons.whoseTitle.is("Add").first
      const groupIdViewButton = modifyGroupsWindow.popupButtons.whoseTitle.is('GroupIDView').first
      
      /// Wait for "Add" button to be enabled before proceeding
      sf.waitFor({
          callback: () => groupAddButton.invalidate().isEnabled
      })
      
      // Get current groupID view button value (for later comparison)
      const originalGroupIdViewButtonValue = groupIdViewButton.value.invalidate().value
      
      // Select target VCA group from popup menu by filtering popup items for the one that contains the target VCA's group name
      groupIdViewButton.popupMenuSelect({
          menuSelector: items => items.find(i => i.path[1] && i.path[1].endsWith(`(${targetVcaName})`)),
          targetValue: "Enable",
      });
      
      // Wait for groupID button value to change
      sf.waitFor({
          callback: () => groupIdViewButton.value.invalidate().value !== originalGroupIdViewButtonValue
      })
      
      //Add tracks to group and close Modify Groups window
      groupAddButton.elementClick();
      
      modifyGroupsWindow.buttons.whoseTitle.is("OK").first.elementClick();
      
      1. S
        In reply toSTEPHANE_BRIAND:
        STEPHANE BRIAND @STEPHANE_BRIAND
          2025-06-09 16:45:41.007Z

          Hi Chris,

          Thanks a lot for the updated script — I really appreciate the time and effort you put into refactoring it!
          This will definitely make my workflow smoother. Thanks again for sharing it!
          I’ll test it out tomorrow and let you know how it goes.

          Thanks again!

          Best,
          Stéphane