Script suddenly stopped working - failing at "duplicate playlists" - since last PT update?
Hi all,
So I have a script that I use to send off listening copies - the script:
- renames the printed audio file after the track (getting rid of the PT suffixes)
- duplicates the track and renames it.
- makes the first (limiter) plugin active, opens it, copies the settings, closes it and makes it inactive.
- opens Audiosuite plugin of the same, pastes the settings, renders the audio and closes it.
- renames the audio file.
(I use this so I can print a mix without the final limiter but send out the listening copy with the limiter.
Since the last pro tools update - it seems to fail on the " duplicate playlist" line.
sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.is('Playlist selector').first.popupMenuSelect({ menuPath: ["Duplicate Main Playlist..."]
I notice this has been reported before - Pro Tools 2024.3.0 Playlist selector - and then fixed - is this the same sort of issue? nothing has changed my end!
Thanks all for any help :) @Kitch
Script below:
if (!sf.ui.proTools.isRunning) throw `Pro Tools is not running`;
sf.ui.proTools.appActivateMainWindow();
sf.ui.proTools.selectedTrack.trackOpenRenameDialog();
sf.keyboard.press({keys: 'cmd+c'})
sf.keyboard.press({keys: 'return'})
sf.ui.proTools.menuClick({
menuPath: ["Clip", "Rename..."],
});
sf.keyboard.press({keys: 'cmd+v'})
sf.keyboard.press({keys: 'return'})
sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.is('Playlist selector').first.popupMenuSelect({
menuPath: ["Duplicate Main Playlist..."],
});
sf.keyboard.press({keys: 'return'})
sf.ui.proTools.selectedTrack.trackOpenRenameDialog();
sf.keyboard.press({keys: 'cmd+v'})
sf.keyboard.press({keys: 'right'})
sf.keyboard.press({keys: 'space'})
sf.keyboard.press({keys: 'shift+l'})
sf.keyboard.press({keys: 'shift+i'})
sf.keyboard.press({keys: 'shift+m'})
sf.keyboard.press({keys: 'return'})
sf.ui.proTools.selectedTrack.trackInsertToggleActive({
insertNumber: 1,
});
sf.ui.proTools.selectedTrack.trackInsertToggleShow();
sf.keyboard.press({
keys: "cmd+shift+c",
});
sf.ui.proTools.selectedTrack.trackInsertToggleShow();
sf.ui.proTools.selectedTrack.trackInsertToggleActive({
insertNumber: 1,
});
sf.ui.proTools.audioSuiteOpenPlugin({
category: "Dynamics",
name: "FabFilter Pro-L 2",
});
sf.keyboard.press({
keys: "cmd+shift+v",
});
sf.ui.proTools.firstAudioSuiteWindow.audioSuiteRender();
//Calling command "Close Audiosuite" from package "Pro-Tools Decks and Processes"
sf.soundflow.runCommand({
commandId: 'package:ckl7xijxq0006w9101habcbsj',
props: {}
});
sf.ui.proTools.selectedTrack.trackOpenRenameDialog();
sf.keyboard.press({keys: 'cmd+c'})
sf.keyboard.press({keys: 'return'})
sf.ui.proTools.menuClick({
menuPath: ["Clip", "Rename..."],
});
sf.keyboard.press({keys: 'cmd+v'})
sf.keyboard.press({keys: 'return'})
Linked from:
- FForrester Savell @Forrester_Savell
PT 2025.6 has changed some of the names of the Playlist menu. Pretty sure if you change line 17 to
menuPath: ["Duplicate Main Playlist"],
it will fix your issue. I thinkNew...
has changed toNew Playlist
too, if you have any scripts that use that.- AAdrian Breakspear @Adrian_Breakspear
Ah - so it has! Three little dots...they've left them for delete playlists though!
Thanks mate - that fixes it, although I now have to tell it to wait before trying to close the Audiosuite plugin, previously it waited til completion automatically, now I've got to manually tell it to stop for 5sec or so whilst the render happens.
Ah well - it's working again, thanks for your help (and congrats on the new Karnivool!).
- FForrester Savell @Forrester_Savell
Hey mate I did a refactor to take out the key presses. Let me know if this works for you?
//âââââââââââââââââââââââââââââââââââââââââââââââââââââââ // Activate the main Pro Tools window //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ if (!sf.ui.proTools.isRunning) throw `Pro Tools is not running`; sf.ui.proTools.appActivateMainWindow(); //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ // Store the name of the selected track //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ const mixTrackName = sf.ui.proTools.selectedTrack.normalizedTrackName; //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ // Rename selected clip to match track name // Assumes clip on mixTrack is already selected //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] }, `could not find rename window`); //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ // Wait for the clip rename window and set clip name //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ const clipNameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first; clipNameWin.elementWaitFor({ onError: "Continue" }); clipNameWin.groups.whoseTitle.is('Name').first.textFields.first.elementSetTextFieldWithAreaValue({ value: mixTrackName }); clipNameWin.buttons.whoseTitle.is("OK").first.elementClick(); clipNameWin.elementWaitFor({ waitType: "Disappear" }); //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ // Duplicate the playlist and append "LIM" to the name //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ sf.ui.proTools.selectedTrack.popupButtons.whoseTitle.is('Playlist selector').first.popupMenuSelect({ menuPath: ["Duplicate Main Playlist"], }); //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ // Set the duplicated playlist name and confirm //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ const dupPlaylistDialog = sf.ui.proTools.confirmationButtonDialog; dupPlaylistDialog.elementWaitFor(); dupPlaylistDialog.textFields.first.elementSetTextFieldWithAreaValue({ value: `${mixTrackName} + LIM`, useMouseKeyboard: false }); dupPlaylistDialog.buttons.whoseTitle.is('OK').first.elementClick(); dupPlaylistDialog.elementWaitFor({ waitType: "Disappear" }); //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ // Toggle and show track insert for plugin interaction //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ sf.ui.proTools.selectedTrack.trackInsertToggleActive({ insertNumber: 1, }); sf.ui.proTools.selectedTrack.trackInsertToggleShow(); //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ // Copy plugin settings from FabFilter Pro-L 2 //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ const plugInWindow = sf.ui.proTools.windows.whoseTitle.is("Plug-in: FabFilter Pro-L 2").first; plugInWindow.popupButtons.whoseTitle.is('Settings menu').first.popupMenuSelect({ menuPath: ["Copy Settings"], }); //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ //Toggle track insert and open Audiosuite version //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ sf.ui.proTools.selectedTrack.trackInsertToggleShow(); sf.ui.proTools.selectedTrack.trackInsertToggleActive({ insertNumber: 1, }); sf.ui.proTools.audioSuiteOpenPlugin({ category: "Dynamics", name: "FabFilter Pro-L 2", }); //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ // Paste plugin settings in AudioSuite window and render //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ const asSettingsMenu = sf.ui.proTools.firstAudioSuiteWindow.popupButtons.whoseTitle.is('Settings Menu').first; asSettingsMenu.invalidate().popupMenuSelect({ menuPath: ["Paste Settings"], }); sf.ui.proTools.firstAudioSuiteWindow.audioSuiteRender(); //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ // Wait for all modal dialogs and Audiosuite Window to close //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ sf.ui.proTools.waitForNoModals(); sf.ui.proTools.firstAudioSuiteWindow.windowClose() //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ // Rename selected clip to include "LIM" suffix // Assumes clip on mixTrack is already selected //âââââââââââââââââââââââââââââââââââââââââââââââââââââââ sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] }, `could not find rename window`); clipNameWin.elementWaitFor({ onError: "Continue" }); clipNameWin.groups.whoseTitle.is('Name').first.textFields.first.elementSetTextFieldWithAreaValue({ value: `${mixTrackName} + LIM` }); clipNameWin.buttons.whoseTitle.is("OK").first.elementClick(); clipNameWin.elementWaitFor({ waitType: "Disappear" });
Chad Wahlbrink @Chad2025-08-13 14:17:15.378Z
Great refactor, @Forrester_Savell!
Note that we are currently tracking a bug with SF on PT2025.6 that prevents
sf.ui.proTools.waitForNoModals();
andaudioSuiteRender();
from waiting properly.The temporary fix is to use this code snippet after
audioSuiteRender()
or instead ofsf.ui.proTools.waitForNoModals();
:sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: 'Disappear', timeout: -1 });
- FForrester Savell @Forrester_Savell
Chad Wahlbrink @Chad2025-08-13 22:14:05.338Z2025-08-13 22:25:37.913Z
Hi, @Forrester_Savell,
That's interesting. We've received numerous reports of this issue on PT 2025.6 and SF 5.10.6, particularly when users have scripts that wait for bounces to complete or when rendering long-running/multiple Audio Suite plugins. It's not present on PT 2024.10.2 for me.
For example, when I run open the bounce dialog on a mix and run this:
sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.buttons.whoseTitle.is("Bounce").first.elementClick(); sf.ui.proTools.waitForNoModals(); log('Done');
On Pro Tools 2025.6, it logs 'done' immediately.
On Pro Tools 2024.10.2 - sf.ui.proTools.waitForNoModals(); waits for the dialog to disappear.- FForrester Savell @Forrester_Savell
Ah ok - that might make sense. In all my Bounce scripts I use
const audioImportOptionsWin = sf.ui.proTools.dialogWaitForManual({ timeout: -1, dialogTitle: 'Audio Import Options' }).dialog;
The use of
sf.ui.proTools.waitForNoModals();
is used in other functions like Save&Close session, or committing tracks. I haven't seen any errors on those scripts though.
- In reply toForrester_SavellâŹ:
Kitch Membery @Kitch2025-08-13 16:19:22.007Z
Nice work, mate! Thanks for chiming in!
- In reply toForrester_SavellâŹ:AAdrian Breakspear @Adrian_Breakspear
Ok so yes - this works, but occasionally it fails to close the audiosuite plugin (and if the audiosuite plugin is covering the audio file, then fails to rename the audio file!). It does a "can't click that" bleep, but SF doesn't throw an error message.
Not sure why it only happens sometimes! the whole script is way faster than mine of course!
Chad Wahlbrink @Chad2025-08-14 12:31:34.046Z
Was this happening when running the full script shared above?
Did you try swapping out
sf.ui.proTools.waitForNoModals();
in line 84 for:sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: 'Disappear', timeout: -1 });
- AAdrian Breakspear @Adrian_Breakspear
Hey - yes that does seem to fix it! Thanks. Jeez I wish I understood this stuff better...I feel like the engineer who can't fix a pair of headphones when they go down!
Chad Wahlbrink @Chad2025-08-15 02:11:44.651Z
I'm glad that got it working for you, @Adrian_Breakspear!
Chad Wahlbrink @Chad2025-08-15 16:27:26.770Z
Hey, @Adrian_Breakspear and @Forrester_Savell,
The underlying issue with
sf.ui.proTools.firstAudioSuiteWindow.audioSuiteRender();
waiting for the process to complete has been remedied in an upcoming build of SF (5.10.8). Here's an early download link if it helps with this or other scripts:
https://downloads.soundflowcdn.com/5.10/5.10.8/0efbb9e989875498/SoundFlow_5.10.8.pkgThis should allow Forrester's original script to work as expected:
Script suddenly stopped working - failing at "duplicate playlists" - since last PT update? #post-4
- AIn reply toAdrian_BreakspearâŹ:Adrian Breakspear @Adrian_Breakspear
Thanks @Forrester_Savell - I'll try it and report back, I'm sure you've nailed it!
- SIn reply toAdrian_BreakspearâŹ:SoundFlow Bot @soundflowbot
This report was now added to the internal issue tracked by SoundFlow as SF-2051
- SIn reply toAdrian_BreakspearâŹ:SoundFlow Bot @soundflowbot
The linked internal issue SF-2051 has been marked as Done