Rename clips by markers in Pro Tools
Hello, I wonder if there is a way to make a script for Pro tools to rename all clips in a track (Beginnig to end of the session) by each marker in front of each clip
I am trying to repeat this several times
I found some script here but I think is incomplete for what I need
Also, I would like to run this for clips that are already cut, avoiding a last strip silence again
function getMemLocName() {
const currentLocation = sf.ui.proTools.selectionGetInSamples()
const memLocName = sf.proTools.memoryLocationsFetch().collection['list'].filter(x =>
x.mainCounterValue >= currentLocation.selectionStart &&
x.mainCounterValue <= currentLocation.selectionEnd
)[0]
return memLocName
}
function renameClip() {
// Get First Memory Location Name from selection
const memLocName = getMemLocName()
if (memLocName != undefined) {
//Open Rename window
sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] });
//Reference for Rename Window
const renameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({ waitType: "Appear" }).element
const nameClipOnlyButton = renameWin.groups.first.radioButtons.first
/// Set Clip Name Only
if (nameClipOnlyButton.exists)
renameWin.groups.first.radioButtons.first.checkboxSet({ targetValue: "Enable" });
// Set the clip name to Track name
renameWin.groups.first.textFields.first.elementSetTextFieldWithAreaValue({ value: memLocName.Name });
// Click OK
renameWin.buttons.whoseTitle.is('OK').first.elementClick()
// Wait for window to cloce
renameWin.elementWaitFor({ waitType: "Disappear" })
}
}
function main() {
// Acivate Pro Tools
sf.ui.proTools.appActivateMainWindow()
// Do For Each
sf.ui.proTools.clipDoForEachSelectedClip({
action: renameClip,
onError: "Continue"
})
}
main()
Linked from:
- samuel henriques @samuel_henriques
Hello Maggy,
I think this was my code, and has a fundamental mistake, maybe it worked when I made it, but I can see now how it could fail.
Here's the fixed code, and made it faster.
Let me know how it goes.
function getMemLoc() { // Functions to grab start and end time on any counter //( because its runnign on clipDoForEachSelectedClip it should be Samples, but will work on any) const getSelectionStart = () => sf.ui.proTools.selectionGet().selectionStart.replace(/[:.+| ]/g, ''); const getSelectionEnd = () => sf.ui.proTools.selectionGet().selectionEnd.replace(/[:.+| ]/g, ''); // filter mem locs within selection const memLocFromSelection = sf.proTools.memoryLocationsFetch().collection['list'].filter(m => m.mainCounterValue.replace(/[:.+| ]/g, '') >= getSelectionStart() && m.mainCounterValue.replace(/[:.+| ]/g, '') <= getSelectionEnd() ); // return first memory location within selection return memLocFromSelection[0] }; function renameClip() { // Get First Memory Location Name from selection const memLocFromSelection = getMemLoc() if (memLocFromSelection) { //Open Rename window sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] }); //Reference for Rename Window const renameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({ waitType: "Appear" }).element const nameClipOnlyButton = renameWin.groups.first.radioButtons.first /// Set Clip Name Only if (nameClipOnlyButton.exists) renameWin.groups.first.radioButtons.first.checkboxSet({ targetValue: "Enable" }); // Set the clip name to Track name renameWin.groups.first.textFields.first.elementSetTextFieldWithAreaValue({ value: memLocFromSelection.name }); // Click OK renameWin.buttons.whoseTitle.is('OK').first.elementClick() // Wait for window to cloce renameWin.elementWaitFor({ waitType: "Disappear" }) } } function main() { // Acivate Pro Tools sf.ui.proTools.appActivateMainWindow() // Do For Each sf.ui.proTools.clipDoForEachSelectedClip({ action: renameClip, onError: "Continue" }) } main()
- MIn reply toMaggy_Ayala⬆:Maggy Ayala @Maggy_Ayala
Hey Samuel, thanks a lot for your help
Looks like a bit faster and it allows me to use it with clips I have already cut
but the names what it start to put are ramdom
ie
clip 1 have a marker with 101 but the script ended naming like 123 (what is another marker in another place)samuel henriques @samuel_henriques
umm...
could you share a screen recording of it running?
samuel henriques @samuel_henriques
Could it be two clips that are actually the the same whole clip? It renames the first, and it changes when the script renames the second clip.
If you can have this situation, we could consolidate the clips before renaming them
- MIn reply toMaggy_Ayala⬆:Maggy Ayala @Maggy_Ayala
Sure
Have a look here https://filebin.net/6scqrnqeeugvtp1h
I did try to consolidate each clip before run the script and the result is exactly the sameOh man, I feel this is super close but .. haha
samuel henriques @samuel_henriques
Got it, the script is looking for a marker within the clip selection, the first memory location after the start of the clip, but before its end. But, if there is no marker it shouldn't change the name.
Could you try to make the markers on the clips, just to see if it works better?
samuel henriques @samuel_henriques
could you confirm the version of PT you are using?
and to work the way you want, where the markers are outside the clips, I need to think of another way.
Could be making a selection including the markers, and if the number of markers is the same as the number of selected clips, it would name each clip on the same order of markers. Does this make sense?samuel henriques @samuel_henriques
I made a new version based on your workflow. It will name the clips based on the memory locations in the selection and in the same order.
for example, the selection you made wouldn't,
In this case, the clip 1 would be named L09, clip 2 L11, clip 3 L13 and clip 4 wouldn't be named.
You must make a selection including the markers and the clips you want to rename.
First marker name will go to the first selected clip, second marker to the second clip and so on.
You can't have any other markers in the way otherwise it will use those to name.Give this a try,
function getMemLoc() { // Functions to grab start and end time on any counter //( because its running on clipDoForEachSelectedClip it should be Samples, but will work on any) const getSelectionStart = () => sf.ui.proTools.selectionGet().selectionStart.replace(/[:.+| ]/g, ''); const getSelectionEnd = () => sf.ui.proTools.selectionGet().selectionEnd.replace(/[:.+| ]/g, ''); // filter mem locs within selection const memLocFromSelection = sf.proTools.memoryLocationsFetch().collection['list'].filter(m => m.mainCounterValue.replace(/[:.+| ]/g, '') >= getSelectionStart() && m.mainCounterValue.replace(/[:.+| ]/g, '') <= getSelectionEnd() ); // return first memory location within selection return memLocFromSelection } let index = 0 /** * @param {array} memLocs */ function renameClip(memLocs) { if (memLocs[index]) { //Open Rename window sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] }); //Reference for Rename Window const renameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({ waitType: "Appear" }).element const nameClipOnlyButton = renameWin.groups.first.radioButtons.first /// Set Clip Name Only if (nameClipOnlyButton.exists) renameWin.groups.first.radioButtons.first.checkboxSet({ targetValue: "Enable" }); // Set the clip name to Track name renameWin.groups.first.textFields.first.elementSetTextFieldWithAreaValue({ value: memLocs[index].name }); // Click OK renameWin.buttons.whoseTitle.is('OK').first.elementClick() // Wait for window to cloce renameWin.elementWaitFor({ waitType: "Disappear" }) index++ } } function main() { // Acivate Pro Tools sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.invalidate(); sf.ui.proTools.memoryLocationsEnsureWindow({ restoreWindowOpenState: true, action: () => { // Get Locations from selection const memLocFromSelection = getMemLoc() // Do For Each sf.ui.proTools.clipDoForEachSelectedClip({ action: () => renameClip(memLocFromSelection), onError: "Continue" }); } }); }; main();
- In reply tosamuel_henriques⬆:KKurt Kellenberger @Kurt_Kellenberger
Hi, I want to do something very similar, except that instead of replacing the clip name, I want to add each marker name to the beginning of
click to show
- MIn reply toMaggy_Ayala⬆:Maggy Ayala @Maggy_Ayala
Hey Samuel, this one definetly works a lot better, pretty happy about it :) again, thanks so much for you help
Still, I can see even I made sure each clip is near to his marker, at some point just stop to rename (but still does the process like copying the name from the marker, and still at some point takes from the marker 2 clips away
I also notice that It doesnt name correctly if I do a huge selectionI am still trying to figure all the little glitches
I will so another little video soon - MIn reply toMaggy_Ayala⬆:Maggy Ayala @Maggy_Ayala
Have a look
https://filebin.net/vxw9vrnb5e448q8e
there are bit even I am inside the rules I was following for the others clips, (as you said for the new script, select markers and clips to rename) still, it will not rename correctly, even if I consolidate again
I am on PT 2020.12.0 and OSX 10.15.6samuel henriques @samuel_henriques
something else is wrong, it should choose "name clip only" and its not doing it, on the other video as well. The recording might be missing if because it's too fast, but you should be able to see it.
can't say if it has to do with versions of pt, but I'm on 2021.7, and might be some things different versions do to soundFlow.
on this video, it didn't rename anything, or you made the video after renaming?
do you see the memory locations window open and close?
samuel henriques @samuel_henriques
you have the memory locations sorted by number, could you try to sort by time?
it certainly makes a difference for this workflow.
- WIn reply toMaggy_Ayala⬆:William Kleinsasser @William_Kleinsasser
Hello, I have a need to use this exact functionality in Protools sessions with multiple clips. I'm using Protools version 2022.9.0 for reasons of plugin compatibility. The script below is not working for me. I'm selecting all the clips in the session, including the markers bar and then running the script but in Protools the only thing that happens is Protools becomes the active top application. If anyone can help, I'd really appreciate it.
Thanks,
WKfunction getMemLoc() { // Functions to grab start and end time on any counter //( because its runnign on clipDoForEachSelectedClip it should be Samples, but will work on any) const getSelectionStart = () => sf.ui.proTools.selectionGet().selectionStart.replace(/[:.+| ]/g, ''); const getSelectionEnd = () => sf.ui.proTools.selectionGet().selectionEnd.replace(/[:.+| ]/g, ''); // filter mem locs within selection const memLocFromSelection = sf.proTools.memoryLocationsFetch().collection['list'].filter(m => m.mainCounterValue.replace(/[:.+| ]/g, '') >= getSelectionStart() && m.mainCounterValue.replace(/[:.+| ]/g, '') <= getSelectionEnd() ); // return first memory location within selection return memLocFromSelection[0] }; function renameClip() { // Get First Memory Location Name from selection const memLocFromSelection = getMemLoc() if (memLocFromSelection) { //Open Rename window sf.ui.proTools.menuClick({ menuPath: ['Clip', 'Rename...'] }); //Reference for Rename Window const renameWin = sf.ui.proTools.windows.whoseTitle.is('Name').first.elementWaitFor({ waitType: "Appear" }).element const nameClipOnlyButton = renameWin.groups.first.radioButtons.first /// Set Clip Name Only if (nameClipOnlyButton.exists) renameWin.groups.first.radioButtons.first.checkboxSet({ targetValue: "Enable" }); // Set the clip name to Track name renameWin.groups.first.textFields.first.elementSetTextFieldWithAreaValue({ value: memLocFromSelection.name }); // Click OK renameWin.buttons.whoseTitle.is('OK').first.elementClick() // Wait for window to cloce renameWin.elementWaitFor({ waitType: "Disappear" }) } } function main() { // Acivate Pro Tools sf.ui.proTools.appActivateMainWindow() // Do For Each sf.ui.proTools.clipDoForEachSelectedClip({ action: renameClip, onError: "Continue" }) } main()
- WWilliam Kleinsasser @William_Kleinsasser
I figured it out. In the Protools session only one track can be selected. Before running the script, open Protools file and select a single track name in the left column of the tracks window, then select the region and include the marker strip in the selection. Be sure that markers and clips are sorted by time not name. With these settings and selection, run the SoundFlow script to rename clips with marker names. This is such a useful script! Thank you.
- DIn reply toMaggy_Ayala⬆:Dylan Furrow @Dylan_Furrow
Hey guys, I've been trying to use this script and it doesn't seem to be renaming the clips. Everything else seems fine though
- GIn reply toMaggy_Ayala⬆:Gary Keane @Gary_Keane
Hi all, I've been looking through this post as it exactly what I'm hoping to do. However, I haven't been able to get a script working for me yet.
Here's what I'm hoping to achieve:
Rename a number of clips based on the marker before them and up until the next marker. Then repeat with the next marker. I would ideally like to do it within a selected section if at all possible:
So you'll see how I'd like it to be sectioned out with each red box containing a number of clips that are to be renamed based on the marker before them and up until the next marker.
I'd also like them to include numbers are the end of each clip - 01 02 03 04 05 06 07 08 09 10 11....etc
So ideally:
- I select a group of clips
- SoundFlow renames the clips based on the marker before the clips and adds (01 02 03 04 05 06 07 08 09 10 11....etc) to the end of each clip
Is it possible?
- GGary Keane @Gary_Keane
Sorry, I should mention that I've tried all the scripts above an none seem to work for me. I'm getting as far as the first clip getting renamed but none of the rest of them. @samuel_henriques I'm wondering did you get the script working for you?
samuel henriques @samuel_henriques
hello Gary,
Try this:function getMemLocsInSelection(inTime, outTime) { const memLocs = sf.app.proTools.invalidate().memoryLocations.allItems.map(m => ({ name: m.name, startTime: String(m.startTimeInSamples), startTimeInSamples: m.startTimeInSamples })) return memLocs.filter(ml => +ml.startTimeInSamples >= +inTime && +ml.startTimeInSamples <= +outTime).sort((a, b) => +a.startTimeInSamples - +b.startTimeInSamples) } function dismissRenameError() { const renameErrorWin = sf.ui.proTools.windows.whoseTitle.is('Batch Clip Rename Error').first if (renameErrorWin.exists) { renameErrorWin.buttons.whoseTitle.is('OK').first.elementClick() renameErrorWin.elementWaitFor({ waitType: "Disappear" }) }; }; function menuOpenBatchRename() { function clipListPopupMenu(path) { //Old /* sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({ menuPath: path, targetValue: "Enable" }); */ sf.ui.proTools.mainWindow.buttons.whoseTitle.is("Plate").first.popupMenuSelect({ menuPath: path, targetValue: "Enable" }) sf.ui.proTools.appActivateMainWindow() } // Get clip list open/closed for later const clipListWasClosed = sf.ui.proTools.getMenuItem("View", "Other Displays", "Clip List").isMenuChecked /// Show Clip List sf.ui.proTools.menuClick({ menuPath: ["View", "Other Displays", "Clip List"], targetValue: "Enable" }); //Clear search let clearSearchTextBtn = sf.ui.proTools.mainWindow.buttons.whoseValue.is("Clear Search Text").first if (clearSearchTextBtn.exists) { clearSearchTextBtn.elementClick(); } /// Show audio and auto-created let enableViewMenus = [ ["Audio"], ["Auto-Created"], ] enableViewMenus.forEach(clipListPopupMenu) // count selected clips on clip list //Old // If clear find was needed, the clips need to be selected again so they get selected on the clip list /* let clipsTable = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first; let selectedClipCount = clipsTable.getElements("AXSelectedRows").allItems.invalidate().length; */ let selectedClipCount = sf.app.proTools.getSelectedClipInfo().clips.length if (selectedClipCount === 0) { alert('Please select at least one whole clip to export and try again.') throw 0 } sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is("Show Options Menu").first.popupMenuSelect({ menuPath: ["Batch Rename..."], }); /* // Set clip list open/closed as it was if (!clipListWasClosed) sf.ui.proTools.menuClick({ menuPath: ["View", "Other Displays", "Clip List"], targetValue: "Disable" }); // reset menus sf.keyboard.press({ keys: 'n', fast: true, repetitions: 2 }); */ }; /** * @param {Object} data */ function batchClipRename({ clipName }) { sf.app.proTools.invalidate() sf.keyboard.press({ keys: "ctrl+shift+r", fast: true }); const batchClipRenameWin = sf.ui.proTools.windows.whoseTitle.is('Batch Clip Rename').first; try { batchClipRenameWin.elementWaitFor({ waitType: "Appear", timeout: 500 }); } catch (err) { menuOpenBatchRename() batchClipRenameWin.elementWaitFor({ waitType: "Appear", timeout: 500 }); } const checkBoxWhoseTitle = batchClipRenameWin.checkBoxes.whoseTitle; checkBoxWhoseTitle.is('Replace').first.checkboxSet({ targetValue: "Enable" }); checkBoxWhoseTitle.is('Clear Existing Name').first.checkboxSet({ targetValue: "Enable" }); checkBoxWhoseTitle.is('Regular Expressions').first.checkboxSet({ targetValue: "Disable" }); checkBoxWhoseTitle.is('Trim').first.checkboxSet({ targetValue: "Disable" }); checkBoxWhoseTitle.is('Add').first.checkboxSet({ targetValue: "Enable" }); checkBoxWhoseTitle.is('Numbering').first.checkboxSet({ targetValue: "Enable" }); checkBoxWhoseTitle.is("Separate With:").first.checkboxSet({ targetValue: "Disable" }); batchClipRenameWin.radioButtons.whoseTitle.is("Timeline Order (Left to Right, Top to Bottom)").first.checkboxSet({ targetValue: "Enable" }); checkBoxWhoseTitle.is("Prefix:").first.checkboxSet({ targetValue: "Enable" }); checkBoxWhoseTitle.is("Insert:").first.checkboxSet({ targetValue: "Disable" }); checkBoxWhoseTitle.is("Suffix:").first.checkboxSet({ targetValue: "Disable" }); checkBoxWhoseTitle.is("Use A..Z").first.checkboxSet({ targetValue: "Disable" }); // Prefix batchClipRenameWin.textFields.allItems[6].elementSetTextFieldWithAreaValue({ value: clipName }) if (batchClipRenameWin.popupButtons.first.value.invalidate().value !== "End") { batchClipRenameWin.popupButtons.first.popupMenuSelect({ menuPath: ["End"] }) }; // Starting Number batchClipRenameWin.textFields.allItems[11].elementSetTextFieldWithAreaValue({ value: "1", useMouseKeyboard: true }); //Number of places batchClipRenameWin.textFields.allItems[12].elementSetTextFieldWithAreaValue({ value: "2", useMouseKeyboard: true }); batchClipRenameWin.buttons.whoseTitle.is('OK').first.elementClick(); batchClipRenameWin.elementWaitFor({ waitType: "Disappear" }); dismissRenameError(); }; function main() { sf.app.proTools.invalidate() const { inTime, outTime } = sf.app.proTools.getTimelineSelection({ timeScale: "Samples" }) const selectionMemLocs = getMemLocsInSelection(inTime, outTime) const selectedTracks = sf.ui.proTools.selectedTrackNames selectionMemLocs.forEach((memLoc, i, arr) => { // Make clip selection between mem locs sf.app.proTools.setTimelineSelection({ inTime: selectionMemLocs[i].startTime, outTime: arr[i + 1] ? arr[i + 1].startTime : outTime }) // setTimelineSelection does not select clips in clip list - but after track is re-selected, it does sf.app.proTools.selectTracksByName({ trackNames: selectedTracks }) const isCLipSelected = sf.app.proTools.getSelectedClipInfo().clips.length > 0 if (isCLipSelected) { batchClipRename({ clipName: memLoc.name + "_" }) } }) // Finish with initial selection sf.app.proTools.setTimelineSelection({ inTime: inTime, outTime: outTime }) } main();
- GGary Keane @Gary_Keane
Samuel, you are a genius! That is going to save me a ridiculous amount of time in renaming. Thanks so much!!
- In reply tosamuel_henriques⬆:GGary Keane @Gary_Keane
Hi Samuel, for some reason the script has stopped working. It was working with some small clusters of clips but once I went into large numbers, nothing happens when I ran the command and if I try to rename small batches again, the command stops working. Sometimes if I restart Pro Tools or SoundFlow, it will work again, but for now I can't get it to work.
Right now in the past 5 mins it's throwing up the following error:
I wonder has it to so with window layout or UI or something. I should mention that I have also got track markers active in my session although I have successfully renamed small batches of regions using the macro in the session regardless of these track markers:
Any ideas, it was going so well...
Many thanks
samuel henriques @samuel_henriques
This error is the batch rename window not opening. The script is opening the window using ctrl+shift+r. Reasons for window not opening by pr
click to show