A simple way to copy a playlist name
Hi! Slowly expanding my SF workflow and could use an assist. I do a lot of versioning of huge numbers of TV spots with multiple unique phone numbers. I've automated parts of this process, but could use a simple way to copy a playlist name without having to double click on a selected playlist, copy, and hit return. This seems like a good place to start, but would need to substitute "Comment" with the playlist name:
function setComment(trackHeader, text) {
var commentsField = trackHeader.textFields.whoseTitle.startsWith('Comments').first;
commentsField.mouseClickElement();
sf.keyboard.press({ keys: 'cmd+c' });
sf.keyboard.press({ keys: 'return' });
Any advice? Thanks in advance!
Linked from:
- samuel henriques @samuel_henriques
Hello Peter,
When you say "copy a playlist name" is this the same as the track name? When you change the playlist on the track, the track name changes as well.
this will get you the selected track name.
Let me know if this is it.
const selectedTracKName = sf.ui.proTools.selectedTrackNames[0] log(selectedTracKName)
- PPeter Rydberg @Peter_Rydberg
Here's a more clear way of explaining it: I have a single track with up to 400 different playlists, all being viewed at once. Each playlist is labeled with a unique phone number. I need to copy and paste each unique number into a new bounce to disk window. I currently have the task broken up into three steps. One script selects the next unique playlist and solos that playlist. I then manually double click the playlist name. The next script copies that playlist name, hits "OK" the UI window, then cycles through bouncing to disk dialogue, enters the new playlist name, and renders the file.
I'm largely doing this through key commands and not through UI automation, but I'm slogging my way through learning more and better ways to do things....
samuel henriques @samuel_henriques
Hello Peter,
I managed this, it will solo each playlist, and get its name.
Now we need to add the bounce part.As it is now, it will do it for all Comp tracks (playlist tracks) in the session, so, keep open only the one you want to bounce.
If you run it just the way it is, you should see it select each playlist at a time, and log its name.
Send me the bounce part you have if you get stuck.
function bounceToDisk(bounceName) { log(bounceName) // here goes your bounce script, and must include a wait for bounce to finish } const compTracks = sf.ui.proTools.visibleTrackHeaders.filter(track => track.title.value.endsWith("- Comp Track ")) const playlistTracks = compTracks.map(track => ({ playlistName: track.normalizedTrackName, soloBtn: track.children.filter(x => x.title.value === "Solo Comp Lane")[0] })) playlistTracks.forEach(playlist => { // Press solo playlist.soloBtn.elementClick() // Bouce bounceToDisk(playlist.playlistName) })
samuel henriques @samuel_henriques
Hey Peter, I'm working on a version that will do it for all playlist in the selected track. You would only need to select the track you have the playlists to bounce and the script will do the rest.
Could you confirm if the playlists you commonly need, are the ones in red? And do you bounce the first in menu, meaning the selected playlist?
samuel henriques @samuel_henriques
The reason i'm thinking about this method is so the script would know the names of the playlists to solo, instead of the way the first script works, where it's searching the complete list of tracks in the session for playlist tracks.
Another way could be inputing the list of phone numbers to the script and then ask the script to find the playlist tracks and bounce them. This would be advantageous in the event there is a mistake with naming or missing the playlists. We could then report a specific number wasn't found or is missing, for example.
Let me know if ay of this makes sense.
- In reply tosamuel_henriques⬆:PPeter Rydberg @Peter_Rydberg
Amazing! The best way to make this work wouldn't be to bounce every playlist at once in each track. I usually have multiple spots spread across the timeline and need to specify a range to bounce and since the number of successive bounces always changes, the function can't work as "bounce all of these playlists." Hopefully that makes sense. Here's the workflow in more detail:
First, I'd select a range to bounce. Then:
- Select and solo playlist
- Copy name of playlist
- Call up Bounce To Disk UI
- Copy name of playlist to File Name
- Activate bounce function
I'd repeat this for manually for each successive playlist. Ultimately, this script would be a generic "one-shot" button press.
Here's how I've got these 3 parts scripted at the moment:
- Select next playlist and solo
sf.keyboard.press({ keys: "semicolon", }); sf.keyboard.press({ keys: "shift+s", });
- Then I manually double click the playlist name.
- Copy/paste name and bounce to disk:
const selectedTracKName = sf.ui.proTools.selectedTrackNames[0] log(selectedTracKName) sf.keyboard.press({ keys: "cmd+c", }); sf.ui.proTools.focusedWindow.buttons.whoseTitle.is("OK").first.elementClick(); sf.keyboard.press({ keys: "cmd+alt+b", }); sf.keyboard.press({ keys: "tab", }); sf.keyboard.press({ keys: "cmd+v", }); sf.keyboard.press({ keys: "return", });
Hope this makes things clearer. The assistance you're providing is invaluable - thanks so much.
P.
samuel henriques @samuel_henriques
okok. so this should do what you described, apart from the select next and solo at the start of the script.
It's making more sense, for me, doing that in the end, but it's an easy change, just let me know.So you make a selection, and solo the one you want and run the script.
Let me know how it goes.
function bounceMix(name) { sf.ui.proTools.menuClick({ menuPath: ["File", "Bounce Mix..."] }) const bounceMixWin = sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.elementWaitFor({}, "Cound not open Bounce Mix window.").element bounceMixWin.textFields.first.elementSetTextFieldWithAreaValue({ value: name }); bounceMixWin.buttons.whoseTitle.is("Bounce").first.elementClick(); bounceMixWin.elementWaitFor({ waitType: "Disappear" }, "Bounce Mix Window did not close.") //Wait for bounce to finish sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: 'Disappear', timeout: -1 }); //-1 is endless timeout (cancel by Ctrl+Shift+Esc) } sf.ui.proTools.appActivateMainWindow() sf.ui.proTools.invalidate() const soloed = sf.ui.proTools.visibleTrackHeaders.filter(track => track.title.value.endsWith("- Comp Track ") && track.children.filter(x => x.title.value === "Solo Comp Lane" && x.value.invalidate().value === "on state")[0] )[0]; if (soloed) { bounceMix(soloed.normalizedTrackName) // Select Next sf.keyboard.press({ keys: "semicolon" }); // Solo track sf.keyboard.press({ keys: "shift+s" }); } else { alert("Please solo a playlist track.") };
samuel henriques @samuel_henriques
Make sure to check out this video to learn how to quote code in the forum:
How to quote code in the SoundFlow forum.samuel henriques @samuel_henriques
UPDATED, there was a mistake on the first one and simplified the code.
- PIn reply toPeter_Rydberg⬆:Peter Rydberg @Peter_Rydberg
Hmm, doesn't seem to do it. I copied and pasted that script to a new button on my deck, selected a range, solo'd the playlist I was targeting, and got this Soundflow message in Pro Tools:
"Please solo a playlist track."
Thoughts?
samuel henriques @samuel_henriques
That warning was meant to show if there is no playlist soloed.
Could you send me a screen pic of the track with the visible playlists and the soloed one?
I might have missed something.- PPeter Rydberg @Peter_Rydberg
samuel henriques @samuel_henriques
Could you quit and open soundFlow and try again please?
- PPeter Rydberg @Peter_Rydberg
Nope, same result.
samuel henriques @samuel_henriques
keeping the playlist soloed, can you run this code and send me the result?
sf.ui.proTools.appActivateMainWindow() sf.ui.proTools.invalidate() const soloed = sf.ui.proTools.visibleTrackHeaders.filter(track => track.title.value.endsWith("- Comp Track ") && track.children.filter(x => x.title.value === "Solo Comp Lane" && x.value.invalidate().value === "on state")[0] )[0]; alert(JSON.stringify(soloed))
samuel henriques @samuel_henriques
Hey @Kitch, hope you are doing well.
could you run this to see if it works for you?
create a few playlists on a track, solo one, and run the script.
Thank you so much.
Kitch Membery @Kitch2021-11-09 23:03:22.186Z
Hi mate!
Am working on something right now, however, I should be done in the next hour so I'll check it out asap.
Rock on!
- In reply tosamuel_henriques⬆:
Kitch Membery @Kitch2021-11-10 01:41:55.776Z
Sorry for the delay... It seems to be working here @samuel_henriques.
Maybe if @Peter_Rydberg could do a screen recording that might help to work out what's happening.
Rock on!
- In reply tosamuel_henriques⬆:
Kitch Membery @Kitch2021-11-10 02:16:37.609Z
I thought I'd do a quick refactor to see if I could find any problems, but it was mostly just adjusting variable and function names, formatting, and substituting the keyboard shortcut for moving to the next track. This shouldn't work any differently to your script. (But I thought I'd share the refactor anyway.)
/** * @param {string} name */ function bounceSelection(name) { sf.ui.proTools.menuClick({ menuPath: ["File", "Bounce Mix..."], }); const bounceMixWin = sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first bounceMixWin.elementWaitFor({}, "Cound not open Bounce Mix window.").element; bounceMixWin.textFields.first.elementSetTextFieldWithAreaValue({ value: name, }); bounceMixWin.buttons.whoseTitle.is("Bounce").first.elementClick({}, `Could not click "Bounce."`); bounceMixWin.elementWaitFor({ waitType: "Disappear" }, `The "Bounce Mix Window" did not close.`); //Wait for bounce to finish sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: 'Disappear', timeout: -1 }); //-1 is endless timeout (cancel by Ctrl+Shift+Esc) } function solotNextTrack() { sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Selection', 'Extend Edit Down'] }); sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Selection', 'Remove Edit from Top'] }); sf.keyboard.press({ keys: "shift+s" }); } function main() { sf.ui.proTools.appActivateMainWindow() sf.ui.proTools.invalidate() const soloedPlaylist = sf.ui.proTools.visibleTrackHeaders.filter(track => track.title.value.endsWith("- Comp Track ") && track.children.filter(playlist => playlist.title.value === "Solo Comp Lane" && playlist.value.invalidate().value === "on state")[0] )[0]; if (soloedPlaylist) { let soloedPlaylistName = soloedPlaylist.normalizedTrackName; //Bounce Selection bounceSelection(soloedPlaylistName); //Solo Next Track solotNextTrack(); } else { alert("Please solo a playlist track.") }; } main();
I'll follow this thread to see if anything arises.
Rock on!samuel henriques @samuel_henriques
Cool, thank you Kitch.
And thank you for the refactor, it certainly helps readability.Kitch Membery @Kitch2021-11-10 10:13:33.945Z
You’re welcome, legend! :-)
- PPeter Rydberg @Peter_Rydberg
Hi folks -
Again, really can't express enough gratitude for the assist here. Unfortunately, I'm still getting this SF message when running the script:
"Please solo a playlist track."
I'd be happy to do a screen capture - should I post it into this thread?
Kitch Membery @Kitch2021-11-11 17:59:37.977Z
Yes that would be great :-)
- PPeter Rydberg @Peter_Rydberg
Video posted here:
samuel henriques @samuel_henriques
Thank you Peter,
This is you doing it manually.
This is what the script should do.
Could you show us a video when trying to use the script?samuel henriques @samuel_henriques
Just noticed, as well, we are not on same pro tools versions.
What is the Pro tools version you are using?- PPeter Rydberg @Peter_Rydberg
That's probably the issue. Currently on Ultimate 2019.12 which isn't compatible. I'm installing 2020.12 as we speak and will report back with updates. I'm obviously very slow to institute changes to a stable system... ;)
Kitch Membery @Kitch2021-11-11 22:16:22.479Z
Sounds good Peter. Keep @samuel_henriques and I posted. :-)
Rock on!
- PPeter Rydberg @Peter_Rydberg
Ok, PT Ultimate 2020.12 is now running smoothly. Copied the script, dropped it into SF, added to a button on my Android device running the app, pressed the button, and this video is the result.
Kitch Membery @Kitch2021-11-11 22:37:27.440Z
Hi Peter,
I think you uploaded the video from before where you are doing the steps manually. Can you check that?
- PPeter Rydberg @Peter_Rydberg
Oh boy that's embarrassing - moving way too fast these days....
Kitch Membery @Kitch2021-11-11 22:54:40.318Z
No worries.. I do stuff like that at least five times a day! Haha
Can you try making an audio selection and running the script again?
Also are you in Full Screen mode for Pro Tools?- PPeter Rydberg @Peter_Rydberg
I'm not running Pro Tools in full screen mode. Here's two attempts to run the same script:
samuel henriques @samuel_henriques
hey Peter, I'm sorry this is taking so long. The first time is correct, the script should warn if no track is soloed. But the second try should work. I'm really missing something here, because I can't reproduce the behaviour you are getting.
Soloing one playlist, can you try this and send me a pic of the alert?
sf.ui.proTools.appActivateMainWindow() sf.ui.proTools.invalidate() const soloedPlaylist = sf.ui.proTools.visibleTrackHeaders.filter(track => track.title.value.endsWith("- Comp Track ") && track.children.filter(playlist => playlist.title.value === "Solo Comp Lane" && playlist.value.invalidate().value === "on state")[0] )[0]; alert(JSON.stringify(soloedPlaylist))
Kitch Membery @Kitch2021-11-12 21:14:09.785Z
For what it's worth @samuel_henriques, I get an alert of the track object;
samuel henriques @samuel_henriques
exactly, thats what I get as well. For me, the only way to go to the "Please solo a playlist track." alert is if the
soloedPlaylist
is undefined. If Peter gets the object, there should be something else.Kitch Membery @Kitch2021-11-12 21:31:41.072Z
Just a thought...
Could you check in "Pro Tools" => "Preferences..." => Display Tab => Tool Tips (Function & Details checkboxes are both checked).
samuel henriques @samuel_henriques
ahh good one, that makes if fail for me.
- PPeter Rydberg @Peter_Rydberg
I turned off Tool Tips about a hundred years ago. ;) Definitely not the issue here.
Let me try the previously suggested path. Standby!
Kitch Membery @Kitch2021-11-12 21:42:55.809Z
I'm not sure I was clear in my last message...
If you have Tool tips turned off the script will not work. Both the "Function" & "Details" checkboxes both need to be enabled as in the above screenshot.
Without them enabled the script will not work as expected.
Hope that makes sense.
- PPeter Rydberg @Peter_Rydberg
Eureka! After turning on Tool Tips, this works 100% as advertised:
To say that this is nothing short of monumental to my workflow for these types of projects would be a massive understatement. I kludged my way through this before with some ugly Avid Dock shortcuts, but this is a game changer. You have my unending gratitude. Cheers, gents!
Kitch Membery @Kitch2021-11-12 22:17:06.614Z
samuel henriques @samuel_henriques
Awesome!!! Really happy it's working.
Thank you for the help @Kitch .Kitch Membery @Kitch2021-11-12 22:44:12.152Z
A pleasure as always, legend!
- In reply tosamuel_henriques⬆:
Kitch Membery @Kitch2021-11-12 21:36:41.399Z
Note: It's also a SoundFlow requirement that the Pro Tools language should also be set to English but it looks like Peter has his set to english. :-)
- PPeter Rydberg @Peter_Rydberg
Hi everyone! Before I go any further, congrats on the new SF5 release - it's a game changer!
Sooooooo... this script continues to be unbelievably great, but I'm thinking it could be even greater. Would it be possible to introduce an option to specify bouncing every playlist in a track automatically without having to select and bounce each playlist manually? Let me know what you think. And thanks in advance!