Hi! I'm refining a complicated script that works on a number of selected tracks via a clipDoForEachSelectedClip
of the top track of the selection. I want to add a condition to the action function to return early if there is only one clip in the selection... is this possible?
Thanks in advance! :)
- Chris Shaw @Chris_Shaw2020-12-09 23:38:10.282Z
I'm not sure how to count clips in a selection but this will count clips on a track (if you delete the line with the comment). As is, the script will stop counting if there is more than one clip.
Hope this can get you started…sf.ui.proTools.transportEnsureCluster(); function location() { return sf.ui.proTools.getCurrentTimecode().stringValue } sf.ui.proTools.mainWindow.groups.whoseTitle.is('Transport View Cluster').first.groups.whoseTitle. is('Normal Transport Buttons').first.buttons.whoseTitle.is('Return to Zero').first.elementClick(); var lastLocation sf.keyboard.press({ keys: "ctrl+tab", }); var clipCount = 0 while (true) { sf.keyboard.press({ keys: "ctrl+tab", }); if (lastLocation == location()) break if (sf.ui.proTools.selectionGetInfo().hasFullClip) { clipCount = clipCount + 1 lastLocation = location() if (clipCount > 1) {log ("More Than One Full Clip Exists","");break;} //Delete this to count all clips in track } } log("ClipCount = " + clipCount)
Dustin Harris @Dustin_Harris
Thanks Chris, but I’m counting vertically in my case. I have a clunky/slow work around, but it does a lot of work to accomplish it that needs to be undone. Am hoping there’s a cool selection property I’m unaware of. Maybe the number of selections in the clip list?
Chris Shaw @Chris_Shaw2020-12-09 23:50:31.274Z
That was my first thought (# of clips selected in clip list) but I don't know how to get that value.
Dustin Harris @Dustin_Harris
Hahaha me neither :)
- In reply toDustin_Harris⬆:
Raphael Sepulveda @raphaelsepulveda2020-12-10 01:16:01.702Z
Hey @Dustin_Harris ! This bit tells you how many clips are selected in the Clip List.
let selectedClips = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first.children.whoseRole.is("AXRow").allItems.map(row => row.children[1].children.first.value.value).filter(c => c.startsWith('Selected. ')); log(selectedClips.length);
The thing is that the clip has to be fully selected in order for Pro Tools to consider it as selected.
Hopefully this gets you closer to what you want to do!
Dustin Harris @Dustin_Harris
Raphael this is superb and works perfectly for what I need! Thank you so much!
- In reply toraphaelsepulveda⬆:JJack Byrne @Jack_Byrne
Hey Raphael,
Old thread, this seems to have stopped working. Fairly certain it's something with the latest version of PT, only thing that's changed. I'll check it in an old version when I can to see if it's just this session misbehaving as well, but I figured you might want a heads up. I'm on SF 5.8.3 if that affects things, not sure if that's the latest.
Chris Shaw @Chris_Shaw2024-11-06 23:37:32.424Z
The clip list has been overhauled so this should do it.
let selectedClips = sf.ui.proTools.mainWindow.clipListView.children.whoseRole.is("AXRow").allItems.map(row => row.children[1].children.first.value.value).filter(c => c.startsWith('Selected. ')); log(selectedClips.length);
Chris Shaw @Chris_Shaw2024-11-06 23:38:56.447Z
Essentially, instead of addressng the clip list with:
sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first
You can now use this:
sf.ui.proTools.mainWindow.clipListView
- In reply toChris_Shaw⬆:JJack Byrne @Jack_Byrne
Does this break compatibility with older versions? I tend to run a couple of PT versions at once, couple of edit workflows from older versions that I've not updated mainly
Chris Shaw @Chris_Shaw2024-11-22 16:11:27.122Z
This should work with all versions.
// Get PT version const ptVersion = sf.ui.proTools.appVersion.split('.') .map(Number) .slice(0, 2) .reduce((p, c, i) => p + Math.pow(100, 2 - i) * c, 0); // Get clip list element (depending on PT version) const clipList = ptVersion >= 241000 ? sf.ui.proTools.mainWindow.clipListView : sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first // get selected clips in clip list let selectedClips = clipList.children.whoseRole.is("AXRow").allItems.map(row => row.children[1].children.first.value.value).filter(c => c.startsWith('Selected. ')); log (selectedClips.length)
I'm assuming that the clip list element changed with PT 2024.10. If it changed with an earlier version just change the number in line 8. If, for example, it changed with PT2024.6 then the number on line 8 should be
240600
Chris Shaw @Chris_Shaw2024-11-22 16:23:46.184Z
I've realized that the script could give an incorrect count if any selected stereo clip in the clip list is expanded to show the individual channels:
In this example there are two stereo clips on the selected track but with the stereo clip expanded the script will return a count 5. So be sure that no stereo clips are expanded before running this script. (unless @raphaelsepulveda has a clever way of ensuring that no stereo clips are expanded in the clip list :) )
Raphael Sepulveda @raphaelsepulveda2024-11-22 21:07:49.539Z
@Chris_Shaw, @Jack_Byrne I recently wrote this script that fetches clip info using the SDK: Get selected Clip Name #post-5
Give it a shot. It doesn't rely on the Clip List panel, deals with multichannel clips, and should work with any version of PT 2023 and onwards.
Just change the last line to this to get the number of selected clips:
log(selectedClipNames.length);
- JJack Byrne @Jack_Byrne
Thanks! My use case is typically just mono files (drum sample workflow) but it'll be handy to have a version that's a little more bomb proof
- In reply toJack_Byrne⬆:
Dustin Harris @Dustin_Harris
Hi Jack,
I’m on mobile so my syntax might be a little off, there is also an SDK derived function that is quick:sf.app.proTools.getSelectedClipInfo().clips.length
- BIn reply toDustin_Harris⬆:Ben Rauscher @Ben_Rauscher
This is great @Chris_Shaw, thank you. I've been using this too:
clipListView.getElements("AXSelectedRows");
Can either of these methods be used in a forEach to click through every selected clip in the Clip List window? I am trying to get this clip-color script working to increase speed without needing to continuously select "Clips in Tracks" from the color palette window. Currently, using an elementClick() will select or de-select all the rows together, not individually:
function Color_Clips_By_Channel_Name() { let clipListView = sf.ui.proTools.mainWindow.clipListView; //let selectedClipRowsOLD = clipListView.getElements("AXSelectedRows"); let selectedClipRows = clipListView.children.whoseRole.is("AXRow").allItems .map(row => row.children[1].children.first.value.value) .filter(clip => clip.startsWith('Selected. ')); log (selectedClipRows); selectedClipRows.forEach(row => { // Click the row in the clip list to select the clip in the timeline, or de-select at the end... //row.elementClick(); // Get metadata let clipDetailsElement = row.children.allItems[1].children.first; if (!clipDetailsElement || !clipDetailsElement.title.value) { log(`Warning: Skipping clip due to missing or invalid details.`); return; } let clipDetails = clipDetailsElement.title.value; let line2 = clipDetails.split("\n")[1]; if (!line2) { log(`Warning: Skipping clip with invalid format: ${clipDetails}`); return; } let psplit = line2.split("("); if (psplit.length < 2) { throw new Error("Invalid clip format: Missing parenthesis content."); } //let clipName = line2.split("(")[0].trim().replace(/"/g, ""); let parenthesisContent = psplit[1].split(")")[0]; let detailsMatch = parenthesisContent.match(/S:\s*(\S+),\s*T:\s*(\S+),\s*(\S+)/); //let sceneNumber = detailsMatch ? detailsMatch[1] : "Unknown"; //let takeNumber = detailsMatch ? detailsMatch[2] : "Unknown"; let channelName = detailsMatch ? detailsMatch[3] : "Unknown"; // Color the clip without re-selecting "Clips in Tracks" let selectedColor = colorIso; // Default if (channelName.toLowerCase().includes("mix")) { selectedColor = colorMix; } else if (channelName.toLowerCase().includes("boom")) { selectedColor = colorBoom; } else if (channelName.toLowerCase().includes("plant")) { selectedColor = colorPlant; } sf.waitFor({ callback: () => sf.ui.proTools.colorPaletteWindow.tables.whoseTitle.is("Color Palette View").first .children.whoseRole.is("AXRow").allItems[selectedColor.row] .children.whoseRole.is("AXCell").allItems[selectedColor.cell].buttons.first .elementClick() }); // ...Command-click to de-select the processed clip and proceed to the next row }); }