No internet connection
  1. Home
  2. How to

Pro Tools - Delete Unused Playlists

By Zak Cohen @Zak_Cohen
    2023-11-19 00:15:00.737Z2023-11-19 05:37:52.995Z

    I'm wondering if there's any way to create the following macro:

    -Open the Playlist menu from a track
    -Click "Delete Unused"
    -Select all in list
    -Click "Delete"

    Any suggestions would be appreciated, thanks!

    • 13 replies

    There are 13 replies. Estimated reading time: 13 minutes

    1. Kitch Membery @Kitch2024-02-14 21:25:47.244Z

      Hi @Zak_Cohen,

      This exact question came up in the SoundFlow hangout today (asked by @Dreamcatcher_Studio ), and I found this old thread so I thought I'd answer it here.

      function deleteAllUnusedPlaylists() {
          sf.ui.proTools.appActivateMainWindow();
          sf.ui.proTools.mainWindow.invalidate();
      
          sf.ui.proTools.selectedTrack.popupButtons.allItems[1].popupMenuSelect({
              menuPath: ["Delete Unused..."],
          });
      
          const deleteUnusedPlaylistsWin = sf.ui.proTools.windows.whoseTitle.is("Delete Unused Playlists").first;
      
          deleteUnusedPlaylistsWin.elementWaitFor();
      
          const deleteUnusedPlaylistsTable = deleteUnusedPlaylistsWin.tables.whoseTitle.is("List of playlists").first;
      
          deleteUnusedPlaylistsTable.childrenByRole("AXRow").map(row => {
              const cell = row.childrenByRole("AXCell").first;
              const staticTextBtn = cell.childrenByRole("AXStaticText").first;
      
              // Quirk: The playlist rows text fields need to be clicked twice for some reason otherwise every other row is selected.
              staticTextBtn.elementClick();
              staticTextBtn.elementClick();
          });
      
          deleteUnusedPlaylistsWin.buttons.whoseTitle.is("Delete").first.elementClick();
          deleteUnusedPlaylistsWin.elementWaitFor({waitForNoElement:true});    
      }
      
      deleteAllUnusedPlaylists();
      

      It seems that there is a quirk when selecting the rows in the table programmatically. After trying a few things I found that clicking the static text in the rows twice, ensures the rows are selected. Nice and fast!

      FYI: @Chris_Shaw, @Mike_Wax, @Owen_Granich_Young (Regs at the SoundFlow Hangout!)

      1. ZZak Cohen @Zak_Cohen
          2024-02-23 02:50:14.247Z

          Thank you!
          The script is working but for some reason, the keyboard trigger I'm using (control+cmd+D) will only work when the D is pressed first. If I hold down control and cmd before pushing D, nothing happens. Any ideas?

          1. Kitch Membery @Kitch2024-02-23 03:38:12.821Z

            Hi @Zak_Cohen,

            Using the combination "control+cmd+D" will be problematic when selecting from a popup menu. When SoundFlow is trying to open the menu holding down "control+cmd" will cause the playlists to show. Try doing this manually in Pro Tools and you'll see what I mean. Instead, try to use a keyboard shortcut that does not use problematic modifiers.

            But you are correct in noticing that the track needs to be selected... You could instead find the topmost track in the edit window, and use that track to click the "Delete Unused..." menu item in the Track header popup. (Unless there is a "Delete unused playlists" main menu item in Pro Tools that I'm overlooking?)

            function getTopMostTrack() {
                const editTimeLineTopY = sf.ui.proTools.mainWindow.timelineFocusButton.frame.y;
            
                const topTrack = sf.ui.proTools.visibleTrackHeaders.filter(h => h.frame.y >= editTimeLineTopY)[0];
            
                return topTrack;
            }
            
            function deleteAllUnusedPlaylists() {
                sf.ui.proTools.appActivateMainWindow();
                sf.ui.proTools.mainWindow.invalidate();
            
                const topMostTrack = getTopMostTrack();
            
                topMostTrack.popupButtons.allItems[1].popupMenuSelect({
                    menuPath: ["Delete Unused..."],
                });
            
                const deleteUnusedPlaylistsWin = sf.ui.proTools.windows.whoseTitle.is("Delete Unused Playlists").first;
            
                deleteUnusedPlaylistsWin.elementWaitFor();
            
                const deleteUnusedPlaylistsTable = deleteUnusedPlaylistsWin.tables.whoseTitle.is("List of playlists").first;
            
                deleteUnusedPlaylistsTable.childrenByRole("AXRow").map(row => {
                    const cell = row.childrenByRole("AXCell").first;
                    const staticTextBtn = cell.childrenByRole("AXStaticText").first;
            
                    // Quirk: The playlist rows text fields need to be clicked twice for some reason otherwise every other row is selected.
                    staticTextBtn.elementClick();
                    staticTextBtn.elementClick();
                });
            
                deleteUnusedPlaylistsWin.buttons.whoseTitle.is("Delete").first.elementClick();
                deleteUnusedPlaylistsWin.elementWaitFor({ waitForNoElement: true });
            }
            
            deleteAllUnusedPlaylists();
            
            1. Counter to how a lot of people do things, I usually have the master track and click track at the top of my edit window. Could this script be modified to select the first available audio track in order to run the rest of the script?

              1. Also, I selected the top audio track and ran the script and got the following error:
                Could not click popup menu item (Delete Unused Playlists: Line 15)

                Is that because of the update to the latest Pro Tools update and/or Sonoma 14.3.1 ?

          2. In reply toKitch:
            ZZak Cohen @Zak_Cohen
              2024-02-23 02:52:35.046Z

              Also, the tracks need to be selected before the script is executed, while the actual menu item "delete unused playlists" does not require this. Not a big deal, but selecting all tracks can be cumbersome when there are folder tracks involved.

            • M
              In reply toZak_Cohen:
              Matthew Bronleewe @Matthew_Bronleewe
                2024-05-06 21:06:49.427Z

                Looking into this again... I'm still getting the "Could not click popup menu item (Delete Unused Playlists: Line 15" error. This script would be super helpful as I'm cleaning up a session to send to the mixer. In a perfect world, the script would comb through the session and get rid of any unused playlists on any tracks. Thoughts here?

                1. Filip Killander @FilipKillander
                    2024-07-11 07:54:15.108Z

                    I would love that. I've been trying to get that to work as well, but no success yet!

                  • In reply toZak_Cohen:
                    Donny @Dreamcatcher_Studio
                      2024-07-10 01:08:18.170Z

                      @Matthew_Bronleewe

                      Sorry I'm late, but this may help you. When there are no additional playlists, the popup menu will be greyed out. I modified the code to check to see if the popup menu option exists first. I'm not sure if this is the best way to do it, but it works!

                      function deleteAllUnusedPlaylists() {
                          sf.ui.proTools.appActivateMainWindow();
                      
                          var deletePlaylistsEnabled = sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.contains('Delete Unused...').exists
                          
                          const deleteUnusedPlaylistsWin = sf.ui.proTools.windows.whoseTitle.is("Delete Unused Playlists").first;
                      
                      
                              if (deletePlaylistsEnabled) {
                      
                                  sf.ui.proTools.selectedTrack.popupButtons.allItems[1].popupMenuSelect({ 
                                  menuPath: ["Delete Unused..."],
                                  });
                      
                                  deleteUnusedPlaylistsWin.elementWaitFor();
                      
                                  const deleteUnusedPlaylistsTable = deleteUnusedPlaylistsWin.tables.whoseTitle.is("List of playlists").first;
                      
                                  deleteUnusedPlaylistsTable.childrenByRole("AXRow").map(row => {
                                      const cell = row.childrenByRole("AXCell").first;
                                      const staticTextBtn = cell.childrenByRole("AXStaticText").first;
                      
                                      // Quirk: The playlist rows text fields need to be clicked twice for some reason otherwise every other row is selected.
                                      staticTextBtn.elementClick();
                                      staticTextBtn.elementClick();
                                  });
                      
                                  deleteUnusedPlaylistsWin.buttons.whoseTitle.is("Delete").first.elementClick();
                                  deleteUnusedPlaylistsWin.elementWaitFor({waitForNoElement:true});    
                              }
                              else {
                                  log ("No playlists to delete.")
                              }
                          }
                      
                      deleteAllUnusedPlaylists();
                      1. Donny @Dreamcatcher_Studio
                          2024-10-22 07:27:48.734Z

                          @Kitch ,

                          I hope you're doing well! I miss you guys.

                          What would be a more reliable way to check to see if 'Delete Unused...' is available in the pop up menu before trying to get to the Delete Unused Playlists window?

                          1. I don't think there's a way to detect if a popup menu item is enabled or not ( @Kitch ?).
                            But you can wait for the Delete Unused Playlist window to appear and bail if it doesn't using the following:

                            sf.ui.proTools.selectedTrack.popupButtons.allItems[1].popupMenuSelect({
                                menuPath: ["Delete Unused..."],
                            });
                            
                            const deleteUnusedPlaylistsWin = sf.ui.proTools.windows.whoseTitle.is("Delete Unused Playlists").first;
                            
                            const playlistsExists = deleteUnusedPlaylistsWin.elementWaitFor({
                                timeout: 500,
                                onError: "Continue"
                            }).success;
                            
                            if (!playlistsExists) {
                                log("Delete Unused...", "No additional playlists exists")
                                sf.ui.proTools.appActivateMainWindow(); // This closes the popup menu
                                throw 0
                            }
                            
                            1. Kitch Membery @Kitch2024-10-22 22:53:09.384Z

                              @Dreamcatcher_Studio & @Chris_Shaw,

                              Here is another option using the menuSelector property to see if the Menu Item exists and is enabled, if the menu selection fails (ie no enabled menu item for "Delete Unused..." exists) then instead of throwing a SoundFlow error, have a function to close the popup menu using the appActivateMainWindow method.

                              sf.ui.proTools.appActivateMainWindow();
                              
                              const playlistSelector = sf.ui.proTools.selectedTrack.getFirstWithDescription("Playlist selector");
                              
                              playlistSelector.popupMenuSelect({
                                  menuSelector: items => items.find(mi => mi.path[0] === "Delete Unused..." && mi.element.isEnabled)
                              }, () => sf.ui.proTools.appActivateMainWindow());
                              

                              FUN!

                              1. Donny @Dreamcatcher_Studio
                                  2024-10-22 23:07:00.074Z

                                  @Kitch @Chris_Shaw,

                                  Thanks so much.
                                  You guys are the best!