Hi, how to make a short cut with a serie of actions or a script to do that (see the picture). Sorry if it's a newbie question, I've searched the answer in the forum but I didn't find it. Thanks in advance.
Romain

- Christian Scheuer @chrscheuer2019-12-03 01:31:07.105Z
Hi Romain @Le_Bras_Romain
This script seems to do it for me - not very well tested but seems to work here :)
var selectedClipRows = sf.ui.proTools.mainWindow.clipListView.getElements('AXSelectedRows'); selectedClipRows[0].children.allItems[1].children.first.popupMenuSelect({ isRightClick: true, menuPath: ['Reveal in Finder'], });
Christian Scheuer @chrscheuer2019-12-03 01:35:08.033Z
However I think if the clip list has been scrolled in, this will fail due to a bug in Pro Tools unfortunately :/ Which PT version are you on?
- LIn reply toLe_Bras_Romain⬆:Le Bras Romain @Le_Bras_Romain
Hi, Christian
Thank you for your answer. I'm on PT HD 2019.10.0Christian Scheuer @chrscheuer2019-12-03 01:40:03.749Z
Gotcha. Due to the PT bug I mentioned I'm not sure if this can be made to work without issues unfortunately.
- LLe Bras Romain @Le_Bras_Romain
It doesn't work here but i'm a newbie so maybe there is something I do wrong. Thanks anyway !
- LIn reply toLe_Bras_Romain⬆:Le Bras Romain @Le_Bras_Romain
Hello Christian,
I've just figured out a way to do it.
You have to clean the Find of the Clip List ( cmd+shift+D) then select a clip and apply the sript :sf.ui.proTools.appActivate(); // Open Rename, copy Filename and close Rename sf.ui.proTools.menuClick({ menuPath: ["Clip","Rename..."], }); sf.ui.proTools.menuClick({ menuPath: ["Edit","Copy"], }); sf.ui.proTools.focusedWindow.buttons.whoseTitle.is('OK').first.mouseClickElement(); // Wait sf.wait({ intervalMs: 500, }); // Open Find from Clips List, Paste Filename and close Find sf.keyboard.press({ keys: "cmd+shift+f", }); sf.ui.proTools.windows.whoseTitle.is('Find Clips').first.elementWaitFor(); sf.ui.proTools.menuClick({ menuPath: ["Edit","Paste"], }); sf.ui.proTools.windows.whoseTitle.is('Find Clips').first.buttons.whoseTitle.is('OK').first.mouseClickElement(); // Go to the beginning of the clip, select it to make it appear in Clips View sf.keyboard.press({ keys: "l", }); sf.keyboard.press({ keys: "ctrl+shift+tab", }); sf.wait({ intervalMs: 1000, }); // Reveal in Finder var selectedClipRows = sf.ui.proTools.mainWindow.clipListView.getElements('AXSelectedRows'); selectedClipRows[0].children.allItems[1].children.first.popupMenuSelect({ isRightClick: true, menuPath: ['Reveal in Finder'], });
Christian Scheuer @chrscheuer2019-12-04 11:05:13.949Z
WOW!!! Ok that's very impressive :) I'm happy you got this working for you.
What's the larger workflow in which you need this?- LLe Bras Romain @Le_Bras_Romain
Hello Christian,
Thanks again for your help.
About the worflow :
I have a PT session in which a large part of the clips have been treated in Izotope RX via “ Batch Processing “.
All those clips are located in a different folder than the Audio Files Folder of the PT session.
The guy who did the “ Batch Processing " choosed to keep the original name of the clips when he saved the “Batch Processing“ in Izotope RX.
As a result the names of the original clips and the treated clips are the same, but there are in 2 different folders.
So, when I'am editing, if I have a doubt about the state of a clip ( was he treated or not ) I hit “ Reveal In Finder “and I can see in which folder is the clip, if he has been treated or not.The goal of this script was also to practice and learn more about macros, scripts ans Sound Flow.
Below, for those who are interested, you will find a new version of the scripts that allows to select a clip whith Fades.
In PT, cmd+shift+D, then select a clip and run the script :
sf.ui.proTools.appActivate(); // Open Rename, copy Filename and close Rename sf.ui.proTools.menuClick({ menuPath: ["Clip", "Rename..."], }); sf.ui.proTools.menuClick({ menuPath: ["Edit", "Copy"], }); sf.ui.proTools.focusedWindow.buttons.whoseTitle.is('OK').first.mouseClickElement(); // Wait sf.wait({ intervalMs: 250, }); // Open Find from Clips List, Paste Filename and close Find sf.keyboard.press({ keys: "cmd+shift+f", }); sf.ui.proTools.windows.whoseTitle.is('Find Clips').first.elementWaitFor(); sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"], }); sf.wait({ intervalMs: 250, }); sf.ui.proTools.windows.whoseTitle.is('Find Clips').first.buttons.whoseTitle.is('OK').first.mouseClickElement(); sf.wait({ intervalMs: 100, }); // Go to the beginning of the clip, select it to make it appear in Clips View sf.keyboard.press({ keys: "semicolon", }); sf.wait({ intervalMs: 100, }); sf.keyboard.press({ keys: "p", }); sf.wait({ intervalMs: 250, }); // Reveal in Finder var selectedClipRows = sf.ui.proTools.mainWindow.clipListView.getElements('AXSelectedRows'); selectedClipRows[0].children.allItems[1].children.first.popupMenuSelect({ isRightClick: true, menuPath: ['Reveal in Finder'], });
Christian Scheuer @chrscheuer2019-12-04 17:44:07.140Z
Very cool :) Thank you for the background.
By the way, if you want to encode your scripts in here to be more readable, you can add a line with three backticks (
```
) before and after your script :) I've edited your post, so you can see how it works - you can see it if you edit it yourself.- LLe Bras Romain @Le_Bras_Romain
Christian, thanks a million for the (```) I had no idea of how to do that ! :)
- In reply toLe_Bras_Romain⬆:JJonathan Grossman @Jonathan_Grossman
Btw - I added the COMMAND SHIFT D key command, and the REVEAL CLIPS function to this script so now you can just select the clip and hit the macro.
sf.ui.proTools.appActivate();
sf.keyboard.press({
keys: "cmd+shift+d",
});sf.ui.proTools.mainWindow.buttons.whoseTitle.is('Show/Hide Clip List').first.elementClick();
// Open Rename, copy Filename and close Rename
sf.ui.proTools.menuClick({
menuPath: ["Clip", "Rename..."],
});sf.ui.proTools.menuClick({
menuPath: ["Edit", "Copy"],
});sf.ui.proTools.focusedWindow.buttons.whoseTitle.is('OK').first.mouseClickElement();
// Wait
sf.wait({
intervalMs: 250,
});// Open Find from Clips List, Paste Filename and close Find
sf.keyboard.press({
keys: "cmd+shift+f",
});sf.ui.proTools.windows.whoseTitle.is('Find Clips').first.elementWaitFor();
sf.ui.proTools.menuClick({
menuPath: ["Edit", "Paste"],
});
sf.wait({
intervalMs: 250,
});sf.ui.proTools.windows.whoseTitle.is('Find Clips').first.buttons.whoseTitle.is('OK').first.mouseClickElement();
sf.wait({
intervalMs: 100,
});// Go to the beginning of the clip, select it to make it appear in Clips View
sf.keyboard.press({
keys: "semicolon",
});sf.wait({
intervalMs: 100,
});sf.keyboard.press({
keys: "p",
});sf.wait({
intervalMs: 250,
});// Reveal in Finder
var selectedClipRows = sf.ui.proTools.mainWindow.clipListView.getElements('AXSelectedRows');
selectedClipRows[0].children.allItems[1].children.first.popupMenuSelect({
isRightClick: true,
menuPath: ['Reveal in Finder'],
});- LLe Bras Romain @Le_Bras_Romain
Thanks !
- In reply toLe_Bras_Romain⬆:JJeremy Bowker @Jeremy_Bowker
For some reason Reveal in Finder seems to be working with some files and not others.... and I have yet to figure out why that is. Please let me know if you have any brilliant ideas.
Christian Scheuer @chrscheuer2021-01-10 14:17:25.575Z
Hi Jeremy (@Jeremy_Bowker)
The above script is one of these "great if it works, but hard to figure out when it doesn't". It's doing a couple of things that aren't best practices in SoundFlow (ie. simulating keystrokes, using manual wait times etc) - and, perhaps more importantly, it uses some assumptions that may not always be true - ie., that by searching for the clip's name and then selecting the clip, it will always end up at the top of the clip list.
So, in other words, the approach here is by design not stable. It's pretty cool that it works most of the time for the users who added the code - but most likely, when it's failing for you, it's either due to the manual wait times (which we always advise against using), or the assumptions around clip search.
- JJonathan Grossman @Jonathan_Grossman
in contrast to the REVEAL BOUNCED FOLDERS script I use, this one is very cumbersome. Seems like there should be a way to grab the name of the selected file, similar to double clicking it, then go to the audio files folder of the current session, and then search for that copied file name in that folder.
- JJeremy Bowker @Jeremy_Bowker
Thanks for the feedback! I just realized something unique about when it works and when it doesn't (at least within PT 2020.12.0)....
It appears that, no matter how the clip list is sorted, the top half of the list* will work with the script & the bottom half will not.
*As a side note: I've hidden auto created clips.
Christian Scheuer @chrscheuer2021-01-10 14:48:42.426Z
I've hidden auto created clips.
Ah yea, this would break the script's approach. (Although I can understand why you'd be doing it for performance reasons).
And yes, like Jonathan says, the script (workflow) is quite cumbersome - but still impressive that it does work sometimes, IMO.
One other approach could be to grab the clip name in the rename clip dialog, and then just use the filename from that to search through the Audio Files folder for a matching filename.
That approach would only work of course, if you're not linking to files in other folders.
But it could potentially be made as a template script where you could easily specify additional search paths.Christian Scheuer @chrscheuer2021-01-10 15:01:34.821Z
Here's a script that will do exactly that :) Works quite well here.
If it finds multiple matching filenames in the search path(s), it will ask the user which one to locate in Finder :)
function getClipFilename() { sf.ui.proTools.appActivateMainWindow(); //Clear search, to ensure Clip Rename will work sf.keyboard.press({ keys: "cmd+shift+d", }); // Open Rename, copy Filename and close Rename sf.ui.proTools.menuClick({ menuPath: ["Clip", "Rename..."], }); var nameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first; nameWin.elementWaitFor({}, `Clip Rename didn't work`); let nameElement = nameWin.groups.whoseTitle.is('Clip Info').first.children.whoseRole.is("AXStaticText").allItems[2]; let name = nameElement.value.value; nameWin.buttons.whoseTitle.is('OK').first.mouseClickElement(); nameWin.elementWaitFor({ waitForNoElement: true }); return name; } function locateFile({ filename, searchPaths }) { var ext = filename.split('.').slice(-1)[0].toLowerCase(); var filenameLowerCase = filename.toLowerCase(); var candidates = []; for (let searchPath of searchPaths) { for (let candidatePath of sf.file.directoryGetFiles({ path: searchPath, searchPattern: `*.${ext}`, isRecursive: true }).paths.filter(p => p.split('/').slice(-1)[0].toLowerCase() === filenameLowerCase)) { candidates.push(candidatePath); } } return candidates; } function main() { let sessionFolder = sf.ui.proTools.mainWindow.sessionPath.split('/').slice(0, -1).join('/'); let audioFilesFolder = `${sessionFolder}/Audio Files`; let clipFilename = getClipFilename(); let candidates = locateFile({ filename: clipFilename, searchPaths: [ audioFilesFolder, //Specify additional search paths here, like this: // '/Volumes/Intern_SSD1/Projects/202008_YOUNG', ], }); if (candidates.length === 0) log('No files found'); else if (candidates.length === 1) { sf.system.exec({ commandLine: `open -R "${candidates[0]}"` }); } else { log('Multiple files found.'); let selectedPath = sf.interaction.popupSearch({ items: candidates.map(c => ({ name: c, })) }).item.name; sf.system.exec({ commandLine: `open -R "${selectedPath}"` }); } } main();
Christian Scheuer @chrscheuer2021-01-10 15:07:40.638Z
Adding this as a template now to the "Pro Tools Utilities" package - called "Reveal Selected Clip in Finder":
It'll search the Audio Files folder of the current session, plus any search path you specify in the template:
Christian Scheuer @chrscheuer2021-01-10 15:08:51.660Z
This way, you can easily add a preset for each project you're working on, having different search paths depending on the current project.
- LIn reply toLe_Bras_Romain⬆:Le Bras Romain @Le_Bras_Romain
I forgot to mention that it doesn't work if the Clip has fades. :)
- JIn reply toLe_Bras_Romain⬆:Jonathan Grossman @Jonathan_Grossman
Thanks Christian! trying to implement but getting an error. here's the log
[user:ck99zpoez000h6e10rjx8vg5g:ckjr9uiem000sn0101yy1ehx7] 10.01.2021 07:18:13.89 <info> [Backend]: #App: Activate "com.avid.ProTools" -> PT Deck [ck99zpsq5000j6e10f9hx9wg8] 10.01.2021 07:18:13.89 <info> [Backend]: Showing Deck " PT Deck " on Device "NSA TOWER STREAMDECK" (We were called with device "NSA TOWER STREAMDECK") [StreamDeck] Device 'NSA TOWER STREAMDECK' instantiating deck ' PT Deck ' 10.01.2021 07:18:15.51 <info> [Backend]: #StreamDeck: KeyDown (4,3) -> TEST 10.01.2021 07:18:15.52 <info> [Backend]: >> Command: TEST [user:ck99zpoez000h6e10rjx8vg5g:ckjr9uiem000sn0101yy1ehx7] JavaScript error with InnerException: null !! Command Error: TEST [user:ck99zpoez000h6e10rjx8vg5g:ckjr9uiem000sn0101yy1ehx7]: TypeError: Cannot convert undefined or null to object (TEST line 1) << Command: TEST [user:ck99zpoez000h6e10rjx8vg5g:ckjr9uiem000sn0101yy1ehx7]
Christian Scheuer @chrscheuer2021-01-10 15:36:04.114Z
Hi Jonathan. Not sure what exactly you're running here?
Can you quite the contents of your test script?Note, that I'd recommend using the template I put up instead.
Christian Scheuer @chrscheuer2021-01-10 15:42:34.962Z
Note you can't just copy/paste the contents of a template script into a normal script (it could look like that's what you're doing, but I have no chance of knowing without seeing the contents of the script you're running here)
- JJonathan Grossman @Jonathan_Grossman
yes that's what I did. So instead I am now just running your script and still getting an error
10.01.2021 07:52:02.60 <info> [Backend]: [StreamDeck] Device 'NSA TOWER STREAMDECK' instantiating deck ' PT Deck ' 10.01.2021 07:52:26.88 <info> [Backend]: >> Command: Default Preset [user:cka8kuvp3000xsu10onnuy4c7:ck3p6srh30000pt10jeenso16#ckjr9qsrw000135108iunqan3] 10.01.2021 07:52:27.01 <info> [Backend]: #App: Activate "com.avid.ProTools" -> PT Deck [ck99zpsq5000j6e10f9hx9wg8] 10.01.2021 07:52:27.15 <info> [Backend]: Clicking with mouse here: 70, 28 10.01.2021 07:52:27.74 <info> [Backend]: Clicking with mouse here: 1348, 449 10.01.2021 07:52:28.06 <info> [Backend]: [LOG] No files found in search path(s) 10.01.2021 07:52:28.06 <info> [Backend]: << Command: Default Preset [user:cka8kuvp3000xsu10onnuy4c7:ck3p6srh30000pt10jeenso16#ckjr9qsrw000135108iunqan3] Showing Deck " PT Deck " on Device "NSA TOWER STREAMDECK" (We were called with device "NSA TOWER STREAMDECK") [StreamDeck] Device 'NSA TOWER STREAMDECK' instantiating deck ' PT Deck '
Christian Scheuer @chrscheuer2021-01-10 16:27:10.287Z
If you're just running my script and you get the "No files found in search path(s)" then that indicates it couldn't find a file with that name in the Audio Files directory.
Make sure that the file in fact is in the Audio Files directory - otherwise you need to create a Preset for the template where you specify additional search paths.
Christian Scheuer @chrscheuer2021-01-10 16:28:36.633Z
The point of this script is that since it can only get the filename (not the full path) of the file from Pro Tools, then it needs to be told where to look physically on the drive.
If your file is in the Audio Files folder and it still doesn't work then there's a chance a part of the script isn't working. If that's the case, please share a screenshot of the Clip Rename dialog as it looks for the clip you're testing.
- JJonathan Grossman @Jonathan_Grossman
see attached - file is def in the audio files folder. I even consolidated to make sure it would resave the file there.
Christian Scheuer @chrscheuer2021-01-10 18:47:40.570Z
Ah, this likely happens because these are stereo files in non-interleaved mode (so, separate mono files that end in .L and .R).
What does the Clip Rename dialog look like for this file?Christian Scheuer @chrscheuer2021-01-10 18:48:26.336Z
The script is likely searching for a file named "GTR s1.01_02.wav" which doesn't exist - rather, "GTR s1.01_02.L.wav" and "GTR s1.01_02.R.wav" exist.
- JJonathan Grossman @Jonathan_Grossman
That's def the issue. I almost always work in non-interleaved. How can we add something to the script to account for this?
Christian Scheuer @chrscheuer2021-01-10 19:32:52.143Z
Can you show the clip rename dialog for this clip?
When I look here it actually comes up with the ".L" suffix, so we'll have to check this first.
Christian Scheuer @chrscheuer2021-01-10 19:34:26.258Z
I've also made an update in Pro Tools Utilities 1.0.26 that may solve the issue, but until we can see what your clip rename dialog looks like, I can't be sure if it's the right fix.
- JJonathan Grossman @Jonathan_Grossman
I'll check it you! Thank you! Here's the requested screenshot.
Christian Scheuer @chrscheuer2021-01-10 19:41:52.594Z
Ah! The issue is that Clip Info is collapsed :)
Please expand that manually (the script won't try to do that right now)- JJonathan Grossman @Jonathan_Grossman
that fixed it! thanks
Christian Scheuer @chrscheuer2021-01-10 19:57:50.832Z
Awesome, thanks for the feedback!
@Jeremy_Bowker it should now work.
I've updated the script in v1.0.27 of the Pro Tools Utilities package so it should now work more reliably, by ensuring the Clip Info part of the Clip Rename dialog gets expanded as needed.
- In reply tochrscheuer⬆:JJonathan Grossman @Jonathan_Grossman
I'm just using your default template bc I want it to search just the current PT session, nowhere else.
const { searchPaths } = event.props; function getClipFilename() { sf.ui.proTools.appActivateMainWindow(); //Clear search, to ensure Clip Rename will work sf.keyboard.press({ keys: "cmd+shift+d", }); // Open Rename, copy Filename and close Rename sf.ui.proTools.menuClick({ menuPath: ["Clip", "Rename..."], }); var nameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first; nameWin.elementWaitFor({}, `Clip Rename didn't work`); let nameElement = nameWin.groups.whoseTitle.is('Clip Info').first.children.whoseRole.is("AXStaticText").allItems[2]; let name = nameElement.value.value; nameWin.buttons.whoseTitle.is('OK').first.mouseClickElement(); nameWin.elementWaitFor({ waitForNoElement: true }); return name; } function locateFile({ filename, searchPaths }) { var ext = filename.split('.').slice(-1)[0].toLowerCase(); var filenameLowerCase = filename.toLowerCase(); var candidates = []; for (let searchPath of searchPaths) { for (let candidatePath of sf.file.directoryGetFiles({ path: searchPath, searchPattern: `*.${ext}`, isRecursive: true }).paths.filter(p => p.split('/').slice(-1)[0].toLowerCase() === filenameLowerCase)) { candidates.push(candidatePath); } } return candidates; } function main() { let sessionFolder = sf.ui.proTools.mainWindow.sessionPath.split('/').slice(0, -1).join('/'); let audioFilesFolder = `${sessionFolder}/Audio Files`; let clipFilename = getClipFilename(); let candidates = locateFile({ filename: clipFilename, searchPaths: [ audioFilesFolder, ...(searchPaths || []), ], }); if (candidates.length === 0) log('No files found in search path(s)'); else if (candidates.length === 1) { sf.system.exec({ commandLine: `open -R "${candidates[0]}"` }); } else { log('Multiple files found.'); let selectedPath = sf.interaction.popupSearch({ items: candidates.map(c => ({ name: c, })) }).item.name; sf.system.exec({ commandLine: `open -R "${selectedPath}"` }); } } main();
- JIn reply toLe_Bras_Romain⬆:Jeremy Bowker @Jeremy_Bowker
Running into an error here too
- RIn reply toLe_Bras_Romain⬆:randy matuszewski @randy_matuszewski
@chrscheuer can i revive this old thread? i was just searching for this exact function. the current utility in soundflow gives an error message. would you mind taking a look at the newest PT and see if there's a way to make this work?
thanks!!!
Christian Scheuer @chrscheuer2024-03-09 00:49:04.904Z
Hi Randy,
The best way to get help with a script (even if it's part of an older thread) is to use the Script Help workflow. Once you've created the thread, you can link to this thread to help give context.
By using the Script Help workflow, you're giving more information to allow people to help you (me or the community), in that we'd have access to the script you're attempting to use, logs and most importantly, what you hope for the script to do and the exact error messages.Christian Scheuer @chrscheuer2024-03-09 00:49:43.759Z
Please note that the Pro Tools Utilities package is now deprecated in favor of the official Pro Tools package from SoundFlow. Any scripts that we deemed we would be able to support are in the Pro Tools package.