No internet connection
  1. Home
  2. How to

Get selected Clip Name

By Benjamin Hörbe @Benjamin_Horbe
    2021-01-19 10:31:36.089Z

    Hi Community,

    is there a more elegant way to get the name of the selected clip from the clip list? I know, I can get the clip name from the rename window, but this won't be an option for my usecase.

    The code below does the job, but is pretty slow and outputs very unhandy strings like "{"title":"Selected. Audio Clip\n\"test PT Text TOols_01\" ","role":"AXStaticText","fullRole":"AXStaticText"}" with "test PT Text TOols_01" being the clip name.

    var i = 1
    var y = -1
    
        for (i = 0; i < 16; i++) {
    
            var test = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first.children.whoseRole.is("AXRow").whoseValue.is('').allItems[i].children.whoseRole.is("AXCell").allItems[1].children.whoseRole.is("AXStaticText").whoseTitle.contains('Selected').exists
            if (test === true ){break ;}
            //log(i, test)
            //log ("y",y)
        }
    
        var y = i;
    
    
    var selectedClip = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first.children.whoseRole.is("AXRow").whoseValue.is('').allItems[y].children.whoseRole.is("AXCell").allItems[1].children.whoseRole.is("AXStaticText").whoseTitle.contains('Selected').first
    log(selectedClip)
    

    Any suggestions?
    Cheers from Berlin

    Solved in post #2, click to view
    • 17 replies

    There are 17 replies. Estimated reading time: 13 minutes

    1. Hey Benjamin!

      This should do it!

      function getSelectedClipNamesFromClipList() {
          const clipsTable = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first;
      
          // Get all selected clips
          const selectedClips = clipsTable.children.whoseRole.is("AXRow").allItems.map(row =>
              row.children[1].children.first.value.value).filter(c => c.startsWith('Selected. '));
      
          // Extract clip names
          const clipNames = selectedClips.map(c => c.split('"')[1]);
      
          return clipNames
      };
      
      const selectedClip = getSelectedClipNamesFromClipList()[0];
      
      log(selectedClip)
      
      Reply1 LikeSolution
      1. Benjamin Hörbe @Benjamin_Horbe
          2021-01-20 07:37:40.758Z

          It works like a charm!
          Thanks a lot!

        • B
          In reply toBenjamin_Horbe:
          Brian Mullany @Brian_Mullany
            2024-11-13 12:32:51.567Z

            Heya @raphaelsepulveda , this no longer works in PT 2024.10.

            Something around the clipsTable is returning nothing. Any chance something in the backend has changed and needs to be updated here?

            The log of selectedClip returns

            undefined

            .
            The log of clipNames returns

            []

            Any help?

            tying to log clipsTable bombs SoundFlow out with the following error:

            !! Command Error: test 2 [user:cl32uwy7y00010b10mqt1wp9o:cm3fu6a0q0000bo108nt9ysy7]:
            Error: Couldn't get item #0 as the array length was 0 - sf.ui.app('com.avid.ProTools')..tables.whoseTitle.is('CLIPS').first (AxElementArrayIndexedItem)
            (test 2 line 6)

            1. Raphael Sepulveda @raphaelsepulveda2024-11-13 18:13:26.353Z2025-02-04 17:53:45.594Z

              Hey @Brian_Mullany, nowadays I would opt for a different approach for this.

              Updated Feb 4th, 2025 — Fades are now removed by default (Thanks Chris Shaw!)

              /** @param {{ includeFades?: boolean }} [args] */
              function getSelectedClipInfo({ includeFades = false } = {}) {
                  const selectionInTime = Number(
                      sf.app.proTools.getTimelineSelection().inTime
                  );
                  const selectionOutTime = Number(
                      sf.app.proTools.getTimelineSelection().outTime
                  );
              
                  const fullySelectedClips = sf.app.proTools.getSelectedClipInfo().clips
                      .reduce((clips, clip) => {
                          if (!includeFades) {
                              if (clip.clipName.startsWith("(fade") || clip.clipName === "(cross fade)") {
                                  return clips;
                              }
                          }
              
                          const clipStartTime = Number(clip.startTime);
                          const clipEndTime = Number(clip.endTime) - 1;
              
                          const isClipFullySelected = clipStartTime >= selectionInTime
                              && clipEndTime < selectionOutTime;
              
                          if (isClipFullySelected) {
                              // Remove any extensions from clipName (.L, .R...)
                              const clipName = clip.clipName.replace(/\.\w+$/, "");
              
                              // Filter repeated clips
                              if (clips.some(clip => clip.clipName === clipName)) return clips;
              
                              clips.push({
                                  clipName,
                                  trackName: clip.trackName,
                                  startTime: clipStartTime,
                                  endTime: clipEndTime
                              });
                          }
              
                          return clips;
                      }, []);
              
              
                  const names = fullySelectedClips.map(clip => clip.clipName);
              
                  return { clips: fullySelectedClips, names };
              }
              
              const selectedClipNames = getSelectedClipInfo().names;
              
              log(selectedClipNames);
              

              This script does the following:

              • Gets clip info through the PT SDK, which is more robust than scraping the UI.
              • Fixes an issue with the original SDK command where adjacent clips would be listed as selected.
              • Removes multichannel duplicates (i.e. stereo files would be listed as two different files).
              1. BBrian Mullany @Brian_Mullany
                  2024-11-13 18:24:27.376Z

                  You’re amazing thank you.

                  I’ll try tomorrow morning and let you know :)

                  Appreciate the super fast help

                  1. BBrian Mullany @Brian_Mullany
                      2024-11-14 09:51:28.611Z2024-11-14 10:00:02.641Z

                      @raphaelsepulveda

                      Unfortunately it doesn't work :(

                      It returns the stereo pair information (.L and .R) when I need it to just return the clip name in the edit window as a single line string.

                      14.11.2024 10:48:35.20 [Backend]: [LOG] [
                      "Reference Track_01.L",
                      "Reference Track_01.R"
                      ]

                      It should just return

                      Reference Track_01

                      in this example

                      :)

                      edit

                      I've frankenstined something together that works on stereo clips, but it is deeply inelegant because I'm a complete noob. And it wouldn't work on Mono Clips that don't append the .L or .R

                      const selectedClipFull = getSelectedClipNames().names[0];
                      let selectedClip = selectedClipFull.slice(0, -2);
                      
                      
                      log(selectedClip)
                      
                      1. BBrandon Jiaconia @Brandon_Jiaconia
                          2024-11-14 14:02:44.502Z

                          I use something similar to get rid of the .L .R in clips names. The cool thing about Raphaels script is it returns the names of multiple clips. I've been using this for only one selected clip. I'm also a noob so I'm sure there is a better way to go about it.

                          sf.ui.proTools.appActivateMainWindow();
                          
                          const selectedClipInfo = sf.app.proTools.getSelectedClipInfo().clips;
                          
                          const firstSelectedClipName = selectedClipInfo[0].clipName.replace(/\.[LR]$/, "");
                          log(firstSelectedClipName);
                          
                          1. Hey @Brian_Mullany, @Brandon_Jiaconia,
                            I've updated the script above to take care of this.
                            Give it another whirl!

                      2. Chris Shaw @Chris_Shaw2024-11-22 21:33:46.100Z2024-11-22 21:39:53.019Z

                        This is great!
                        The only issue is that it lists fades as clips so some additional filtering is needed if you only want clips. You can just add this to the code:

                        const clipsAndFadesInfo = getSelectedClipInfo()
                        
                        const clipsOnlyInfo = {
                            "clips": clipsAndFadesInfo.clips
                                .filter(c => !c.clipName.startsWith("(fade") && c.clipName !== "(cross fade)"),
                            "names": clipsAndFadesInfo.names.filter(n => !n.startsWith("(fade") && n == "(cross fade)")
                        }
                        
                        log(clipsOnlyInfo)
                        
                        1. Oops! Forgot to check for cross fades as well.
                          I've updated the code above.

                          1. Teamwork makes the dream work. Thanks @Chris_Shaw! 🙏🏼

                    • B
                      In reply toBenjamin_Horbe:
                      Brian Mullany @Brian_Mullany
                        2025-02-04 12:30:13.350Z

                        Hey Team, I'm struggling with this to just get the clip name out as a string.

                        Running Raphael's script I get

                        04.02.2025 13:28:02.49 <info> [Backend]: [LOG] [
                            "(fade in)",
                            "AMBRain_Rain Drops on Plastic Pool Tarp 01_tonic_48khz",
                            "(fade out)"
                        ]
                        
                        

                        Then adding Chris's Filter I get:

                        04.02.2025 13:29:08.11 <info> [Backend]: [LOG] {
                                "clips": [
                                {
                                    "clipName": "AMBRain_Rain Drops on Plastic Pool Tarp 01_tonic_48khz",
                                    "trackName": "Mono",
                                    "startTime": 2983936,
                                    "endTime": 35831807
                                }
                            ],
                                "names": []
                        

                        All I would love to have is the part AMBRain_Rain Drops on Plastic Pool Tarp 01_tonic_48khz as an output so I can copy it to my clipboard in my other script. Please help! I've tried a million little things but this is so beyond me

                        1. Hey @Brian_Mullany, I just updated my script above incorporating Chris' method of removing fades, that now allows us to easily get the first selected clip name like so:

                          const selectedClipNames = getSelectedClipInfo().names;
                          const firstSelectedClipName = selectedClipNames[0];
                          
                          1. BBrian Mullany @Brian_Mullany
                              2025-02-06 10:03:35.350Z

                              Thanks! Unfortunately it's not quite working.

                              It outputs

                              [
                                  "AMBRain_Rain Drops on Plastic Pool Tarp 01_tonic_48khz"
                              ]
                              

                              When it should output:

                              AMBRain_Rain Drops on Plastic Pool Tarp 01_tonic_48khz
                              

                              Without ][, line breaks, and "". Any ideas? :)

                                1. BBrian Mullany @Brian_Mullany
                                    2025-02-06 21:45:09.848Z

                                    Oh I see! I needed that extra bit of code. Sorry I thought it was included :) thanks so much for the video walkthrough as well. Really appreciate it! Thanks!

                                    1. No problem! Glad it's all sorted 🙌🏼