No internet connection
  1. Home
  2. Script Sharing

Spot to Original Timestamp MUSIC EDITORS TEST PLEASE

By Owen Granich-Young @Owen_Granich_Young
    2023-07-27 23:56:06.752Z2023-07-28 00:20:46.306Z

    Made on a 'hold my beer' challenge for my music editor who might make the jump to Soundflow. Calling all music editors to give it a run and see if it breaks. One button to Spot all your stems ;)

    /// Make sure You're in Time Grabber Function \\\
    function toggleTimeGrabTool() {
    
        const grabberTool = sf.ui.proTools.mainWindow.groups.whoseTitle.is('Cursor Tool Cluster').first.buttons.whoseTitle.startsWith('Grabber tool').first;
    
        grabberTool.elementClick(); // if there's smart tool selected then it turns it off
        grabberTool.popupMenuSelect({
            isRightClick: true,
            menuPath: ['Time']
        });
    }
    
    /// Single File Spot to Original \\\
    function spotToOriginal() {
    
        /// Define the Spotting Window
        const spotWin = sf.ui.proTools.clipSpotDialog
        
        /// Toggle Time Tool
        toggleTimeGrabTool();
        
        /// Open Spot Dialog
        sf.ui.proTools.clipOpenSpotDialog();
    
        /// Wait for Spot Dialog to Open
        spotWin.elementWaitFor();
        
        ///Click Original Timestamp Button
        spotWin.mouseClickElement({ relativePosition: { "x": 271, "y": 247 },});
    
        ///Click OK
        spotWin.buttons.whoseTitle.is("OK").first.elementClick();
    }
    
    function main() {
    
        /// Saftey Invalidate
        sf.ui.proTools.appActivateMainWindow();
        sf.ui.proTools.invalidate();
    
        /// Get selected tracks
        const originalTracks = sf.ui.proTools.selectedTrackNames;
    
        //Do for each track.
        sf.ui.proTools.selectedTracks.trackHeaders.slice().map(track => {
    
            //Select track
            track.trackSelect();
    
            //Scroll track into View
            track.trackScrollToView();
    
            //Do for each clip on Track
            sf.ui.proTools.clipDoForEachSelectedClip({
                action: () => {
                    spotToOriginal();
                },
                onError: "Continue",
            });
        });
    
        //Restore previously selected tracks
        sf.ui.proTools.trackSelectByName({ names: originalTracks });
    };
    
    main();
    
    Solved in post #6, click to view
    • 12 replies

    There are 12 replies. Estimated reading time: 21 minutes

    1. Kitch Membery @Kitch2023-07-28 00:07:27.460Z

      Awesome, Owen!

      What's this line clicking?

      spotWin.mouseClickElement({ relativePosition: { "x": 271, "y": 247 }, });

      Original Time Stamp?

      1. The original timestamp button inside the Spotting pane it didn't seem to trigger on ui when I rolled over it. I"ll update the script with comments now.

        1. Kitch Membery @Kitch2023-07-28 00:16:07.739Z

          A few tweaks but top work, Owen!

          function selectTimeGrabTool() {
              const grabberTool = sf.ui.proTools.mainWindow.cursorToolCluster.grabberTool;
          
              grabberTool.elementClick(); // if there's smart tool selected then it turns it off
              grabberTool.popupMenuSelect({
                  isRightClick: true,
                  menuPath: ['Time'],
              });
          }
          
          function spotToOriginal() {
              const spotWin = sf.ui.proTools.clipSpotDialog;
          
              selectTimeGrabTool();
          
              sf.ui.proTools.clipOpenSpotDialog();
          
              spotWin.elementWaitFor();
          
              // Click "Original Time Stamp"
              spotWin.mouseClickElement({ relativePosition: { "x": 271, "y": 247 }, });
          
              spotWin.buttons.whoseTitle.is("OK").first.elementClick();
          
              spotWin.elementWaitFor({ waitType: "Disappear" });
          }
          
          function main() {
              // Activate Pro Tools Main Window
              sf.ui.proTools.appActivateMainWindow();
          
              // Invalidate Pro Tools main Window
              sf.ui.proTools.mainWindow.invalidate();
          
              // Get selected tracks
              const originalTracks = sf.ui.proTools.selectedTrackNames;
          
              // Do for each track.
              sf.ui.proTools.selectedTracks.trackHeaders.slice().map(track => {
                  // Select track
                  track.trackSelect();
          
                  // Scroll track into View
                  track.trackScrollToView();
          
                  // Do for each clip on Track
                  sf.ui.proTools.clipDoForEachSelectedClip({
                      action: spotToOriginal,
                      onError: "Continue",
                  });
              });
          
              // Restore previously selected tracks
              sf.ui.proTools.trackSelectByName({ names: originalTracks });
          }
          
          main();
          
          1. VVanessa Garde @Vanessa_Garde
              2023-10-04 18:47:07.682Z

              @Kitch , would it be possible to update this script, as it sometimes fails on certain tracks?

              Thanks a lot!

              1. Kitch Membery @Kitch2023-10-04 19:09:02.594Z

                Work in Progress. But this should work.

                function selectTimeGrabTool() {
                    const grabberTool = sf.ui.proTools.mainWindow.cursorToolCluster.grabberTool;
                
                    grabberTool.elementClick(); // if there's smart tool selected then it turns it off
                    grabberTool.popupMenuSelect({
                        isRightClick: true,
                        menuPath: ['Time'],
                    });
                }
                
                function spotToOriginal() {
                    //Get Current Selection
                    const oldSelection = sf.ui.proTools.selectionGetInSamples();
                
                    const spotWin = sf.ui.proTools.clipSpotDialog;
                
                    //selectTimeGrabTool();
                
                    //sf.ui.proTools.clipOpenSpotDialog();
                
                    const menu = sf.ui.proTools.clipOpenContextMenu().popupMenu;
                    menu.menuClickPopupMenu({
                        menuPath: ['Spot...'],
                    });
                
                    spotWin.elementWaitFor();
                
                    // Click "Original Time Stamp"
                    spotWin.mouseClickElement({ relativePosition: { "x": 271, "y": 247 }, });
                
                    spotWin.buttons.whoseTitle.is("OK").first.elementClick();
                
                    spotWin.elementWaitFor({ waitType: "Disappear" });
                
                    //Restore Current Selection
                    sf.ui.proTools.selectionSetInSamples({
                        selectionStart: oldSelection.selectionStart,
                        selectionEnd: oldSelection.selectionEnd,
                    });
                }
                
                function main() {
                    // Activate Pro Tools Main Window
                    sf.ui.proTools.appActivateMainWindow();
                
                    // Invalidate Pro Tools main Window
                    sf.ui.proTools.mainWindow.invalidate();
                
                    // Get selected tracks
                    const selectedTrackNames = sf.ui.proTools.selectedTrackNames;
                
                
                    // Do for each track.
                    selectedTrackNames.forEach(name => {
                
                        // Select track
                        const track = sf.ui.proTools.trackGetByName({ name }).track
                
                        // Select Track
                        track.trackSelect();
                
                        // Scroll track into View
                        track.trackScrollToView();
                
                        sf.ui.proTools.menuClick({ menuPath: ["Edit", "Select All"] });
                
                        // Do for each clip on Track
                        sf.ui.proTools.clipDoForEachSelectedClip({
                            action: spotToOriginal,
                            onError: "Continue",
                        }, `There was an error spotting track ${name}`);
                    });
                
                    // Restore previously selected tracks
                    sf.ui.proTools.trackSelectByName({ names: selectedTrackNames });
                
                    sf.ui.proTools.toolsSelect({ tool: "Smart", });
                    sf.ui.proTools.editModeSet({ mode: "Slip", });
                }
                
                main();
                
                Reply3 LikesSolution
                1. VVanessa Garde @Vanessa_Garde
                    2023-10-05 09:15:38.149Z

                    Thanks for the work on this, @Kitch & @Owen_Granich_Young !!

                    Just tried the newer version, and I had to do it twice, since some clips were spotted to the wrong timestamp (just to go to 00:00:00:00). Repeating the process took them to the right place... I screencasted, for reference:

                    Any idea why this might be happening?

                    Thanks again!!!

                    1. Kitch Membery @Kitch2023-10-05 10:27:57.884Z

                      Hi @Vanessa_Garde,

                      Looking into this further, there are more issues stopping this above implementation from working.

                      It looks like the method for spotting does not always display the correct Original Time Stamp, it instead reports it as zero.

                          const menu = sf.ui.proTools.clipOpenContextMenu().popupMenu;
                          menu.menuClickPopupMenu({
                              menuPath: ['Spot...'],
                          });
                      

                      When reverting to using the sf.ui.proTools.clipOpenSpotDialog() method, it's important that the clips are zoomed in. So for this, I'm using a zoom memory button to make sure the clips are zoomed in enough.

                      I've also changed some other things so let me know if you have questions about anything else.

                      Try this out and let me know how it goes for you.

                      function selectTimeGrabTool() {
                          const grabberTool = sf.ui.proTools.mainWindow.cursorToolCluster.grabberTool;
                      
                          grabberTool.elementClick(); // If there's smart tool selected then it turns it off
                      
                          grabberTool.popupMenuSelect({
                              isRightClick: true,
                              menuPath: ['Time'],
                          });
                      }
                      
                      function spotToOriginal() {
                          //Get Current Selection
                          const oldSelection = sf.ui.proTools.selectionGetInSamples();
                      
                          const clipSpotDialog = sf.ui.proTools.clipSpotDialog;
                      
                          sf.ui.proTools.clipOpenSpotDialog();
                          clipSpotDialog.elementWaitFor();
                      
                          if (clipSpotDialog.popupButtons.first.value.value !== "Samples") {
                              clipSpotDialog.popupButtons.first.popupMenuSelect({
                                  menuPath: ["Samples"]
                              });
                          }
                      
                          const textFields = clipSpotDialog.childrenByRole("AXStaticText").map(e => e.value.value);
                      
                          const originalTimeStamp = clipSpotDialog.childrenByRole("AXStaticText")[textFields.indexOf("Original Time Stamp:") + 1].value.value;
                      
                          sf.ui.proTools.clipSpotDialog.textFields.whoseTitle.is("NumericEntryText").first.elementSetTextFieldWithAreaValue({
                              useMouseKeyboard: true,
                              value: originalTimeStamp,
                          });
                      
                          clipSpotDialog.buttons.whoseTitle.is("OK").first.elementClick();
                          clipSpotDialog.elementWaitFor({ waitForNoElement: true });
                      
                          //Restore Current Selection
                          sf.ui.proTools.selectionSetInSamples({
                              selectionStart: oldSelection.selectionStart,
                              selectionEnd: oldSelection.selectionEnd,
                          });
                      }
                      
                      function main() {
                          // Activate Pro Tools Main Window
                          sf.ui.proTools.appActivateMainWindow();
                      
                          // Invalidate Pro Tools main Window
                          sf.ui.proTools.mainWindow.invalidate();
                      
                          selectTimeGrabTool();
                          sf.ui.proTools.mainWindow.zoomQuadrantCluster.buttons.whoseTitle.is("Zoom Memory 1").first.elementClick();
                      
                          // Get selected tracks
                          const selectedTrackNames = sf.ui.proTools.selectedTrackNames;
                      
                          // Do for each track.
                          selectedTrackNames.forEach(name => {
                      
                              // Select track
                              const track = sf.ui.proTools.trackGetByName({ name }).track;
                      
                              // Select Track
                              track.trackSelect();
                      
                              // Scroll track into View
                              track.trackScrollToView();
                      
                              sf.ui.proTools.menuClick({ menuPath: ["Edit", "Select All"] });
                      
                              sf.keyboard.press({ keys: "left" });
                      
                              // Do for each clip on Track
                              sf.ui.proTools.clipDoForEachSelectedClip({
                                  action: spotToOriginal,
                                  onError: "Continue",
                              }, `There was an error spotting track ${name}`);
                          });
                      
                          // Restore previously selected tracks
                          sf.ui.proTools.trackSelectByName({
                              names: selectedTrackNames
                          });
                      
                          sf.ui.proTools.toolsSelect({ tool: "Smart", });
                          sf.ui.proTools.editModeSet({ mode: "Slip", });
                      }
                      
                      main();
                      
                      1. VVanessa Garde @Vanessa_Garde
                          2023-10-05 13:56:49.868Z

                          Great!! Much better now...!! Thanks @Kitch !!!

                          I noticed something too:

                          • If no selection is made (on the timeline, with the cursor in the beginning of the session, for ex.), on the first track, the clip doesn't spot. The rest does tho.
                          • Including a selection, it does make it work on the first track, as well.

                          Video:
                          https://www.dropbox.com/scl/fi/co6vqyf32yj1m7xav8lld/SF_VG-Spot-Script-v2.mov?rlkey=a3h8wwrorrknjehrse9s6jcxc&dl=0

                          Thank you!

                          1. Kitch Membery @Kitch2023-10-05 17:22:22.412Z

                            Interesting... I assume this is a quirk in the way the sf.ui.proTools.clipOpenSpotDialog(); works.

                            Try inserting sf.ui.proTools.menuClick({ menuPath: ["Edit", "Select All"] }); at line 52 to see if that fixes the issue.

                            Rock on!

                            1. VVanessa Garde @Vanessa_Garde
                                2023-10-11 09:51:46.812Z

                                BRAVO!!! Thank you @Kitch !!!

                                1. JJascha Viehl @Jascha_Viehl
                                    2025-04-09 14:21:42.332Z2025-04-09 16:37:42.810Z

                                    @Owen_Granich_Young @Kitch_Membery @Vanessa_Garde

                                    Thanks for posting, refining and debugging the script.
                                    It helped me to align a lot of music cues so far.
                                    And it will be a great resource in the future as the show I'm working on has about 120 cues of music, sometimes delivered in stems.

                                    With the last mentioned script here some clips still where spotted to the beginning of the session, because the script clicked "Ok" in the spotting dialog before all of the sample values where entered into the number field "Start".

                                    I inserted a small pause and adapted the script so the Spot Dialog resets to Timecode after all clips are spotted.

                                    function selectTimeGrabTool() {
                                        const grabberTool = sf.ui.proTools.mainWindow.cursorToolCluster.grabberTool;
                                    
                                        grabberTool.elementClick(); // If there's smart tool selected then it turns it off
                                    
                                        grabberTool.popupMenuSelect({
                                            isRightClick: true,
                                            menuPath: ['Time'],
                                        });
                                    }
                                    
                                    function spotToOriginal() {
                                        //Get Current Selection
                                        const oldSelection = sf.ui.proTools.selectionGetInSamples();
                                    
                                        const clipSpotDialog = sf.ui.proTools.clipSpotDialog;
                                    
                                        sf.ui.proTools.clipOpenSpotDialog();
                                        clipSpotDialog.elementWaitFor();
                                    
                                        if (clipSpotDialog.popupButtons.first.value.value !== "Samples") {
                                            clipSpotDialog.popupButtons.first.popupMenuSelect({
                                                menuPath: ["Samples"]
                                            });
                                        }
                                    
                                        const textFields = clipSpotDialog.childrenByRole("AXStaticText").map(e => e.value.value);
                                    
                                        const originalTimeStamp = clipSpotDialog.childrenByRole("AXStaticText")[textFields.indexOf("Original Time Stamp:") + 1].value.value;
                                    
                                        sf.ui.proTools.clipSpotDialog.textFields.whoseTitle.is("NumericEntryText").first.elementSetTextFieldWithAreaValue({
                                            useMouseKeyboard: true,
                                            value: originalTimeStamp,
                                        });
                                    
                                        // Wait to enable full entry of value (original TimeStamp)
                                        sf.wait({
                                            intervalMs: 100,
                                        });
                                    
                                        clipSpotDialog.buttons.whoseTitle.is("OK").first.elementClick();
                                        clipSpotDialog.elementWaitFor({ waitForNoElement: true });
                                    
                                        //Restore Current Selection
                                        sf.ui.proTools.selectionSetInSamples({
                                            selectionStart: oldSelection.selectionStart,
                                            selectionEnd: oldSelection.selectionEnd,
                                        });
                                    }
                                    
                                    function main() {
                                        // Activate Pro Tools Main Window
                                        sf.ui.proTools.appActivateMainWindow();
                                    
                                        // Invalidate Pro Tools main Window
                                        sf.ui.proTools.mainWindow.invalidate();
                                    
                                        // Select all in case nothing is selcted
                                        sf.ui.proTools.menuClick({ menuPath: ["Edit", "Select All"] });
                                    
                                        selectTimeGrabTool();
                                        sf.ui.proTools.mainWindow.zoomQuadrantCluster.buttons.whoseTitle.is("Zoom Memory 1").first.elementClick();
                                    
                                        // Get selected tracks
                                        const selectedTrackNames = sf.ui.proTools.selectedTrackNames;
                                    
                                        // Do for each track.
                                        selectedTrackNames.forEach(name => {
                                    
                                            // Select track
                                            const track = sf.ui.proTools.trackGetByName({ name }).track;
                                    
                                            // Select Track
                                            track.trackSelect();
                                    
                                            // Scroll track into View
                                            track.trackScrollToView();
                                    
                                            sf.ui.proTools.menuClick({ menuPath: ["Edit", "Select All"] });
                                    
                                            sf.keyboard.press({ keys: "left" });
                                    
                                            // Do for each clip on Track
                                            sf.ui.proTools.clipDoForEachSelectedClip({
                                                action: spotToOriginal,
                                                onError: "Continue",
                                            }, `There was an error spotting track ${name}`);
                                        });
                                    
                                        // Reset Spot Dialog to Time Scale "Timecode"
                                    
                                        const clipSpotDialog = sf.ui.proTools.clipSpotDialog;
                                    
                                        sf.ui.proTools.menuClick({ menuPath: ["Edit", "Select All"] });
                                    
                                        sf.ui.proTools.clipOpenSpotDialog();
                                        clipSpotDialog.elementWaitFor();
                                    
                                        if (clipSpotDialog.popupButtons.first.value.value !== "Timecode") {
                                            clipSpotDialog.popupButtons.first.popupMenuSelect({
                                                menuPath: ["Timecode"]
                                            });
                                        }
                                        clipSpotDialog.buttons.whoseTitle.is("CANCEL").first.elementClick();
                                        clipSpotDialog.elementWaitFor({ waitForNoElement: true });
                                    
                                        // Restore previously selected tracks
                                        sf.ui.proTools.trackSelectByName({
                                            names: selectedTrackNames
                                        });
                                    
                                        sf.ui.proTools.toolsSelect({ tool: "Smart", });
                                        sf.ui.proTools.editModeSet({ mode: "Slip", });
                                    }
                                    
                                    main();
                                    
                2. J
                  Judson Crane @Judson_Crane
                    2025-04-09 15:32:02.305Z

                    Hi! excited to come across this as it is always a pain to spot clips when importing mixes to review before a dub. It failed at first on 5 of 6 clips I tried it on, but then I simply moved the clips to somewhere in the timeline besides the top, and it worked (perhaps this was mentioned and I missed it)! brilliant! much thanks!