No internet connection
  1. Home
  2. How to

Creating Markers Based on Clip Name

By Brandon Jiaconia @Brandon_Jiaconia
    2023-11-05 16:54:12.489Z

    I have a macro for creating markers based on the name of a Video file in my Pro Tools session. It works great but I have to trigger it for each video in the session. Sometimes I will have 10+ videos and I would like to automate the process. Here is my macro:

    and the script of the macro:
    
    //Calling command "Next Clip" from package "Glenn PT" (installed from user/pkg/version "cC8lEkgySCUgl4chMHut9tysKdy1/cl44nzq020000rq10ouciq4gh/cl6ffsb5j000c6s104wtrhmxk")
    sf.soundflow.runCommand({
        commandId: 'user:cl6fa659600000610lggi0qif:cl5ii0n9q000d5t10fc0terze',
        props: {}
    });
    
    //Calling command "Rename..." from package "Pro Tools" (installed from user/pkg/version "srAasovvDiQacRZ2mcId4RrOA8R2/ckp49i4j60000a2100yfwywgf/cln0nxiji0000yp102352fxp9")
    sf.soundflow.runCommand({
        commandId: 'user:ckp49i4j60000a2100yfwywgf:ckw2p6vpz0002ik10txjjtvhs#ckw2wdejo000uik103hef958b',
        props: {}
    });
    
    sf.keyboard.press({
        keys: "cmd+c",
    });
    
    sf.keyboard.press({
        keys: "return",
    });
    
    sf.wait({
        intervalMs: 100,
    });
    
    sf.keyboard.press({
        keys: "numpad enter",
    });
    
    sf.wait({
        intervalMs: 100,
    });
    
    sf.keyboard.press({
        keys: "cmd+v",
    });
    
    sf.keyboard.press({
        keys: "numpad enter",
    });
    
    
    

    Anyone able to make this script run until there are no more videos or clips in the time line? I'm sure there is a cleaner and more sophisticated way to do this.

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

    There are 14 replies. Estimated reading time: 21 minutes

    1. O

      I thought I had the lego pieces lying around for this so figured I'd look at it. Of NOTE this is for PT pre track markers, so if you're on 2023.6 or later it may or may not work. Be sure to select all the video files before you run the script (see attached movie). I'm sure Icing on the cake would be some functions at the top that go, 'Find Video Track' 'Select all on video track' 'run script' but I've used my allotted hobby time for the day and got to get back to it. If somebody else has those lego pieces at easy reach maybe we can bolt them onto this script.

      ///Clear Find So You can get Clip Name
      const clearFind = () => sf.keyboard.press({ keys: "cmd+shift+d", });
      
      ////Create memory location
      function createMemoryLocationsMarker({ name }) {
          sf.ui.proTools.appActivateMainWindow();
      
          const dlg = sf.ui.proTools.newMemoryLocationDialog;
      
          if (!dlg.exists) {
              sf.keyboard.press({ keys: "numpad enter" });
          }
      
          dlg.elementWaitFor();
      
          dlg.radioButtons.whoseTitle.is("Marker").first.elementClick();
      
          dlg.textFields.allItems[1].elementSetTextFieldWithAreaValue({
              value: name,
          });
      
          dlg.buttons.whoseTitle.is("OK").first.elementClick();
      
          dlg.elementWaitFor({ waitType: "Disappear", });
      }
      
      ///Get Current Clip Name
      function getCurrentClipName() { //This gets the current region name in Pro Tools
      
          const clipNameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first
          try {
              sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] }, `could not find rename window`);
              clipNameWin.elementWaitFor({ onError: "Continue" });
              let currentClipName = clipNameWin.groups.whoseTitle.is('Name').first.textFields.first.value.invalidate().value;
              clipNameWin.buttons.whoseTitle.is('Cancel').first.elementClick({}, `could not click Rename window: cancel button`);
              return currentClipName
          } catch (err) {
              throw `error in getCurrentClipNameWin(): ${err}`
          }
      }
      
      ///Combine the above functions to get the goal
      function dropMarkerOfClipName() {
      
          createMemoryLocationsMarker({ name: getCurrentClipName() });
      
      }
      
      ///  Clear Caches and Finds then Do to all clips selected
      function main() {
          sf.ui.proTools.appActivateMainWindow();
          sf.ui.proTools.invalidate();
          clearFind();
          sf.ui.proTools.clipDoForEachSelectedClip({
              action: dropMarkerOfClipName
          });
      }
      
      main();
      

      Bests,
      Owen

      1. BBrandon Jiaconia @Brandon_Jiaconia
          2023-11-06 21:08:42.171Z

          Owen, Thank you for your reply. Your script looks great in the video! But your suspicion about PT 2023.6 was correct. This script selects the clips the same way as your video, but does not make the markers for some reason.

          1. Ugh, yeah @Chris_Shaw or @Kitch I know it's an easy fix one of you posted around the forum, but I can't seem to get the keywords right to track it back down. If you have a free moment will you remind me? Pretty sure it's as easy as changing line 18 just a little but I can't track it down.

            Sorry @Brandon_Jiaconia I've not yet updated here, so I can't trouble shoot myself.

            1. BBrandon Jiaconia @Brandon_Jiaconia
                2023-11-06 21:22:30.453Z

                All good - I really appreciate you taking the time to look at this.

                1. Kitch Membery @Kitch2023-11-06 22:59:29.814Z

                  Try this @Owen_Granich_Young!

                  /** 
                   * Clear Find in the clips list so you can get Clip Name 
                   */
                  function clearFind() {
                      sf.keyboard.press({ keys: "cmd+shift+d", });
                  }
                  
                  /** 
                   * Create memory location 
                   * @param {object} obj
                   * @param {string} obj.name
                   */
                  function createMemoryLocationsMarker({ name }) {
                      sf.ui.proTools.appActivateMainWindow();
                  
                      const dlg = sf.ui.proTools.newMemoryLocationDialog;
                  
                      if (!dlg.exists) {
                          sf.keyboard.press({ keys: "numpad enter" });
                      }
                  
                      dlg.elementWaitFor();
                  
                      dlg.radioButtons.whoseTitle.is("Marker").first.elementClick();
                  
                      const nameTextField = dlg.textFields.first;
                  
                      nameTextField.elementSetTextFieldWithAreaValue({
                          value: name,
                      });
                  
                      dlg.buttons.whoseTitle.is("OK").first.elementClick();
                  
                      dlg.elementWaitFor({
                          waitType: "Disappear",
                      });
                  }
                  
                  /**
                   * Get Current Clip Name
                   */
                  function getCurrentClipName() { //This gets the current region name in Pro Tools
                  
                      const clipRenameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first;
                  
                      try {
                  
                          // Open clip rename window
                          sf.ui.proTools.menuClick({
                              menuPath: ['Clip', 'Rename...'],
                          }, `could not find rename window`);
                  
                          // Wait for clip rename window
                          clipRenameWin.elementWaitFor({
                              onError: "Continue",
                          });
                  
                          let currentClipName = clipRenameWin.groups.whoseTitle.is('Name').first.textFields.first.value.invalidate().value;
                  
                          clipRenameWin.buttons.whoseTitle.is('Cancel').first.elementClick({}, `could not click Rename window: cancel button`);
                  
                          return currentClipName
                      } catch (err) {
                          throw `error in getCurrentClipNameWin(): ${err}`;
                      }
                  }
                  /**
                   * Combine the above functions to get the goal
                   */
                  function createMarkerFromClipName() {
                      // Get current clip name
                      const currentClipName = getCurrentClipName();
                  
                      // Create memory location
                      createMemoryLocationsMarker({
                          name: currentClipName,
                      });
                  }
                  
                  ///  Clear Caches and Finds then Do to all clips selected
                  function main() {
                      sf.ui.proTools.appActivateMainWindow();
                      sf.ui.proTools.invalidate();
                  
                      clearFind();
                  
                      // Do for each selected clip
                      sf.ui.proTools.clipDoForEachSelectedClip({
                          action: createMarkerFromClipName,
                      });
                  }
                  
                  main();
                  

                  I probably didn't need to refactor it but did anyway.

                  All you needed to change was line 18...

                  dlg.textFields.allItems[1].elementSetTextFieldWithAreaValue({
                          value: name,
                      });
                  

                  to

                  dlg.textFields.first.elementSetTextFieldWithAreaValue({
                          value: name,
                      });
                  

                  as the "Name" text field was the first or allItems[0] not the allItems[1] textField.

                  Hope that works.
                  :-)

                  1. @Brandon_Jiaconia The pros have stepped in you should be good to go. Thanks @Kitch I knew it was something there in 18 I just couldn't remember what. I'll leave the old one un-edited above just in case someone needs it for pre 2023.6

                    1. BBrandon Jiaconia @Brandon_Jiaconia
                        2023-11-06 23:40:53.639Z

                        Owen, I just realized that your original script works with the name of Audio clips, but not with Video clips. Kitchs' update is the same! I also realized I can use the reference audio from the video (which has the same name as the video) to make these markers. Again, really appreciate your help, thanks so much! And Kitch thank you for chiming in! You guys are legends !

                        1. Innnnnntersting, my bad TBH I never checked against a video file. Will fix tomorrow if somebody doesn't beat me to it.

                          1. Doubly interesting @Kitch it's the sf.ui.proTools.clipDoForEachSelectedClip it doesn't like video clips. If I remove that and just run it it works... log for internal review? Or other workaround?

                            1. Kitch Membery @Kitch2023-11-07 00:33:48.941Z

                              Ahhh yes, I don't believe the sf.ui.proTools.clipDoForEachSelectedClip method works for video clips. It would best to request in the Ideas section of the forum or upvote the Idea if it's already been requested.

                              1. @Brandon_Jiaconia in the mean time, this script will prompt you to tell it how many clips are in the selection and then run that number of times.

                                ///Clear Find So You can get Clip Name
                                const clearFind = () => sf.keyboard.press({ keys: "cmd+shift+d", });
                                /// Select Next Clip
                                const cntrlTab = () => sf.keyboard.press({ keys: "ctrl+tab", fast: true, });
                                
                                
                                ////Create memory location
                                function createMemoryLocationsMarker({ name }) {
                                    sf.ui.proTools.appActivateMainWindow();
                                
                                    const dlg = sf.ui.proTools.newMemoryLocationDialog;
                                
                                    if (!dlg.exists) {
                                        sf.keyboard.press({ keys: "numpad enter" });
                                    }
                                
                                    dlg.elementWaitFor();
                                
                                    dlg.radioButtons.whoseTitle.is("Marker").first.elementClick();
                                
                                    dlg.textFields.allItems[0].elementSetTextFieldWithAreaValue({
                                        value: name,
                                    });
                                
                                    dlg.buttons.whoseTitle.is("OK").first.elementClick();
                                
                                    dlg.elementWaitFor({ waitType: "Disappear", });
                                }
                                
                                ///Get Current Clip Name
                                function getCurrentClipName() { //This gets the current region name in Pro Tools
                                
                                    const clipNameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first
                                    try {
                                        sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] }, `could not find rename window`);
                                        clipNameWin.elementWaitFor({ onError: "Continue" });
                                        let currentClipName = clipNameWin.groups.whoseTitle.is('Name').first.textFields.first.value.invalidate().value;
                                        clipNameWin.buttons.whoseTitle.is('Cancel').first.elementClick({}, `could not click Rename window: cancel button`);
                                        return currentClipName
                                    } catch (err) {
                                        throw `error in getCurrentClipNameWin(): ${err}`
                                    }
                                }
                                
                                function dropMarkerOfClipName() {
                                
                                    createMemoryLocationsMarker({ name: getCurrentClipName() });
                                
                                }
                                
                                /// Do to all clips -- this is how you package it to do it to all highlight clips
                                function main() {
                                    sf.ui.proTools.appActivateMainWindow();
                                    sf.ui.proTools.invalidate();
                                    clearFind();
                                    var repeat = prompt("How many tabs would you like to process?");
                                    for (let i = 0; i < +repeat; i++) {
                                        cntrlTab();
                                        dropMarkerOfClipName();
                                    }
                                }
                                
                                main();
                                

                                Sorry @kitch it's not your Refactored - Brandon I did change it to work 2023.6 though... (i think)

                                1. Ok thought about it some more... here's better yet. You only need to click into your video track now...

                                  ///Clear Find So You can get Clip Name
                                  const clearFind = () => sf.keyboard.press({ keys: "cmd+shift+d", });
                                  
                                  /// Select Next Clip
                                  const cntrlTab = () => sf.keyboard.press({ keys: "ctrl+tab", fast: true, });
                                  
                                  
                                  ////Create memory location
                                  function createMemoryLocationsMarker({ name }) {
                                      sf.ui.proTools.appActivateMainWindow();
                                  
                                      const dlg = sf.ui.proTools.newMemoryLocationDialog;
                                  
                                      if (!dlg.exists) {
                                          sf.keyboard.press({ keys: "numpad enter" });
                                      }
                                  
                                      dlg.elementWaitFor();
                                  
                                      dlg.radioButtons.whoseTitle.is("Marker").first.elementClick();
                                  
                                      dlg.textFields.allItems[0].elementSetTextFieldWithAreaValue({
                                          value: name,
                                      });
                                  
                                      dlg.buttons.whoseTitle.is("OK").first.elementClick();
                                  
                                      dlg.elementWaitFor({ waitType: "Disappear", });
                                  }
                                  
                                  ///Get Current Clip Name
                                  function getCurrentClipName() { //This gets the current region name in Pro Tools
                                  
                                      const clipNameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first
                                      try {
                                          sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] }, `could not find rename window`);
                                          clipNameWin.elementWaitFor({ onError: "Continue" });
                                          let currentClipName = clipNameWin.groups.whoseTitle.is('Name').first.textFields.first.value.invalidate().value;
                                          clipNameWin.buttons.whoseTitle.is('Cancel').first.elementClick({}, `could not click Rename window: cancel button`);
                                          return currentClipName
                                      } catch (err) {
                                          throw `error in getCurrentClipNameWin(): ${err}`
                                      }
                                  }
                                  
                                  /**
                                   * Combine the above functions to get the goal
                                   */
                                  function createMarkerFromClipName() {
                                      // Get current clip name
                                      const currentClipName = getCurrentClipName();
                                  
                                      // Create memory location
                                      createMemoryLocationsMarker({
                                          name: currentClipName,
                                      });
                                  }
                                  
                                  /// Do to all clips -- this is how you package it to do it to all highlight clips
                                  function main() {
                                      sf.ui.proTools.appActivateMainWindow();
                                      sf.ui.proTools.invalidate();
                                  
                                      clearFind();
                                      
                                      sf.ui.proTools.menuClick({ menuPath: ["Edit", "Select All"] });
                                      sf.ui.proTools.menuClick({ menuPath: ["Edit", "Selection", "Move Edit Left"] });
                                  
                                      // Get current state of Clip view
                                      const isClipListEnabled = sf.ui.proTools.getMenuItem("View", "Other Displays", "Clip List").isMenuChecked
                                  
                                      // Open Clip List if It's not
                                      if (!isClipListEnabled) {
                                          sf.ui.proTools.menuClick({
                                              menuPath: ["View", "Other Displays", "Clip List"],
                                          });
                                      }
                                  
                                      let selectedClips = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first.children.whoseRole.is("AXRow").allItems.map(row =>
                                          row.children[1].children.first.value.value).filter(c => c.startsWith('Selected. '));
                                  
                                  
                                      for (let i = 0; i < +selectedClips.length; i++) {
                                          cntrlTab();
                                          createMarkerFromClipName();
                                      }
                                  
                                      if (!isClipListEnabled) {
                                          sf.ui.proTools.menuClick({
                                              menuPath: ["View", "Other Displays", "Clip List"],
                                          });
                                      }
                                  
                                  }
                                  
                                  main();
                                  

                                  Of note it relies on the videos being different, if you have two copies of the same video in the timeline it won't 'count' them as separate clips so it won't run the correct number of times. If your video track is always named the same thing should be pretty easy to tack a 'select track' onto the front of this.

                                  Reply2 LikesSolution
                                  1. BBrandon Jiaconia @Brandon_Jiaconia
                                      2023-11-07 18:44:04.998Z

                                      Incredible ! Exactly what I was after !

                                    • BBrandon Jiaconia @Brandon_Jiaconia
                                        2023-11-07 18:39:47.863Z

                                        This is great and works with both audio and video files in 2023.6 ! Thank you so much !