Moving clips with embedded names to selected tracks.
I searched and this has been asked before but is there any real way to do this. I'm working on a show now with 5 main characters and a bunch of additional ones. The crew in the field did a great job of labeling the tracks before things were recorded so every character's clip has their name in it. I know it's probably easier said then done but if there is a clip that had... "kljiojojiojioj... John" in it is there anyway to create a "John" track and have the clip move that track. Obviously this would be a big one for most post work.
- Nathan Salefski @nathansalefski
Here's an option. Instead of it searching the selected clip name, it will work with any selected clip. This is very easily adaptable so long as you switch out
"John"
for any other character's name. Hope it helps!function createTrack(name) { sf.ui.proTools.menuClick({ menuPath: ['Track', 'New...'] }); let newTrackWin = sf.ui.proTools.windows.whoseTitle.is("New Tracks").first; newTrackWin.elementWaitFor(); newTrackWin.textFields.whoseTitle.is("Number of new tracks").first.elementSetTextFieldWithAreaValue({ useMouseKeyboard: true, value: '1' }); newTrackWin.popupButtons.first.popupMenuSelect({ menuPath: ['Mono'] }); newTrackWin.popupButtons.allItems[1].popupMenuSelect({ menuPath: ['Audio Track'] }); newTrackWin.popupButtons.allItems[2].popupMenuSelect({ menuPath: ['Samples'] }); newTrackWin.textFields.whoseTitle.is("Track Name").first.elementSetTextFieldWithAreaValue({ value: name }); newTrackWin.buttons.whoseTitle.is("Create").first.elementClick(); sf.ui.proTools.waitForNoModals(); } function main() { sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.invalidate(); let originalSelectionStart = sf.ui.proTools.selectionGetInSamples().selectionStart; let originalSelectionEnd = sf.ui.proTools.selectionGetInSamples().selectionEnd; sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Cut'] }); let characterTrackIndex = sf.ui.proTools.visibleTrackNames.indexOf('John'); if (characterTrackIndex < 0) { createTrack('John'); } sf.ui.proTools.invalidate().trackSelectByName({ names: ['John'], deselectOthers: true }); sf.ui.proTools.selectionSetInSamples({ selectionStart: originalSelectionStart, selectionEnd: originalSelectionEnd, }); sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Paste'] }); } main();
- CChris Testa @Chris_Testa
Wow. Ok. thanks Nathan! I'll give it a try and let you know..
- In reply tonathansalefski⬆:CChris Testa @Chris_Testa
Hello Nathan,
So I only changed the 3 instances of "John" in the script and it didn't work. It basically took the track I selected, deleted it, then copy pasted it on the correct track. So it got to the correct track but it didn't pick out the name from the selected clips. In the example I selected about 25 clips and 1 of them had the name I entered in it. I moved the destination track and it always find's it which is nice. It's just not finding the name in the clip. Is there something else I need to change in the script that I'm not changing? Thank you. chris
Nathan Salefski @nathansalefski
So the code above doesn't do any filtering. It will simply take the selected clip and place it on the desired character track. I've added filtering to select the first clip with the characters name and place it on the desired character track. Let me know how this works for you !
function createTrack(name) { sf.ui.proTools.menuClick({ menuPath: ['Track', 'New...'] }); let newTrackWin = sf.ui.proTools.windows.whoseTitle.is("New Tracks").first; newTrackWin.elementWaitFor(); newTrackWin.textFields.whoseTitle.is("Number of new tracks").first.elementSetTextFieldWithAreaValue({ useMouseKeyboard: true, value: '1' }); newTrackWin.popupButtons.first.popupMenuSelect({ menuPath: ['Mono'] }); newTrackWin.popupButtons.allItems[1].popupMenuSelect({ menuPath: ['Audio Track'] }); newTrackWin.popupButtons.allItems[2].popupMenuSelect({ menuPath: ['Samples'] }); newTrackWin.textFields.whoseTitle.is("Track Name").first.elementSetTextFieldWithAreaValue({ value: name }); newTrackWin.buttons.whoseTitle.is("Create").first.elementClick(); sf.ui.proTools.waitForNoModals(); } function getClipName(selectedClipNames) { sf.ui.proTools.menuClick({ menuPath: ["Clip", "Rename..."] }); const nameWindow = sf.ui.proTools.windows.invalidate().whoseTitle.is("Name").first nameWindow.elementWaitFor(); const clipName = nameWindow.groups.whoseTitle.is("Name").first.textFields.first.value.invalidate().value; nameWindow.buttons.whoseTitle.is("Cancel").first.elementClick(); nameWindow.elementWaitFor({ waitType: "Disappear" }); selectedClipNames.push(clipName); } function getClipStart(selectedClipsStart) { let clipStart = sf.ui.proTools.selectionGetInSamples().selectionStart; selectedClipsStart.push(clipStart); } function getClipEnd(selectedClipEnd) { let clipEnd = sf.ui.proTools.selectionGetInSamples().selectionEnd; selectedClipEnd.push(clipEnd); } function filterSelectedClips(name) { sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); let selectedClipNames = [] sf.ui.proTools.clipDoForEachSelectedClip({ action: () => getClipName(selectedClipNames) }); let selectedClipsStart = [] sf.ui.proTools.clipDoForEachSelectedClip({ action: () => getClipStart(selectedClipsStart) }); let selectedClipEnd = [] sf.ui.proTools.clipDoForEachSelectedClip({ action: () => getClipEnd(selectedClipEnd) }); let characterClip = selectedClipNames.filter(clipname => clipname.includes(name))[0]; let indexOfCharacterClip = selectedClipNames.indexOf(characterClip); let characterClipStart = selectedClipsStart[indexOfCharacterClip]; let characterClipEnd = selectedClipEnd[indexOfCharacterClip]; sf.ui.proTools.selectionSetInSamples({ selectionStart: characterClipStart, selectionEnd: characterClipEnd, }); } function main() { sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.invalidate(); filterSelectedClips('John'); let characterClipStart = sf.ui.proTools.selectionGetInSamples().selectionStart; let characterClipEnd = sf.ui.proTools.selectionGetInSamples().selectionEnd; sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Cut'] }); let characterTrackIndex = sf.ui.proTools.visibleTrackNames.indexOf('John'); if (characterTrackIndex < 0) { createTrack('John'); } sf.ui.proTools.invalidate().trackSelectByName({ names: ['John'], deselectOthers: true }); sf.ui.proTools.selectionSetInSamples({ selectionStart: characterClipStart, selectionEnd: characterClipEnd, }); sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Paste'] }); } main();
- CChris Testa @Chris_Testa
Wow. You are going above and beyond. Thank you. So I tried it again and it did work. But, it didn't grab all the clips with the name in it. I tried the same example as before. The last 5 clips have the name in it. So it scanned through the track, tabbing and selecting each region and it did that a few times and then it copied the one clip down but not the others. For example, this is the clip name "sd970-000c2a-QUEENS100923-008(A)_AA_02_Rodney_02.wav.new.01-01" and "Rodney" is the name I am swapping out "John" for. So that was the first clip with the "Rodney" name. So I guess I'm wondering if there is a way to have it pull all of those clips down with that name? Let me know if you need any more info. And thank you for doing this. You totally don't need to be doing this... so thank you.
Nathan Salefski @nathansalefski
Try this one out:
function createTrack(name) { sf.ui.proTools.menuClick({ menuPath: ['Track', 'New...'] }); let newTrackWin = sf.ui.proTools.windows.whoseTitle.is("New Tracks").first; newTrackWin.elementWaitFor(); newTrackWin.textFields.whoseTitle.is("Number of new tracks").first.elementSetTextFieldWithAreaValue({ useMouseKeyboard: true, value: '1' }); newTrackWin.popupButtons.first.popupMenuSelect({ menuPath: ['Mono'] }); newTrackWin.popupButtons.allItems[1].popupMenuSelect({ menuPath: ['Audio Track'] }); newTrackWin.popupButtons.allItems[2].popupMenuSelect({ menuPath: ['Samples'] }); newTrackWin.textFields.whoseTitle.is("Track Name").first.elementSetTextFieldWithAreaValue({ value: name }); newTrackWin.buttons.whoseTitle.is("Create").first.elementClick(); sf.ui.proTools.waitForNoModals(); } function getClipName(selectedClipNames) { sf.ui.proTools.menuClick({ menuPath: ["Clip", "Rename..."] }); const nameWindow = sf.ui.proTools.windows.invalidate().whoseTitle.is("Name").first nameWindow.elementWaitFor(); const clipName = nameWindow.groups.whoseTitle.is("Name").first.textFields.first.value.invalidate().value; nameWindow.buttons.whoseTitle.is("Cancel").first.elementClick(); nameWindow.elementWaitFor({ waitType: "Disappear" }); selectedClipNames.push(clipName); } function getClipStart(selectedClipsStart) { let clipStart = sf.ui.proTools.selectionGetInSamples().selectionStart; selectedClipsStart.push(clipStart); } function getClipEnd(selectedClipEnd) { let clipEnd = sf.ui.proTools.selectionGetInSamples().selectionEnd; selectedClipEnd.push(clipEnd); } function copyClipsToCharacterTrack(name) { let selectedClipNames = []; let selectedClipsStart = []; let selectedClipEnd = []; sf.ui.proTools.clipDoForEachSelectedClip({ action: () => getClipName(selectedClipNames) }); sf.ui.proTools.clipDoForEachSelectedClip({ action: () => getClipStart(selectedClipsStart) }); sf.ui.proTools.clipDoForEachSelectedClip({ action: () => getClipEnd(selectedClipEnd) }); let characterClip = selectedClipNames.filter(clipname => clipname.includes(name)); characterClip.forEach(clipName => { let selectedTrackName = sf.ui.proTools.selectedTrackNames[0]; let indexOfCharacterClip = selectedClipNames.indexOf(clipName); let characterClipStart = selectedClipsStart[indexOfCharacterClip]; let characterClipEnd = selectedClipEnd[indexOfCharacterClip]; sf.ui.proTools.selectionSetInSamples({ selectionStart: characterClipStart, selectionEnd: characterClipEnd, }); sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Cut'] }); sf.ui.proTools.invalidate().trackSelectByName({ names: [name], deselectOthers: true }); sf.ui.proTools.selectionSetInSamples({ selectionStart: characterClipStart, selectionEnd: characterClipEnd, }); sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Paste'] }); sf.ui.proTools.invalidate().trackSelectByName({ names: [selectedTrackName], deselectOthers: true }); }) } function main() { sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.invalidate(); let originallySelectedTrack = sf.ui.proTools.selectedTrackNames; let originalSelection = sf.ui.proTools.selectionGetInSamples(); let characterTrackIndex = sf.ui.proTools.visibleTrackNames.indexOf('John'); if (characterTrackIndex < 0) { createTrack('John'); sf.ui.proTools.trackSelectByName({ names: originallySelectedTrack, deselectOthers: true, }); sf.ui.proTools.selectionSetInSamples({ selectionStart: originalSelection.selectionStart, selectionEnd: originalSelection.selectionEnd, }); } copyClipsToCharacterTrack('John'); } main();
- CChris Testa @Chris_Testa
That works perfectly. That's insane man. Ha! This is going to save me a lot of time. I do have a question about how it works. I think it goes through the files 3 times? I'm assuming each one is kind of gathering more information? Also, I was talking to a friend, does it rely on the underscore on either side of the name? The reason I ask is if I have files that don't have the underscore, let's say "..... Rodney... " will it still work? Thank you thank you thank you again.
Nathan Salefski @nathansalefski
You're right those three steps can be combined. Sorry coding between mixes lol. Here you go! As far as the name, it's simply searching for clips that include
John
or in your exampleRodney
, the underscores shouldn't matterfunction createTrack(name) { sf.ui.proTools.menuClick({ menuPath: ['Track', 'New...'] }); let newTrackWin = sf.ui.proTools.windows.whoseTitle.is("New Tracks").first; newTrackWin.elementWaitFor(); newTrackWin.textFields.whoseTitle.is("Number of new tracks").first.elementSetTextFieldWithAreaValue({ useMouseKeyboard: true, value: '1' }); newTrackWin.popupButtons.first.popupMenuSelect({ menuPath: ['Mono'] }); newTrackWin.popupButtons.allItems[1].popupMenuSelect({ menuPath: ['Audio Track'] }); newTrackWin.popupButtons.allItems[2].popupMenuSelect({ menuPath: ['Samples'] }); newTrackWin.textFields.whoseTitle.is("Track Name").first.elementSetTextFieldWithAreaValue({ value: name }); newTrackWin.buttons.whoseTitle.is("Create").first.elementClick(); sf.ui.proTools.waitForNoModals(); } function getClipInfo(selectedClipNames, selectedClipsStart, selectedClipEnd) { let clipRange = sf.ui.proTools.selectionGetInSamples(); sf.ui.proTools.menuClick({ menuPath: ["Clip", "Rename..."] }); const nameWindow = sf.ui.proTools.windows.invalidate().whoseTitle.is("Name").first nameWindow.elementWaitFor(); const clipName = nameWindow.groups.whoseTitle.is("Name").first.textFields.first.value.invalidate().value; nameWindow.buttons.whoseTitle.is("Cancel").first.elementClick(); nameWindow.elementWaitFor({ waitType: "Disappear" }); selectedClipNames.push(clipName); selectedClipsStart.push(clipRange.selectionStart); selectedClipEnd.push(clipRange.selectionEnd); } function copyClipsToCharacterTrack(name) { let selectedClipNames = []; let selectedClipsStart = []; let selectedClipEnd = []; sf.ui.proTools.clipDoForEachSelectedClip({ action: () => getClipInfo( selectedClipNames, selectedClipsStart, selectedClipEnd), }); let characterClips = selectedClipNames.filter(clipname => clipname.includes(name)); characterClips.forEach(clipName => { let selectedTrackName = sf.ui.proTools.selectedTrackNames[0]; let indexOfCharacterClip = selectedClipNames.indexOf(clipName); let characterClipStart = selectedClipsStart[indexOfCharacterClip]; let characterClipEnd = selectedClipEnd[indexOfCharacterClip]; sf.ui.proTools.selectionSetInSamples({ selectionStart: characterClipStart, selectionEnd: characterClipEnd, }); sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Cut'] }); sf.ui.proTools.invalidate().trackSelectByName({ names: [name], deselectOthers: true }); sf.ui.proTools.selectionSetInSamples({ selectionStart: characterClipStart, selectionEnd: characterClipEnd, }); sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Paste'] }); sf.ui.proTools.invalidate().trackSelectByName({ names: [selectedTrackName], deselectOthers: true }); }) } function main() { sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.invalidate(); let originallySelectedTrack = sf.ui.proTools.selectedTrackNames; let originalSelection = sf.ui.proTools.selectionGetInSamples(); let characterTrackIndex = sf.ui.proTools.visibleTrackNames.indexOf('John'); if (characterTrackIndex < 0) { createTrack('John'); sf.ui.proTools.trackSelectByName({ names: originallySelectedTrack, deselectOthers: true, }); sf.ui.proTools.selectionSetInSamples({ selectionStart: originalSelection.selectionStart, selectionEnd: originalSelection.selectionEnd, }); } copyClipsToCharacterTrack('John'); } main();
- CChris Testa @Chris_Testa
holy wow. Love it man. Do you use it as well?
Nathan Salefski @nathansalefski
Nope just wrote it for you. I work in music so not much need for this specifically but fun to solve problems.
- CChris Testa @Chris_Testa
Man I wish I could code like this. This entire forum has to be the most giving forum I've ever been on. Well thank you again and let me know if you need anything from me. I definitely owe you. Thank you. chris
Nathan Salefski @nathansalefski
I didn’t know anything about coding just a few months ago. This forum is awesome. It’s what taught me the most! You’re all good man. Let me know if you run into any issues
- CIn reply toChris_Testa⬆:Chris Testa @Chris_Testa
Wow. Amazing. Thank you again.