Hi, I'm trying to create a script that will export files as clips to a newly created folder named like the session folder in a given directory, but it's not working consistently.
Thanks, Udi
//Calling command "goto current folder" from package "Artlist"
sf.soundflow.runCommand({
commandId: 'package:clq5fljfi0004ed10z4tny2jw',
props: {}
});
sf.wait({
intervalMs: 300,
});
sf.keyboard.press({
keys: "cmd+up, cmd+c",
});
sf.wait({
intervalMs: 300,
});
//Calling command "Focus Pro Tools, Center Cursor on Edit Window" from package "Pro Tools" (installed from user/pkg/version "srAasovvDiQacRZ2mcId4RrOA8R2/ckp49i4j60000a2100yfwywgf/cln0nxiji0000yp102352fxp9")
sf.soundflow.runCommand({
commandId: 'user:ckp49i4j60000a2100yfwywgf:ck1w3h03r000tef10hc8eks5k',
props: {}
});
sf.wait({
intervalMs: 300,
});
sf.keyboard.press({
keys: "cmd+shift+k",
});
sf.wait({
intervalMs: 300,
});
sf.ui.proTools.windows.whoseTitle.is("Export Selected").first.buttons.whoseTitle.is("Choose...").first.elementClick();
sf.wait({
intervalMs: 300,
});
sf.keyboard.press({
keys: "cmd+shift+g",
});
sf.wait({
intervalMs: 300,
});
sf.keyboard.press({
keys: "backspace",
});
sf.wait({
intervalMs: 300,
});
sf.keyboard.type({
text: "/Volumes/Mor M/ARTLIST 2024/STEMS 2024",
});
sf.wait({
intervalMs: 300,
});
sf.keyboard.press({
keys: "return",
});
sf.wait({
intervalMs: 300,
});
sf.keyboard.press({
keys: "cmd+shift+n",
});
sf.wait({
intervalMs: 300,
});
sf.keyboard.press({
keys: "cmd+v",
});
sf.wait({
intervalMs: 300,
});
sf.keyboard.press({
keys: "return",
});
sf.wait({
intervalMs: 300,
});
sf.keyboard.press({
keys: "cmd+down, return",
});
sf.wait({
intervalMs: 300,
});
sf.keyboard.press({
keys: "return",
});
- Nathan Salefski @nathansalefski
Try this. It will bring up a prompt to select a folder. Within that prompt you can also create a new folder and name it. You can also change the bit depth and sample rate in by adjusting the code in Line 87:
function clipExpProp(bitDepth, sampleRate) { const clipExpWin = sf.ui.proTools.windows.whoseTitle.is('Export Selected').first; clipExpWin.popupButtons.allItems[3].popupMenuSelect({ menuPath: ['WAV'], }); clipExpWin.popupButtons.allItems[2].popupMenuSelect({ menuPath: ['Interleaved'], }); clipExpWin.popupButtons.allItems[1].popupMenuSelect({ menuPath: [bitDepth], }); clipExpWin.popupButtons.first.popupMenuSelect({ menuPath: [sampleRate], }); clipExpWin.checkBoxes.whoseTitle.is('Enforce Avid Compatibility').first.checkboxSet({ targetValue: 'Disable', }); clipExpWin.radioButtons.whoseTitle.is('Auto Renaming').first.checkboxSet({ targetValue: 'Enable', }); } function navigateToFolder(folder) { const openWin = sf.ui.proTools.windows.whoseTitle.is('Open').first; openWin.elementWaitFor(); sf.keyboard.type({ text: '/' }); openWin.sheets.first.elementWaitFor(); openWin.sheets.first.textFields.first.elementSetTextAreaValue({ value: `${folder}`, }); sf.keyboard.press({ keys: 'return' }); openWin.sheets.first.elementWaitFor({ waitType: 'Disappear' }); sf.wait({ intervalMs: 250 }); openWin.buttons.whoseTitle.is('Open').first.elementClick(); openWin.elementWaitFor({ waitType: 'Disappear' }); } function exportClipsToFolder(bitDepth, sampleRate, folder) { const clipsMenu = sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first; clipsMenu.popupMenuSelect({ menuPath: ['Export Clips as Files...'], }); const clipExpWin = sf.ui.proTools.windows.whoseTitle.is('Export Selected').first; clipExpProp(bitDepth, sampleRate); clipExpWin.buttons.whoseTitle.is('Choose...').first.elementClick(); navigateToFolder(folder); clipExpWin.buttons.whoseTitle.is('Export...').first.elementClick(); sf.ui.proTools.waitForNoModals(); } function main() { let exportFolder = sf.interaction.selectFolder({ prompt: "Please select export destination", }).path; sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); let clipList = sf.ui.proTools.getMenuItem('View', 'Other Displays', 'Clip List'); let originalClipListState; if (!clipList.isMenuChecked) { sf.ui.proTools.menuClick({ menuPath: ['View', 'Other Displays', 'Clip List'] }); originalClipListState = 'Off'; } exportClipsToFolder('24 Bit', '48 kHz', exportFolder); if (originalClipListState === 'Off') { sf.ui.proTools.menuClick({ menuPath: ['View', 'Other Displays', 'Clip List'] }); } } main();
- UIn reply toUdi_Simhon⬆:Udi Simhon @Udi_Simhon
Thanks!! works perfect!
Is there a way to create a new folder automatically named as the current session folder name?Nathan Salefski @nathansalefski
Definitely, where would you like the folder to be created?
- UUdi Simhon @Udi_Simhon
I wish to choose a folder using finder and then in that folder pro tools will create a new folder (named after the current session folder) and will export all files to that folder 🙏🏼
Nathan Salefski @nathansalefski
You can change the main function to this:
function main() { let chosenDirectory = sf.interaction.selectFolder({ prompt: `Please choose where you'd like to create your folder`, }).path; sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); const sessionPath = sf.ui.proTools.mainWindow.sessionPath; let sessionName = sessionPath.split('/').slice(-1)[0].split('.ptx')[0] sf.file.directoryCreate({ path: `${chosenDirectory}/${sessionName}` }); let exportFolder = `${chosenDirectory}/${sessionName}`; let clipList = sf.ui.proTools.getMenuItem('View', 'Other Displays', 'Clip List'); let originalClipListState; if (!clipList.isMenuChecked) { sf.ui.proTools.menuClick({ menuPath: ['View', 'Other Displays', 'Clip List'] }); originalClipListState = 'Off'; } exportClipsToFolder('24 Bit', '48 kHz', exportFolder); if (originalClipListState === 'Off') { sf.ui.proTools.menuClick({ menuPath: ['View', 'Other Displays', 'Clip List'] }); } } main();
- UUdi Simhon @Udi_Simhon
Thanks !! it's working great !!! @Nathan_Salefski
- UIn reply toUdi_Simhon⬆:Udi Simhon @Udi_Simhon
@nathansalefski Hi! :)
After upgrading the OS to 14.1.2 (23B92) and Pro Tools to 2024.10.0, this script stopped working.
Please advise what you recommend to do 🙏🏼Error Log:
22.04.2025 20:23:18.80 <info> [Backend]: [KeyboardInterfaceController] #Key: ctrl+command+alt+8 (28) -> Export Stems 48 to Stems Folder [clylqnaye00028r10415933pr] 22.04.2025 20:23:18.80 <info> [Backend]: >> Command: Export Stems 48 to Stems Folder [user:clp00xu1a0000gw10kszjhh4p:clylqmtl200018r10p03vyidt] [WithFrontmostAppPreservedAction] Saving the current frontmost app 'com.avid.ProTools' before running callback... 22.04.2025 20:23:21.31 <info> [Backend]: [WithFrontmostAppPreservedAction] Re-activating the app 'com.avid.ProTools' after callback... [NSRunningApplication (static)] Checking for running apps with bundle 'com.avid.ProTools' 22.04.2025 20:23:21.31 <info> [Backend]: NSArray.ArrayFromHandle count = 1 22.04.2025 20:23:21.31 <info> [Backend]: [WithFrontmostAppPreservedAction] Re-activation succeeded after 0.00 seconds 22.04.2025 20:23:21.31 <info> [Backend]: [NSRunningApplication (static)] Checking for running apps with bundle 'com.avid.ProTools' 22.04.2025 20:23:21.31 <info> [Backend]: NSArray.ArrayFromHandle count = 1 22.04.2025 20:23:21.41 <info> [Backend]: Mouse current pos is: (1209.2734375, 610.4375) Clicking with mouse here: (10, 73) 22.04.2025 20:23:21.42 <info> [Backend]: Moving mouse back to: (1209.2734375, 610.4375) 22.04.2025 20:23:21.43 <info> [Backend]: Position is now: (1209.2734375, 610.4375) 22.04.2025 20:23:21.47 <info> [Backend]: Logging error in action (01) ClickButtonAction: ClickButtonAction requires UIElement 22.04.2025 20:23:21.50 <info> [Backend]: Logging error in action (01) ClickButtonAction: ClickButtonAction requires UIElement 22.04.2025 20:23:21.52 <info> [Backend]: Logging error in action (01) OpenPopupMenuFromElementAction: popupMenu.open.fromElement requires an element Logging error in action (01) PopupMenuSelectAction: Could not open popup menu 22.04.2025 20:23:21.52 <info> [Backend]: !! Command Error: Export Stems 48 to Stems Folder [user:clp00xu1a0000gw10kszjhh4p:clylqmtl200018r10p03vyidt]: Could not open popup menu (Export Stems 48 to Stems Folder: Line 50) popupMenu.open.fromElement requires an element Couldn't get item #0 as the array length was 0 - sf.ui.app('com.avid.ProTools').<unknown>.popUpButtons.whoseTitle.is('Clip List').first (AxElementArrayIndexedItem) << Command: Export Stems 48 to Stems Folder [user:clp00xu1a0000gw10kszjhh4p:clylqmtl200018r10p03vyidt] 22.04.2025 20:23:22.93 <info> [EditorWindow:Renderer]: Active Focus Container: app Line 33963 file:///Applications/SoundFlow.app/Contents/Helpers/SoundFlow.app/Contents/Resources/app.asar/dist/editor.js
Thanks!
Kitch Membery @Kitch2025-04-29 19:07:16.381Z
Hi @Udi_Simhon
Can you provide a copy of the script that is failing here in the thread?
And better still, a screen recording would be great.
Also, any extra information that might help troubleshoot would be helpful. For instance, is there a particular place in the workflow where the script fails?
Once I have that information, I'll take a look.
Thanks in advance.
- UUdi Simhon @Udi_Simhon
Thanks @Kitch
Here is the scriptfunction clipExpProp(bitDepth, sampleRate) { const clipExpWin = sf.ui.proTools.windows.whoseTitle.is('Export Selected').first; clipExpWin.popupButtons.allItems[3].popupMenuSelect({ menuPath: ['WAV'], }); clipExpWin.popupButtons.allItems[2].popupMenuSelect({ menuPath: ['Interleaved'], }); clipExpWin.popupButtons.allItems[1].popupMenuSelect({ menuPath: [bitDepth], }); clipExpWin.popupButtons.first.popupMenuSelect({ menuPath: [sampleRate], }); clipExpWin.checkBoxes.whoseTitle.is('Enforce Avid Compatibility').first.checkboxSet({ targetValue: 'Disable', }); clipExpWin.radioButtons.whoseTitle.is('Replacing With New Files').first.checkboxSet({ targetValue: 'Enable', }); } function navigateToFolder(folder) { const openWin = sf.ui.proTools.windows.whoseTitle.is('Open').first; openWin.elementWaitFor(); sf.keyboard.type({ text: '/' }); openWin.sheets.first.elementWaitFor(); openWin.sheets.first.textFields.first.elementSetTextAreaValue({ value: `${folder}`, }); sf.keyboard.press({ keys: 'return' }); openWin.sheets.first.elementWaitFor({ waitType: 'Disappear' }); sf.wait({ intervalMs: 250 }); openWin.buttons.whoseTitle.is('Open').first.elementClick(); openWin.elementWaitFor({ waitType: 'Disappear' }); } function exportClipsToFolder(bitDepth, sampleRate, folder) { const clipsMenu = sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first; clipsMenu.popupMenuSelect({ menuPath: ['Export Clips as Files...'], }); const clipExpWin = sf.ui.proTools.windows.whoseTitle.is('Export Selected').first; clipExpProp(bitDepth, sampleRate); clipExpWin.buttons.whoseTitle.is('Choose...').first.elementClick(); navigateToFolder(folder); clipExpWin.buttons.whoseTitle.is('Export...').first.elementClick(); sf.ui.proTools.waitForNoModals(); } function main() { let chosenDirectory = sf.interaction.selectFolder({ prompt: `Please choose where you'd like to create your folder`, }).path; sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); const sessionPath = sf.ui.proTools.mainWindow.sessionPath; let sessionName = sessionPath.split('/').slice(-1)[0].split('.ptx')[0] sf.file.directoryCreate({ path: `${chosenDirectory}/${sessionName}` }); let exportFolder = `${chosenDirectory}/${sessionName}`; let clipList = sf.ui.proTools.getMenuItem('View', 'Other Displays', 'Clip List'); let originalClipListState; if (!clipList.isMenuChecked) { sf.ui.proTools.menuClick({ menuPath: ['View', 'Other Displays', 'Clip List'] }); originalClipListState = 'Off'; } exportClipsToFolder('24 Bit', '44.1 kHz', exportFolder); if (originalClipListState === 'Off') { sf.ui.proTools.menuClick({ menuPath: ['View', 'Other Displays', 'Clip List'] }); } } main();
the screenshot+Log:
https://www.dropbox.com/scl/fo/ajlyh6gn7j1hqkmjt4twm/AGeWmzwFZAnspJeuycShVDk?rlkey=6osusj6v3d5yht6ll4h6u44c0&dl=0The script worked in the past.
After upgrading to macOS 14.1.2 and PT 2024.10, it now gets stuck.Kitch Membery @Kitch2025-04-30 17:55:54.895Z
Thanks @Udi_Simhon,
This is untested, but give this a try.
function clipExpProp(bitDepth, sampleRate) { const clipExpWin = sf.ui.proTools.windows.whoseTitle.is('Export Selected').first; clipExpWin.popupButtons.allItems[3].popupMenuSelect({ menuPath: ['WAV'], }); clipExpWin.popupButtons.allItems[2].popupMenuSelect({ menuPath: ['Interleaved'], }); clipExpWin.popupButtons.allItems[1].popupMenuSelect({ menuPath: [bitDepth], }); clipExpWin.popupButtons.first.popupMenuSelect({ menuPath: [sampleRate], }); clipExpWin.checkBoxes.whoseTitle.is('Enforce Avid Compatibility').first.checkboxSet({ targetValue: 'Disable', }); clipExpWin.radioButtons.whoseTitle.is('Replacing With New Files').first.checkboxSet({ targetValue: 'Enable', }); } function navigateToFolder(folder) { const openWin = sf.ui.proTools.windows.whoseTitle.is('Open').first; openWin.elementWaitFor(); sf.keyboard.type({ text: '/' }); openWin.sheets.first.elementWaitFor(); openWin.sheets.first.textFields.first.elementSetTextAreaValue({ value: `${folder}`, }); sf.keyboard.press({ keys: 'return' }); openWin.sheets.first.elementWaitFor({ waitType: 'Disappear' }); sf.wait({ intervalMs: 250 }); openWin.buttons.whoseTitle.is('Open').first.elementClick(); openWin.elementWaitFor({ waitType: 'Disappear' }); } function exportClipsToFolder(bitDepth, sampleRate, folder) { const clipsMenu = sf.ui.proTools.mainWindow.getFirstWithTitle("Show Options menu"); clipsMenu.popupMenuSelect({ menuPath: ['Export Clips as Files...'], }); const clipExpWin = sf.ui.proTools.windows.whoseTitle.is('Export Selected').first; clipExpProp(bitDepth, sampleRate); clipExpWin.buttons.whoseTitle.is('Choose...').first.elementClick(); navigateToFolder(folder); clipExpWin.buttons.whoseTitle.is('Export...').first.elementClick(); sf.ui.proTools.waitForNoModals(); } function main() { let chosenDirectory = sf.interaction.selectFolder({ prompt: `Please choose where you'd like to create your folder`, }).path; sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); const sessionPath = sf.ui.proTools.mainWindow.sessionPath; let sessionName = sessionPath.split('/').slice(-1)[0].split('.ptx')[0] sf.file.directoryCreate({ path: `${chosenDirectory}/${sessionName}` }); let exportFolder = `${chosenDirectory}/${sessionName}`; let clipList = sf.ui.proTools.getMenuItem('View', 'Other Displays', 'Clip List'); let originalClipListState; if (!clipList.isMenuChecked) { sf.ui.proTools.menuClick({ menuPath: ['View', 'Other Displays', 'Clip List'] }); originalClipListState = 'Off'; } exportClipsToFolder('24 Bit', '44.1 kHz', exportFolder); if (originalClipListState === 'Off') { sf.ui.proTools.menuClick({ menuPath: ['View', 'Other Displays', 'Clip List'] }); } } main();
From what I could see, the UI Element for the Clips List popup menu had changed under the hood.
Let me know if that fixes the issue for you :-)
- UUdi Simhon @Udi_Simhon
Thanks @Kitch It Worked!
Kitch Membery @Kitch2025-04-30 23:25:14.711Z
Hi @Udi_Simhon
Thanks for reporting back!
One down one to go. I'll take a look at the other script shortly.
Rock on!