How do you repeat a script until there are no clips left in timeline?
I created a macro to help with sound effects editing for repeated graphics. During my spotting session I create clip groups on specific tracks at every point where a graphic appears on screen (for example, a lower third whoosh for a name that repeats on every interview throughout the episode). When I'm done, I move the spotting track directly above the FX track in my session, and then paste the design for the graphic on the track below. Right now, I just continually use a macro that moves to the track below, pastes, moves back up, and then tabs twice to get to the next location (; then Edit>Paste then p then tab tab). It would be nice if I could make that macro repeat indefinitely until it reaches the end of the clips in the spotting track.
- Dustin Harris @Dustin_Harris
if the clips are all on the same track, you can do something like this:
function giveThisFunctionAName() { //all your code goes here } sf.ui.proTools.clipDoForEachSelectedClip({ action: clip => giveThisFunctionAName() });
You may need to think it out, like copy what you want to paste in the clipboard before running this script, etc, but this should get you started :)
- EEric Leigh @Eric_Leigh
Hi Dustin,
I haven't had an opportunity to try this out until now, so thanks for your response! I can't seem to make it work for me though. here is a macro that I would like to make run across all clips on the selected track(s) (hopefully working with a group in pro tools as well).
sf.ui.proTools.nudgeSet({ value: "0000000400", }); sf.keyboard.press({ keys: "cmd+numpad plus", }); sf.ui.proTools.nudgeSet({ value: "0000000400", }); sf.keyboard.press({ keys: "alt+numpad minus", }); sf.ui.proTools.nudgeSet({ value: "0000000100", }); //Calling command "KC: Control Tab" from package "Pro Tools" sf.soundflow.runCommand({ commandId: 'user:default:ckndqdrm6001krh1046alghwz', props: {} });
- OIn reply toEric_Leigh⬆:Owen Granich-Young @Owen_Granich_Young
Hey Eric,
Not sure what you're 2nd macro here is supposed to do, if you describe what it's actually doing there may be another approach, In the mean time here's a script to do your first request. Highlight all the clips in your spot track and make sure your clipboard is loaded with the correct sound and the track below is empty, press go.
function navigateTrack({ direction, repetitions }) { for (let i = 0; i < repetitions; i++) { if (direction === 'Up') { sf.ui.proTools.getMenuItem("Edit", "Selection", "Extend Edit Up").elementClick(); sf.ui.proTools.getMenuItem("Edit", "Selection", "Remove Edit from Bottom").elementClick(); } if (direction === 'Down') { sf.ui.proTools.getMenuItem("Edit", "Selection", "Extend Edit Down").elementClick(); sf.ui.proTools.getMenuItem("Edit", "Selection", "Remove Edit from Top").elementClick(); } } } function downCopyBack() { navigateTrack({ direction: `Down`, repetitions: 1 }) sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"] }); navigateTrack({ direction: `Up`, repetitions: 1 }) } sf.ui.proTools.clipDoForEachSelectedClip({ action: downCopyBack });
bests,
owen- EEric Leigh @Eric_Leigh
Thanks so much for this Owen!
My second script is for extending the handles of clips by a set amount (in this case, 4 frames) across all clips on a track. I use a picture cut track from EdiLoad to cut my interior and exterior BGs to be exactly on the frame changes, and then extend it out 4 frames on either side so I can fade them into each other. It's for a quick and dirty edit when we don't have enough time to really dial them in.
- OOwen Granich-Young @Owen_Granich_Young
This is my favorite fastest extend and fade script... there are many ways to do it. I like this build by
@samuel_henriques/** * @param {1|2|3|4|5} preset */ function createFades(preset) { sf.ui.proTools.menuClick({ menuPath: ["Edit", "Fades", "Create..."] }); const batchFadesWin = sf.ui.proTools.windows.whoseTitle.is('Batch Fades').first; batchFadesWin.elementWaitFor({}, "Batch Fades Win Didn\'t Open."); batchFadesWin.buttons.whoseTitle.is(`Fade Preset Toggle ${preset}`).first.elementClick(); batchFadesWin.buttons.whoseTitle.is('OK').first.elementClick(); batchFadesWin.elementWaitFor({ waitType: "Disappear" }, "Batch Fades Win Didn\'t Close."); }; function nudgeValue() { const nudgeBtn = sf.ui.proTools.mainWindow.gridNudgeCluster.nudgeControls const nudgeValue = nudgeBtn.nudgeValue.invalidate().value.value // If has 3x : it is Timecode if (nudgeValue.split(":").length == 4) { // If not 1 frame, set 1 frame if (!nudgeValue.endsWith("01.00")) sf.ui.proTools.nudgeSet({ value: "00:00:00:01.00" }); } else { nudgeBtn.nudgeValuePopupButton.popupMenuSelect({ menuPath: ["Timecode"], }); sf.ui.proTools.nudgeSet({ value: "00:00:00:01.00" }); } } function extendSelectionOnEitherSide(frameCount) { nudgeValue(); sf.keyboard.press({ keys: 'alt+numpad minus', repetitions: frameCount, fast: true }); sf.keyboard.press({ keys: 'cmd+numpad plus', repetitions: frameCount, fast: true }); }; function getOriginalToolSelection() { // Get original Tools Selection const originalToolSelection = sf.ui.proTools.mainWindow.cursorToolCluster.buttons.filter(btn => btn.title.value == "Smart tool" || btn.title.value == "Trim tool" || btn.title.value == "Selector tool" || btn.title.value.startsWith("Grabber tool") ).filter(btn => btn.value.invalidate().value === "Selected") return originalToolSelection }; function setOriginalToolSelection(originalToolSelection) { ///Set Original Tools Selection originalToolSelection.map(selBtn => selBtn.title.value).indexOf("Smart Tool") > 0 ? originalToolSelection.filter(selBtn => selBtn.title.value === "Smart Tool")[0].elementClick() : originalToolSelection[0].elementClick() }; function setGrabberObjectTool() { const grabberToolToolBtn = sf.ui.proTools.mainWindow.groups.allItems[2].buttons.whoseTitle.startsWith('Grabber tool').first grabberToolToolBtn.elementClick(); grabberToolToolBtn.popupMenuSelect({ isRightClick: true, menuPath: ['Object'] }); }; /** * @param {object} param * @param {number} param.extendFrames * @param {1|2|3|4|5} param.fadesPreset */ function main({ extendFrames, fadesPreset }) { sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.invalidate(); // Save tool selection to use at the end const originalToolSelection = getOriginalToolSelection(); // Get selected tracks names const selectedTrackNames = sf.ui.proTools.selectedTrackNames // Select grabber object tool setGrabberObjectTool(); //Select tracks again to so they are selected as object sf.ui.proTools.trackSelectByName({ names: selectedTrackNames }); //Extend clips extendSelectionOnEitherSide(extendFrames); //Select smart tool sf.ui.proTools.toolsSelect({ tool: "Smart" }); //Select tracks again to loose object selection sf.ui.proTools.trackSelectByName({ names: selectedTrackNames }); //Reset pt menus so fades are available sf.keyboard.press({ keys: 'n', repetitions: 2, fast: true }); //Batch fades create createFades(fadesPreset); //Set original tools selection setOriginalToolSelection(originalToolSelection); } main({ extendFrames: 1, fadesPreset: 3 });
On line 123 you can see I'm only extending 1 frame you can adjust that to your own desire. Then you need to assign one of your fade presets to the correct setting to hit your fades right probably something like this (this is for a 2 frame fade, don't affect cross fades... so maybe instead you want 168 Milliseconds if you do 4 frame cross fades) play with it and see what you think.
Here's the original post where different approaches to this were taken Extend all clips by 'x' & Batch Fade using Batch Fade preset (whole timeline)
Some people did not get the version I like working but he built a couple other versions....