No internet connection
  1. Home
  2. How to

Grabbing data out of marker

By Chip Sloan @ChipSloan
    2021-03-24 22:21:52.152Z

    I am wondering if there's a way to goto a marker and open the marker to copy it's name. I want to use this inside of a doalltoclip. Basically go to a clip, open the marker that is at the same place as the clip and then grab that name etc.

    Is this possible? The only way I know to do would be clicking on the marker. Is opening a marker to edit possible in a script??

    • 23 replies

    There are 23 replies. Estimated reading time: 22 minutes

    1. samuel henriques @samuel_henriques
        2021-03-25 11:46:56.514Z2022-08-11 14:39:15.797Z

        Hey @ChipSloan,

        This will clipDoForEachSelectedClip, get first memory location name from selection and rename the clip with its name.

        Hope it helps:

        
        function getMemLocName() {
        
            // Get current main counter
            const currentCounter = sf.ui.proTools.getMenuItem("View", "Main Counter").children.first.children
                .filter(x => x.isMenuChecked)[0].title.invalidate().value
        
            // Change counter to samples
            sf.ui.proTools.mainCounterSetValue({ targetValue: "Samples" })
        
            // filter mem locs within selection
            const memoryLocations = sf.ui.proTools.selectionGetInSamples()
            const memLocFromSelection = sf.proTools.memoryLocationsFetch().collection['list'].filter(m =>
                m.mainCounterValue >= memoryLocations.selectionStart &&
                m.mainCounterValue <= memoryLocations.selectionEnd
            );
        
            // Change counter back to original
            sf.ui.proTools.mainCounterSetValue({ targetValue: currentCounter })
        
            // return first memory location within selection
            return memLocFromSelection[0]
        }
        
        
        function renameClip() {
        
            // Get First Memory Location Name from selection
            const memLocName = getMemLocName()
        
            if (memLocName != undefined) {
        
                //Open Rename window
                sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] });
        
                //Reference for Rename Window
                const renameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({ waitType: "Appear" }).element
        
                const nameClipOnlyButton = renameWin.groups.first.radioButtons.first
        
                ///  Set Clip Name Only
                if (nameClipOnlyButton.exists)
                    renameWin.groups.first.radioButtons.first.checkboxSet({ targetValue: "Enable" });
        
                //  Set the clip name to Track name
                renameWin.groups.first.textFields.first.elementSetTextFieldWithAreaValue({ value: memLocName.Name });
        
                // Click OK
                renameWin.buttons.whoseTitle.is('OK').first.elementClick()
                //  Wait for window to cloce
                renameWin.elementWaitFor({ waitType: "Disappear" })
            }
        }
        
        
        function main() {
        
            //  Acivate Pro Tools
            sf.ui.proTools.appActivateMainWindow()
            //  Do For Each 
            sf.ui.proTools.clipDoForEachSelectedClip({
                action: renameClip,
                onError: "Continue"
            })
        }
        
        main()
        
        
        1. Chip Sloan @ChipSloan
            2021-03-25 19:46:01.323Z

            Brilliant. Thank you.

            1. DDylan Furrow @Dylan_Furrow
                2024-09-04 19:23:21.879Z

                Hey @Kitch this is the script i was using for the clip rename

              • In reply toChipSloan:
                Chip Sloan @ChipSloan
                  2021-03-25 22:42:27.941Z

                  Okay one more. Once I have that name copied I want to open the Bounce to Disk window and use that name as the text entry in that. What is that command to enter the text into that field.

                  I actually want to do a similar thing in another script to the rename clip text field. So maybe can you tell me how to do both? I can't seem to get it right...

                  1. samuel henriques @samuel_henriques
                      2021-03-25 22:51:49.374Z2022-08-11 14:38:56.354Z

                      okok,

                      this is the part of the code that returns the marker name:

                      function getMemLocName() {
                      
                          // Get current main counter
                          const currentCounter = sf.ui.proTools.getMenuItem("View", "Main Counter").children.first.children
                              .filter(x => x.isMenuChecked)[0].title.invalidate().value
                      
                          // Change counter to samples
                          sf.ui.proTools.mainCounterSetValue({ targetValue: "Samples" })
                      
                          // filter mem locs within selection
                          const memoryLocations = sf.ui.proTools.selectionGetInSamples()
                          const memLocFromSelection = sf.proTools.memoryLocationsFetch().collection['list'].filter(m =>
                              m.mainCounterValue >= memoryLocations.selectionStart &&
                              m.mainCounterValue <= memoryLocations.selectionEnd
                          );
                      
                          // Change counter back to original
                          sf.ui.proTools.mainCounterSetValue({ targetValue: currentCounter })
                      
                          // return first memory location within selection
                          return memLocFromSelection[0]
                      }
                       // Get First Memory Location Name from selection
                          const memLocName = getMemLocName()
                      
                      log(memLocName)
                      
                      

                      on the next step you will use memLocName on the text field

                      this will help you set text on the text field:
                      How to enter text into a Pro Tools text field

                      let me know if this makes sense or you get stuck

                      1. VVanessa Garde @Vanessa_Garde
                          2023-12-12 11:27:27.557Z

                          How would you adapt it to the "new" table marker format on 2023.06 or 2023.09?

                          Trying this without luck...

                          Thank you!

                          function getMemLocName() {
                          
                              // Ensure Memory Locations window is open
                              if (!sf.ui.proTools.getMenuItem('Window', 'Memory Locations').isMenuChecked)
                                  sf.ui.proTools.memoryLocationsShowWindow();
                          
                              const table = sf.ui.proTools.memoryLocationsWindow.invalidate().tables[1];
                          
                              // Get current main counter
                              const currentCounter = sf.ui.proTools.getMenuItem("View", "Main Counter").children.first.children
                                  .filter(x => x.isMenuChecked)[0].title.invalidate().value
                          
                              // Change counter to samples
                              sf.ui.proTools.mainCounterSetValue({ targetValue: "Samples" })
                          
                              // filter mem locs within selection
                              const memoryLocations = sf.ui.proTools.selectionGetInSamples()
                              const memLocFromSelection = table.childrenByRole("AXRow").filter(m =>
                                  m.mainCounterValue >= memoryLocations.selectionStart &&
                                  m.mainCounterValue <= memoryLocations.selectionEnd
                              );
                          
                              // Change counter back to original
                              sf.ui.proTools.mainCounterSetValue({ targetValue: currentCounter })
                          
                              // return first memory location within selection
                              return memLocFromSelection[0]
                          }
                          
                      2. B
                        In reply toChipSloan:
                        Brandon Jiaconia @Brandon_Jiaconia
                          2022-08-10 16:36:01.849Z

                          @samuel_henriques - Could you show me how I could modify this script? I have been trying to sort it out on my own, but I am not really a programmer. It's a smaller part of a larger script involved with preparing my stems for delivery. If I have a clip selected and there is a marker on the first frame of the clip I'd like to select the marker. The marker and the start of the clip have the same timecode. Do you think this is possible ?

                          1. samuel henriques @samuel_henriques
                              2022-08-11 14:42:07.473Z2024-02-20 10:58:02.196Z

                              Hello Brandon,
                              this script will return the first memory location name from a selection. But had an error that I just fixed.
                              You would like to select it instead?

                              1. BBrandon Jiaconia @Brandon_Jiaconia
                                  2022-08-11 16:19:22.404Z

                                  I figured it out, thanks though!

                              2. D
                                In reply toChipSloan:
                                Dylan Furrow @Dylan_Furrow
                                  2024-09-03 17:03:51.362Z

                                  Hey guys, I've been trying to use this script and it doesn't seem to be renaming the clips. Everything else seems fine though

                                  1. Kitch Membery @Kitch2024-09-04 20:34:31.706Z

                                    Hi @Dylan_Furrow,

                                    As requested in the Hangout, this should work. :-)

                                    @raphaelsepulveda & @Chris_Shaw good call this suggested method!

                                    function matchMemoryLocations({ selectedClips, memoryLocations }) {
                                        return selectedClips.reduce((result, clip) => {
                                            const matchingLocation = memoryLocations.find(location => location.startTime === clip.startTime);
                                    
                                            if (matchingLocation) {
                                                result.push({
                                                    oldClipName: clip.name,
                                                    newClipName: matchingLocation.name,
                                                    startTime: clip.startTime
                                                });
                                            }
                                    
                                            return result;
                                        }, []);
                                    }
                                    
                                    function renameSelectedClipsByMarkers() {
                                        sf.ui.proTools.appActivate();
                                        sf.app.proTools.invalidate();
                                    
                                        const selection = sf.app.proTools.getTimelineSelection();
                                        const selectionInTime = selection.inTime;
                                        const selectionOutTime = selection.outTime;
                                    
                                        // Get selected clips omitting preceding and following clip(s)
                                        const selectedClips = sf.app.proTools.getSelectedClipInfo().clips
                                            .filter(clip => clip.endTime !== Number(selectionInTime) && clip.startTime !== Number(selectionOutTime)) //Omit connected clips
                                            .map(clip => ({
                                                name: clip.clipName,
                                                startTime: clip.startTime
                                            }));
                                    
                                        const memoryLocations = sf.app.proTools.memoryLocations.allItems.map(ml => ({
                                            name: ml.name,
                                            startTime: ml.startTimeInSamples,
                                        }));
                                    
                                        const matchingLocations = matchMemoryLocations({ selectedClips, memoryLocations, });
                                    
                                        matchingLocations.forEach(match => {
                                            sf.app.proTools.renameClip({
                                                clipName: match.oldClipName,
                                                newName: match.newClipName,
                                                renameFile: true,
                                            });
                                        });
                                    }
                                    
                                    renameSelectedClipsByMarkers();
                                    
                                    1. DDylan Furrow @Dylan_Furrow
                                        2024-09-04 21:07:54.047Z

                                        Doesn't seem to work, keeps returning this error...

                                        Rename failed
                                        Can't found clip: Audio 1_01.R
                                        (PT_InvalidParameter) (Rename: Line 41)

                                        1. Kitch Membery @Kitch2024-09-04 21:12:26.437Z

                                          Thanks @Dylan_Furrow

                                          I'll take a look at this this afternoon.

                                          1. In reply toDylan_Furrow:
                                            Kitch Membery @Kitch2024-09-05 08:03:09.256Z

                                            Hi @Dylan_Furrow,

                                            This should work. However, if there are fades on any of the clips, it will not work as expected.

                                            function matchMemoryLocations({ selectedClips, memoryLocations }) {
                                                const locationMap = new Map(memoryLocations.map(location => [location.startTime, location.name]));
                                            
                                                return selectedClips
                                                    .filter(clip => locationMap.has(clip.startTime))
                                                    .map(clip => ({
                                                        oldClipName: clip.name,
                                                        newClipName: locationMap.get(clip.startTime),
                                                        startTime: clip.startTime
                                                    }));
                                            }
                                            
                                            function getUniqueObjects(arr) {
                                                return arr.filter((item, index, self) =>
                                                    index === self.findIndex((t) => (
                                                        t.name === item.name && t.startTime === item.startTime
                                                    ))
                                                );
                                            }
                                            
                                            function renameSelectedClipsByMarkers() {
                                                sf.ui.proTools.appActivate();
                                            
                                                const selection = sf.app.proTools.invalidate().getTimelineSelection();
                                                const selectionInTime = selection.inTime;
                                                const selectionOutTime = selection.outTime;
                                            
                                                // Get selected clips omitting preceding and following clip(s)
                                                const selectedClips = sf.app.proTools.invalidate().getSelectedClipInfo().clips
                                                    .filter(clip => clip.endTime !== Number(selectionInTime) && clip.startTime !== Number(selectionOutTime)) //Omit connected clips
                                                    .map(clip => ({
                                                        name: clip.clipName.replace(/\.L$|\.R$/, ""),
                                                        startTime: clip.startTime
                                                    }));
                                            
                                                const uniqueSelectedClips = getUniqueObjects(selectedClips);
                                            
                                                const memoryLocations = sf.app.proTools.memoryLocations.allItems.map(ml => ({
                                                    name: ml.name,
                                                    startTime: ml.startTimeInSamples,
                                                }));
                                            
                                                const matchingLocations = matchMemoryLocations({
                                                    selectedClips: uniqueSelectedClips,
                                                    memoryLocations,
                                                });
                                            
                                                matchingLocations.forEach(match => {
                                                    sf.app.proTools.renameClip({
                                                        clipName: match.oldClipName,
                                                        newName: match.newClipName,
                                                        renameFile: true,
                                                    });
                                                    sf.wait({ intervalMs: 100 });
                                                });
                                            }
                                            
                                            renameSelectedClipsByMarkers();
                                            
                                            1. DDylan Furrow @Dylan_Furrow
                                                2024-09-05 15:57:57.135Z

                                                Sweet, works amazing! Thanks so much @Kitch

                                                1. DDylan Furrow @Dylan_Furrow
                                                    2024-10-03 15:07:21.155Z

                                                    Hey @Kitch, i'm just wondering if theres a way this script can be modified sp that it does multiple clips per marker and incrementally numbers them.

                                                    1. Kitch Membery @Kitch2024-10-08 00:02:45.316Z

                                                      Hi @Dylan_Furrow,

                                                      Quite possibly... Can you tell me more about how this workflow looks?

                                                      What would be the manual steps that you'd take to perform the workflow?

                                                      Thanks in advance!

                                                      1. DDylan Furrow @Dylan_Furrow
                                                          2024-10-08 15:52:23.782Z

                                                          Hey @Kitch, heres a video explaining the workflow.

                                                          1. Kitch Membery @Kitch2024-10-09 01:39:17.260Z

                                                            Thanks for the video, @Dylan_Furrow. That workflow makes sense but requires a different approach to the one above. I'll see if I can whip something up later this week. :-)

                                                            1. DDylan Furrow @Dylan_Furrow
                                                                2024-10-09 01:55:36.909Z

                                                                Sweet, thanks!

                                                                1. Kitch Membery @Kitch2024-10-09 23:59:57.701Z

                                                                  Hi @Dylan_Furrow,

                                                                  Try this script...

                                                                  Be sure to have the Clip List visible (I did not account for that.)

                                                                  sf.app.proTools.invalidate();
                                                                  sf.ui.proTools.mainWindow.invalidate();
                                                                  
                                                                  function getPreceedingMemoryLocation(positionInSamples) {
                                                                  
                                                                      const memoryLocations = sf.app.proTools.memoryLocations.allItems;
                                                                      const memoryLocationsInfo = memoryLocations.map(ml => ({
                                                                          name: ml.name,
                                                                          startTimeInSamples: Number(ml.startTimeInSamples),
                                                                      }));
                                                                  
                                                                      return memoryLocationsInfo.filter(ml => ml.startTimeInSamples <= positionInSamples).slice(-1)[0].name;
                                                                  }
                                                                  
                                                                  function getSelectedClips() {
                                                                      const selection = sf.app.proTools.invalidate().getTimelineSelection();
                                                                      const selectionInTime = selection.inTime;
                                                                      const selectionOutTime = selection.outTime;
                                                                  
                                                                      // Get selected clips omitting preceding and following clip(s)
                                                                      const selectedClips = sf.app.proTools.invalidate().getSelectedClipInfo().clips
                                                                          .filter(clip => clip.endTime !== Number(selectionInTime) && clip.startTime !== Number(selectionOutTime)) //Omit connected clips
                                                                          .map(clip => ({
                                                                              name: clip.clipName.replace(/\.L$|\.R$/, ""),
                                                                              startTime: clip.startTime,
                                                                              endTime: clip.endTime,
                                                                              preceedingMemoryLocationName: getPreceedingMemoryLocation(clip.startTime),
                                                                          }));
                                                                  
                                                                      return selectedClips;
                                                                  }
                                                                  
                                                                  function batchRenameClips(baseName) {
                                                                      sf.ui.proTools.mainWindow.getFirstWithTitle("Clip List").popupMenuSelect({
                                                                          menuPath: ["Batch Rename..."],
                                                                      });
                                                                  
                                                                      const batchClipRenameWindow = sf.ui.proTools.windows.whoseTitle.is("Batch Clip Rename").first.invalidate();
                                                                  
                                                                      batchClipRenameWindow.elementWaitFor();
                                                                  
                                                                      // Restore factory default preset
                                                                      batchClipRenameWindow.getFirstWithTitle("Librarian menu").popupMenuSelect({ menuPath: ["<factory default>"] });
                                                                  
                                                                      // Clear existing name
                                                                      batchClipRenameWindow.checkBoxes.whoseTitle.is("Clear Existing Name").first.checkboxSet({ targetValue: "Enable" });
                                                                  
                                                                      // Enable Numbering Checkbox
                                                                      batchClipRenameWindow.checkBoxes.whoseTitle.is("Numbering").first.checkboxSet({ targetValue: "Enable" });
                                                                  
                                                                      // Set Add "Insert" field
                                                                      batchClipRenameWindow.textFields.allItems[7].elementSetTextFieldWithAreaValue({ value: baseName });
                                                                  
                                                                      // Set "Separate With" field
                                                                      batchClipRenameWindow.textFields.allItems[14].elementSetTextFieldWithAreaValue({ value: "_" });
                                                                  
                                                                      // Click OK
                                                                      batchClipRenameWindow.buttons.whoseTitle.is("OK").first.elementClick();
                                                                  
                                                                      // Wait for Window to Disappear
                                                                      batchClipRenameWindow.elementWaitFor({ waitType: "Disappear" });
                                                                  }
                                                                  
                                                                  function main() {
                                                                      const clips = getSelectedClips();
                                                                  
                                                                      let selections = clips.reduce((acc, clip) => {
                                                                          let location = clip.preceedingMemoryLocationName;
                                                                          if (!acc[location]) {
                                                                              acc[location] = {
                                                                                  startTime: clip.startTime,
                                                                                  endTime: clip.endTime,
                                                                              };
                                                                          } else {
                                                                              acc[location].endTime = Math.max(acc[location].endTime, Number(clip.endTime));
                                                                          }
                                                                          return acc;
                                                                      }, {});
                                                                  
                                                                      for (let memoryLocationName in selections) {
                                                                          if (selections.hasOwnProperty(memoryLocationName)) {
                                                                  
                                                                              sf.ui.proTools.appActivate();
                                                                  
                                                                              sf.app.proTools.setTimelineSelection({
                                                                                  inTime: String(selections[memoryLocationName].startTime),
                                                                                  outTime: String(selections[memoryLocationName].endTime),
                                                                              });
                                                                  
                                                                              // Hack to ensure the clip selection gets updated in the clips list
                                                                              const selectedTrackNames = sf.ui.proTools.selectedTrackNames;
                                                                              sf.ui.proTools.trackSelectByName({ names: selectedTrackNames });
                                                                  
                                                                              batchRenameClips(memoryLocationName);
                                                                          }
                                                                      }
                                                                  }
                                                                  
                                                                  main();
                                                                  

                                                                  Let me know how it goes for you.

                                                                  1. DDylan Furrow @Dylan_Furrow
                                                                      2024-10-10 15:26:08.672Z

                                                                      Works great @Kitch, thank you so much for all your help!

                                                                      1. Kitch Membery @Kitch2024-10-10 22:56:49.272Z

                                                                        Awesome! Glad it works. :-)
                                                                        Thanks for reporting back!