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

Split Selected Clips at Specified Marker Track

By Curtis Macdonald @Curtis_Macdonald
    2025-05-02 18:42:21.012Z

    Title

    Split Selected Clips at Specified Marker Track

    What do you expect to happen when you run the script/macro?

    Hello! Script works, but splits selected clips based on all marker rulers in Pro Tools. Is it possible to use this script so that it splits clips based off a specified marker timeline? Marker 1, Marker 2, etc? Thank you!

    Are you seeing an error?

    What happens when you run this script?

    Clips are separated at all markers in session instead of a secified marker lane

    How were you running this script?

    I used a keyboard shortcut within the target app

    How important is this issue to you?

    4

    Details

    {
        "inputExpected": "Hello! Script works, but splits selected clips based on all marker rulers in Pro Tools. Is it possible to use this script so that it splits clips based off a specified marker timeline? Marker 1, Marker 2, etc? Thank you!",
        "inputIsError": false,
        "inputWhatHappens": "Clips are separated at all markers in session instead of a secified marker lane",
        "inputHowRun": {
            "key": "-Mpfwh4RkPLb2LPwjePT",
            "title": "I used a keyboard shortcut within the target app"
        },
        "inputImportance": 4,
        "inputTitle": "Split Selected Clips at Specified Marker Track"
    }

    Source

    
    //Store original selection
    let originalSelection = sf.ui.proTools.selectionGet();
    let originalSelectionSamples = sf.ui.proTools.selectionGetInSamples();
    
    //Ensure the user has actually made a selection within which we should operate
    if (originalSelectionSamples.selectionLength === 0)
        throw `Please make a selection before running this script`;
    
    try {
        //Collapse selection to the left hand side
        sf.ui.proTools.selectionSet({
            selectionStart: originalSelection.selectionStart,
            selectionEnd: originalSelection.selectionStart,
        });
    
        //Perform an endless loop
        while (true) {
    
            //Go to the next memory location
            let goRes = sf.ui.proTools.memoryLocationsGotoDelta({
                delta: 1,
                onError: 'Continue',
            });
    
            //If we didn't find a next memory location, just abort the loop
            if (!goRes.success)
                break;
    
            //Retrieve the selection at this point
            let newSelection = sf.ui.proTools.selectionGet();
    
            //If we're now further to the right than the original selection,
            //break the loop
            if (newSelection.selectionStart > originalSelection.selectionEnd)
                break;
    
            //Otherwise, click Separate Clip At Selection, and continue the loop
            //also - if for some reason we're in between clips we're allowing the menu click to fail silently
            sf.ui.proTools.menuClick({
                menuPath: ["Edit", "Separate Clip", "At Selection"],
                onError: 'Continue',
            });
    
            //Continue the loop
        }
    } finally {
        //Finally, regardless of any error occurring in the previous code,
        //restore the original selection
        sf.ui.proTools.selectionSetInSamples({
            selectionStart: originalSelectionSamples.selectionStart,
            selectionEnd: originalSelectionSamples.selectionEnd,
        });
    }
    
    

    Links

    User UID: BAHRTrNpErQGSMCXb1Gj6AHsSU13

    Feedback Key: sffeedback:BAHRTrNpErQGSMCXb1Gj6AHsSU13:-OPHIc8gTZsGACFJm22x

    Feedback ZIP: S+aW2eb8llXsIbzoF7bgxktAXBXOyFNbkS1lhAdZuqqAT2430ot3Z4qNvdQxqUx8QZZH/pxfQbBTFXtKOZXxx9YXnP0zU++NjRhcJveSiyUwKY2R+BTBcTgZhVp+L7cNChy7VS++Nw7vVzbrIFwC9REvmnSfM+AHzubsyWGC3XKVvAkYU+bP5CH9D1zPyfVd44rllcVqkUVEmlj0nPUCayMYm9eQav2AiCGo3Jyenq9Dh2uTLx9r2RCOKDm6g7Qcq521f8+VAmTEgx2Z5e4Q17Nj1JJn6+xnzJqFUh775O/mY0oGkFrLMA6yzAWtbdmRcG9BKGYiAhNy7/yv8C7sdw==

    • 2 replies
    1. Chad Wahlbrink @Chad2025-05-03 00:09:38.086Z

      Hi, @Curtis_Macdonald,

      Since you are asking about a specific script, I've moved this post to the “Macro and Script Help” section of the forum.

      The sf.ui.proTools.memoryLocationsGotoDelta() does not have a property for marker track name, so we have to use a different approach. Typically, you'd use something like sf.app.proTools.memoryLocations.invalidate().allItems.map(memLocs => memLocs.trackName) - however, this seems to currently throw some "null" values for the global marker tracks, which is not very helpful.

      Therefore, I'm approaching this differently by utilizing sf.app.proTools.getSessionInfoAsText(). This SDK call can retrieve the session info text you typically get from File > Export > Session Info as Text. This text can include a marker list, including the marker track names. Therefore, I'm filtering that text with some regex (thanks to ChatGPT 😊). From there, we have all the necessary information to make it happen!

      Here's the script - I have refactored it a bit to use more SDK calls than UI automation. Set the name of your desired Marker Lane at the top of the script (line 3 below):

      
      // Set the Marker Track Name Here (Markers, Markers 2, Markers 3, Another Track Name...)
      let markerTrackName = 'MIX';
      
      ////////////////////
      
      if (!sf.ui.proTools.isRunning) throw `Pro Tools is not running`;
      
      sf.ui.proTools.appActivateMainWindow();
      sf.ui.proTools.mainWindow.invalidate();
      
      // Get the Session Info as Text - This is how we are getting the markers list with Marker Tracks
      let sessionInfoResult = sf.app.proTools.getSessionInfoAsText({
          includeMarkers: true,
          includeClipList: false,
          includePluginList: false,
          includeTrackEdls: false,
          includeUserTimestamps: false,
          includeFileList: false,
      })
      
      // Use Regex to Filter for Lines that Start with a Number 
      const markerLines = sessionInfoResult.sessionInfo
          .split('\n')
          .filter(line => /^\d+\s+/.test(line)); // lines that start with a number
      
      // Further Split These Lines by their "headers" of Number, Location, Time Reference, Units, Name, and Marker Track Name
      // Store this as an array of Marker Objects
      const markers = markerLines.map(line => {
          const parts = line.split('\t').map(p => p.trim()).filter(Boolean);
          return {
              number: parseInt(parts[0]),
              location: parts[1],
              timeReference: parts[2],
              units: parts[3],
              name: parts[4],
              trackName: parts[5]
          };
      });
      
      //Store original selection using SDK
      let originalSelectionSamples = sf.app.proTools.getTimelineSelection({ timeScale: "Samples" })
      
      //Ensure the user has actually made a selection within which we should operate
      if (originalSelectionSamples.inTime === originalSelectionSamples.outTime)
          throw `Please make a selection before running this script`;
      
      try {
          // Go to Selection Start
          sf.app.proTools.setTimelineSelection({
              inTime: originalSelectionSamples.inTime,
              outTime: originalSelectionSamples.inTime
          })
      
          // Filter Markers for the Marker Track Name, 
          // the location is after or equal to the in time 
          // the location is before or equal to the out time 
          let markersOnNamedTrack = markers.filter(
              marker =>
              (marker.trackName === markerTrackName
                  && Number(marker.location) >= Number(originalSelectionSamples.inTime)
                  && Number(marker.location) <= Number(originalSelectionSamples.outTime)
              )
          );
      
          // For each Marker On the Named Marker Track and Within our Selection, Split at the Marker
          markersOnNamedTrack.forEach((marker) => {
              // Go to the Markers Location 
              sf.app.proTools.setTimelineSelection({ inTime: marker.location });
              // Seperate the Clip
              sf.ui.proTools.menuClick({
                  menuPath: ["Edit", "Separate Clip", "At Selection"],
                  onError: 'Continue',
              });
          })
      
      } finally {
          //Finally, regardless of any error occurring in the previous code,
          //restore the original selection
          sf.app.proTools.setTimelineSelection({
              inTime: originalSelectionSamples.inTime,
              outTime: originalSelectionSamples.outTime,
          });
      }
      
      1. YOINK!!!!! Huge Chad, huge.