No internet connection
  1. Home
  2. How to

Extend all clips by 'x' & Batch Fade using Batch Fade preset (whole timeline)

By Jason King @Jason_King
    2022-07-11 05:17:05.719Z

    Reading the below thread I thought I'd found what I was thinking in my head but the code basically batch fades using one of the 6 presets. Even though it does extend the selection (not the clip) but 'x'

    I want to;
    After selecting a whole timeline of clips

    1. Extend all clips by 'x'
    2. Batch Fade all clips using a fade preset.

    Before

    After

    Anyone have any ideas?

    • 52 replies

    There are 52 replies. Estimated reading time: 46 minutes

    1. samuel henriques @samuel_henriques
        2022-07-11 10:28:48.564Z2022-08-05 09:45:43.272Z

        Hey Jason,

        Didn't have time to test it too much, let me know how its working

        Set frames to extend and preset number on the lines like this at the end of the script:

        trimToFillSelection(10);
        createFades(1);
        

        Here you go:

        function getSessionFormat() {
            let sessionSetupWin = sf.ui.proTools.windows.whoseTitle.is("Session Setup").first
            const isSessionSetupOpen = sessionSetupWin.exists
        
            if (!isSessionSetupOpen) {
                sf.ui.proTools.menuClick({ menuPath: ["Setup", "Session"] });
            };
        
            sessionSetupWin = sf.ui.proTools.windows.whoseTitle.is("Session Setup").first
            const sessionFormatGroup = sessionSetupWin.groups.whoseTitle.is("Session Format").first
            const timeCodeRate = +sessionFormatGroup.popupButtons.allItems[2].value.invalidate().value.split(' ')[0];
        
            const sampleRateStaticTextElement = sessionFormatGroup.children.whoseRole.is("AXStaticText").allItems[2].value.invalidate().value.split(' ')[0];
            const sampleRate = Number(sampleRateStaticTextElement) * 1000
        
            if (!isSessionSetupOpen) { sf.ui.proTools.menuClick({ menuPath: ["Setup", "Session"] }) };
        
            return { sampleRate, timeCodeRate }
        };
        
        
        function copyAllAutomation() {
            sf.ui.proTools.menuClick({ menuPath: ["Edit", "Copy Special", "All Automation"] });
        };
        
        
        function pasteAllAutomation() {
            sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste Special", "Repeat to Fill Selection"] });
        };
        
        
        
        /**
        * @param {number} extendFrames
        * @param {{ sampleRate: number; timeCodeRate: number; }} sessionFormat
        */
        function trimToFillSelection(sessionFormat, extendFrames) {
        
            const extendAmount = Math.round(sessionFormat.sampleRate / sessionFormat.timeCodeRate * extendFrames)
            const currentSelection = sf.ui.proTools.selectionGetInSamples()
        
            sf.ui.proTools.selectionSetInSamples({
                selectionStart: +currentSelection.selectionStart - extendAmount,
                selectionEnd: +currentSelection.selectionEnd + extendAmount,
            });
        
            sf.ui.proTools.menuClick({ menuPath: ["Edit", "Trim Clip", "To Fill Selection"] });
        };
        
        
        /**
        * @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.elementWaitFor({}, "Batch Fades Win Didn\'t Open.").element
        
            batchFadesWin.buttons.whoseTitle.is("Fade Preset Toggle").allItems[preset - 1].elementClick();
        
            batchFadesWin.buttons.whoseTitle.is('OK').first.elementClick();
        
            batchFadesWin.elementWaitFor({ waitType: "Disappear" }, "Batch Fades Win Didn\'t Close.")
        };
        
        
        
        function main() {
        
            sf.ui.proTools.appActivateMainWindow();
        
            sf.ui.proTools.invalidate();
        
            const sessionFormat = getSessionFormat()
        
            //Get selected tracks
            const originalTracks = sf.ui.proTools.selectedTrackNames;
        
            //Do for each track.
            sf.ui.proTools.selectedTracks.trackHeaders.slice().map(track => {
        
                //Select track
                track.trackSelect();
        
                //Scroll track into View
                track.trackScrollToView();
        
                sf.ui.proTools.clipDoForEachSelectedClip({
                    action: () => {
        
                        copyAllAutomation();
        
                        trimToFillSelection(sessionFormat, 10);  //Set Number of Frames
        
                        pasteAllAutomation();
        
                        createFades(1);  // Set Preset Number
                    },
                    onError: "Continue",
                });
            });
        
            //Restore previously selected tracks
            sf.ui.proTools.trackSelectByName({ names: originalTracks });
        
        };
        
        
        main();
        
        1. Jason King @Jason_King
            2022-07-11 21:45:43.388Z2022-07-11 23:23:29.609Z

            Wow. Will try it. Thanks Samuel

            Why do you need to set sample and frame rate?

            Frame Rates change for us depending on the project.


            So I tried it. It kinda works.

            • On tracks that are checker-boarded (like above) the start and ends are extended by different amounts ranging from 19frames - 19sec & 9 frames.
            • On tracks that have the same region copied to multiple tracks starting in the same spot the start is extended 19 frames and the ends are extended 14 frames.

            It seems to shift the grid between timecode and min:sec at different points

            I think you're on the right track Samuel

            1. samuel henriques @samuel_henriques
                2022-07-11 23:39:46.938Z

                Hello Jason,

                Just updated a version that knows sample rate and frame rate so you don't have to set it up.

                Can't find a way reproduce that behaviour.
                Could you make a screen capture of the script working?
                I might spot something.

                1. Jason King @Jason_King
                    2022-07-12 00:39:14.170Z
                    1. samuel henriques @samuel_henriques
                        2022-07-12 22:11:30.797Z

                        Hello Jason,
                        You must copy all script lines starting at function getSessionFormat()

                        1. Jason King @Jason_King
                            2022-07-12 22:42:09.932Z

                            I have that>

                            1. samuel henriques @samuel_henriques
                                2022-07-12 22:45:37.789Z

                                You must delete line 1 and 2.

                                To set frames and preset is at the end of the script.

                                1. Jason King @Jason_King
                                    2022-07-12 22:55:57.221Z

                                    That was it.

                                    You're a genius Samuel. Works!

                                    So how do you change the amount it it extends the clips and how do you choose the fade preset?

                                    Never mind. It's the same as your original post

                                    1. Jason King @Jason_King
                                        2022-07-12 23:08:09.167Z

                                        @samuel_henriques Should I post this as solved? Or do you think the script could be optimised?

                                        1. samuel henriques @samuel_henriques
                                            2022-07-12 23:14:17.209Z

                                            I think, if this is what you were looking for, you can mark it. If you find anything in the future that could be improved, you can always come back to this post.

                                            1. Jason King @Jason_King
                                                2022-07-12 23:16:57.969Z

                                                Ok cool.

                                                Thanks Samuel. You have saved me hours of time per mix.

                                                1. Jason King @Jason_King
                                                    2022-07-12 23:38:05.000Z2022-07-13 00:13:43.374Z

                                                    Wait....

                                                    @samuel_henriques one more thing. Can you add the function for all automation follow the extension of the clip?

                                                    1. samuel henriques @samuel_henriques
                                                        2022-07-13 23:15:59.096Z

                                                        Sure, updated above.

                                                        1. Jason King @Jason_King
                                                            2022-07-13 23:37:13.181Z

                                                            You're a master!

                                                            Thanks @samuel_henriques 🤘🏻

                                    2. @samuel_henriques thanks for making THE version of this script, I have a few clunky ones that have worked with extra manual steps between for this function. Much nicer to have the 'Samuel special' version though!

                                      Bests,
                                      Owen

                                      1. Jason King @Jason_King
                                          2022-07-14 21:57:32.350Z

                                          So good. This is a great script.

                                      2. In reply toJason_King:
                                        Jason King @Jason_King
                                          2022-08-03 05:15:44.285Z

                                          Hey @samuel_henriques I just started getting this error.

                                          My code hasn't changed.

                                          function getSessionFormat() {
                                              let sessionSetupWin = sf.ui.proTools.windows.whoseTitle.is("Session Setup").first
                                              const isSessionSetupOpen = sessionSetupWin.exists
                                          
                                              if (!isSessionSetupOpen) {
                                                  sf.ui.proTools.menuClick({ menuPath: ["Setup", "Session"] });
                                              };
                                          
                                              sessionSetupWin = sf.ui.proTools.windows.whoseTitle.is("Session Setup").first
                                              const sessionFormatGroup = sessionSetupWin.groups.whoseTitle.is("Session Format").first
                                              const timeCodeRate = +sessionFormatGroup.popupButtons.allItems[2].value.invalidate().value
                                          
                                              const sampleRateStaticTextElement = sessionFormatGroup.children.whoseRole.is("AXStaticText").allItems[2].value.invalidate().value.split(' ')[0];
                                              const sampleRate = Number(sampleRateStaticTextElement) * 1000
                                          
                                          
                                              if (!isSessionSetupOpen) { sf.ui.proTools.menuClick({ menuPath: ["Setup", "Session"] }) };
                                          
                                              return { sampleRate, timeCodeRate }
                                          };
                                          
                                          
                                          function copyAllAutomation() {
                                              sf.ui.proTools.menuClick({ menuPath: ["Edit", "Copy Special", "All Automation"] });
                                          };
                                          
                                          
                                          function pasteAllAutomation() {
                                              sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste Special", "Repeat to Fill Selection"] });
                                          };
                                          
                                          
                                          
                                          /**
                                          * @param {number} extendFrames
                                          * @param {{ sampleRate: number; timeCodeRate: number; }} sessionFormat
                                          */
                                          function trimToFillSelection(sessionFormat, extendFrames) {
                                          
                                          
                                              const extendAmount = sessionFormat.sampleRate / sessionFormat.timeCodeRate * extendFrames
                                              const currentSelection = sf.ui.proTools.selectionGetInSamples()
                                          
                                              sf.ui.proTools.selectionSetInSamples({
                                                  selectionStart: +currentSelection.selectionStart - extendAmount,
                                                  selectionEnd: +currentSelection.selectionEnd + extendAmount,
                                              });
                                          
                                              sf.ui.proTools.menuClick({ menuPath: ["Edit", "Trim Clip", "To Fill Selection"] });
                                          };
                                          
                                          
                                          /**
                                          * @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.elementWaitFor({}, "Batch Fades Win Didn\'t Open.").element
                                          
                                              batchFadesWin.buttons.whoseTitle.is("Fade Preset Toggle").allItems[preset - 1].elementClick();
                                          
                                              batchFadesWin.buttons.whoseTitle.is('OK').first.elementClick();
                                          
                                              batchFadesWin.elementWaitFor({ waitType: "Disappear" }, "Batch Fades Win Didn\'t Close.")
                                          };
                                          
                                          
                                          
                                          function main() {
                                          
                                              sf.ui.proTools.appActivateMainWindow();
                                          
                                              sf.ui.proTools.invalidate();
                                          
                                              const sessionFormat = getSessionFormat()
                                          
                                              //Get selected tracks
                                              const originalTracks = sf.ui.proTools.selectedTrackNames;
                                          
                                              //Do for each track.
                                              sf.ui.proTools.selectedTracks.trackHeaders.slice().map(track => {
                                          
                                                  //Select track
                                                  track.trackSelect();
                                          
                                                  //Scroll track into View
                                                  track.trackScrollToView();
                                          
                                                  sf.ui.proTools.clipDoForEachSelectedClip({
                                                      action: () => {
                                          
                                                          copyAllAutomation();
                                          
                                                          trimToFillSelection(sessionFormat, 5);  //Set Number of Frames
                                          
                                                          pasteAllAutomation();
                                          
                                                          createFades(4);  // Set Preset Number
                                                      },
                                                      onError: "Continue",
                                                  });
                                              });
                                          
                                              //Restore previously selected tracks
                                              sf.ui.proTools.trackSelectByName({ names: originalTracks });
                                          
                                          };
                                          
                                          
                                          main();
                                          

                                          Any ideas?

                                          1. samuel henriques @samuel_henriques
                                              2022-08-03 08:56:41.591Z

                                              Hello Jason,
                                              Still works here, the one I had and I tried the one you just posted, they both work the same way.
                                              this is the same behaviour you had when the script looked like this:
                                              Extend all clips by 'x' & Batch Fade using Batch Fade preset (whole timeline) #post-7

                                              @Owen_Granich_Young are you getting this error?

                                              1. I haven't been using it. Mostly Cutting ADR right now, next time I'm in BG mode I'll report back.

                                                1. Jason King @Jason_King
                                                    2022-08-04 21:43:12.807Z

                                                    Doesn't work here. Tried it on my work machine and at my home studio. Although it behaves differently with 25fps & 29.

                                                    1. samuel henriques @samuel_henriques
                                                        2022-08-04 21:45:40.605Z

                                                        Could you check what you get if you run this part of the code, please?

                                                        function getSessionFormat() {
                                                            let sessionSetupWin = sf.ui.proTools.windows.whoseTitle.is("Session Setup").first
                                                            const isSessionSetupOpen = sessionSetupWin.exists
                                                        
                                                            if (!isSessionSetupOpen) {
                                                                sf.ui.proTools.menuClick({ menuPath: ["Setup", "Session"] });
                                                            };
                                                        
                                                            sessionSetupWin = sf.ui.proTools.windows.whoseTitle.is("Session Setup").first
                                                            const sessionFormatGroup = sessionSetupWin.groups.whoseTitle.is("Session Format").first
                                                            const timeCodeRate = +sessionFormatGroup.popupButtons.allItems[2].value.invalidate().value
                                                        
                                                            const sampleRateStaticTextElement = sessionFormatGroup.children.whoseRole.is("AXStaticText").allItems[2].value.invalidate().value.split(' ')[0];
                                                            const sampleRate = Number(sampleRateStaticTextElement) * 1000
                                                        
                                                        
                                                            if (!isSessionSetupOpen) { sf.ui.proTools.menuClick({ menuPath: ["Setup", "Session"] }) };
                                                        
                                                            return { sampleRate, timeCodeRate }
                                                        };
                                                        
                                                        log(getSessionFormat())
                                                        
                                                        1. Jason King @Jason_King
                                                            2022-08-04 22:11:47.369Z
                                                            1. samuel henriques @samuel_henriques
                                                                2022-08-04 22:37:58.126Z2022-08-04 22:50:38.346Z
                                                                1. Jason King @Jason_King
                                                                    2022-08-05 01:44:57.362Z

                                                                    The original or the one just above here?

                                                                    A general question though. Why does the script need sample settings? Can we just make it advance frames?

                                                                    1. Jason King @Jason_King
                                                                        2022-08-05 03:11:45.608Z

                                                                        @samuel_henriques OK. So.

                                                                        It works in a 25fps session. BUT not in 23.97fps session

                                                                        Why does the script need sample settings/session settings? Can't it work just using frames? This making the script faster and also universal.

                                                                        1. samuel henriques @samuel_henriques
                                                                            2022-08-05 10:05:02.267Z

                                                                            Hello Jason,

                                                                            Just updated on my original post: Extend all clips by 'x' & Batch Fade using Batch Fade preset (whole timeline) #post-2

                                                                            This wasn't a thoroughly tested script so some details weren't taken in consideration. What I fixed yesterday was the decimals in the frame rates with decimals (ex.23.976), it was calculating an impossible number for pro tools to understand. Today I found the drop frame options leave the letters df on the value, that needs to be cleaned.

                                                                            Why does the script need sample settings/session settings? Can't it work just using frames? This making the script faster and also universal.

                                                                            The script takes a selection - tc start and tc end - and calculates what is the start minus the frames you input and what is the end plus the frames you input.

                                                                            The script then calculates the frame duration in samples and applies that duration before and after the selection.

                                                                            I could build and timecode calculator to figure what is the start/end timecode plus/minus the number of frames you input, and you would still need to know what frame rate you are in.

                                                                            Unless you want an approximate frames amount to extend, for example decide the frame length is always 1920 samples - witch is only true for 25f 48k session.
                                                                            A frame at 48k, 23.976 is 2002 samples, for example.

                                                                            1. Jason King @Jason_King
                                                                                2022-08-08 01:40:47.839Z

                                                                                Hey @samuel_henriques very interesting.

                                                                                This new code works across 25fps & 29.97fps.

                                                                                Good job!

                                                                                1. Jason King @Jason_King
                                                                                    2022-08-08 21:36:09.578Z

                                                                                    @samuel_henriques do you think it's rock solid now?

                                                                                    1. samuel henriques @samuel_henriques
                                                                                        2022-08-08 23:41:17.517Z

                                                                                        Can't say if it's perfect. But let me know if you find something to improve and I'll try to do it.

                                                                                        1. Jason King @Jason_King
                                                                                            2022-08-09 00:26:11.261Z

                                                                                            Ok cool.

                                                                                            Thanks Samuel

                                                                                            1. Jason King @Jason_King
                                                                                                2022-08-10 01:38:10.632Z

                                                                                                @samuel_henriques is there a way to get the code to not break up clip groups? So the fades created are on any clip groups as well as any single tracks?

                                                                                                This would also speed up the time it takes for the code carry out all its tasks.

                                                                                                1. samuel henriques @samuel_henriques
                                                                                                    2022-08-10 08:53:47.559Z

                                                                                                    I didn't quite get it. Would you like to leave untouched clips or clip groups with fades?

                                                                                                    1. Jason King @Jason_King
                                                                                                        2022-08-10 21:55:16.185Z

                                                                                                        Try it. Group some clips and run the code.

                                                                                                        The script will fade each clip rather than the grouped clips as a whole.

                                                                                                        As you know when you group clips and you use the fade tool to make a fade it fades the whole clip group rather than each clip.

                                                                                                        If you could somehow get the script to address grouped clips like the fade tool does it would run much faster for people who use clip groups. Especially for Backgrounds.

                                                                                                        1. samuel henriques @samuel_henriques
                                                                                                            2022-08-10 23:20:59.139Z

                                                                                                            Got it, you are correct, this script is doing the process for each clip.
                                                                                                            But you would still want to extend the first and last clip, correct?

                                                                                                            1. Jason King @Jason_King
                                                                                                                2022-08-10 23:25:46.424Z

                                                                                                                Yes. How it is working is fantastic. Don't change anything.

                                                                                                                Just wondering if you can add in a feature that if it finds clip groups it fades the clip group rather than the individual clips?

                                                                                                                1. samuel henriques @samuel_henriques
                                                                                                                    2022-08-10 23:42:56.178Z

                                                                                                                    Got it, I'll think about it.

                                                                                                        2. Hey guys, reviving this, it's working, however it's kinda a slow approach, wanted to run an idea by you Sam and see if it could work.

                                                                                                          Instead of going clip by clip, by switching grabber tools you could do the function much faster. No idea if this is possible, I was doing this as 2 separate steps before with manual controls between.

                                                                                                          Idea would be this:

                                                                                                          User highlights selection to be Extend and faded -
                                                                                                          Scripts switches to object grabber and re-selects that whole section.
                                                                                                          When in object grabber Option - and command + will extend all the self contained regions
                                                                                                          Script the switches to Time Grabber (or reselects original selection if they highlighted a larger area)
                                                                                                          Triggers Fader preset 1 (which obviously has to be set correctly as before)

                                                                                                          This is faster because it's not going to every single clip and individually extending them. But I don't know how to get it to reselect with grabber tool or if that's possible at all.

                                                                                                          Video of workflow performed manually attached.
                                                                                                          Thoughts?

                                                                                                          1. samuel henriques @samuel_henriques
                                                                                                              2022-10-21 01:05:40.944Z2022-10-21 08:31:14.829Z

                                                                                                              excellent idea, try this:

                                                                                                              /**
                                                                                                              * @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: 5, fadesPreset: 1 });
                                                                                                              
                                                                                                              1. CLOSE!
                                                                                                                Failing on Line 10 and line 12... different times I run it... need a wait for UI element maybe?

                                                                                                                20.10.2022 18:56:25.14 <info> [Backend]: #StreamDeck: KeyDown (4,2) -> Same Hen Batach Extend and Fade v3
                                                                                                                
                                                                                                                20.10.2022 18:56:25.14 <info> [Backend]: >> Command: Same Hen Batach Extend and Fade v3 [user:cks7wof7200001o102k4hfaq1:cl9hu64t300050110qd6hw6uy]
                                                                                                                
                                                                                                                20.10.2022 18:56:25.29 <info> [Backend]: Mouse current pos is: (1135.98046875, 812.98046875)
                                                                                                                Right-clicking with mouse here: (404, 63)
                                                                                                                
                                                                                                                20.10.2022 18:56:25.30 <info> [Backend]: Moving back...
                                                                                                                
                                                                                                                20.10.2022 18:56:25.30 <info> [Backend]: Position is now: (1135.98046875, 812.98046875)
                                                                                                                
                                                                                                                20.10.2022 18:56:25.32 <info> [Backend]: PopupMenu full role:AXMenu
                                                                                                                
                                                                                                                20.10.2022 18:56:25.32 <info> [Backend]: Clicking popup menu element: Object
                                                                                                                
                                                                                                                20.10.2022 18:56:26.85 <info> [Backend]: Logging error in action (01) ClickButtonAction: ClickButtonAction requires UIElement
                                                                                                                
                                                                                                                20.10.2022 18:56:26.85 <info> [Backend]: !! Command Error: Same Hen Batach Extend and Fade v3 [user:cks7wof7200001o102k4hfaq1:cl9hu64t300050110qd6hw6uy]:
                                                                                                                ClickButtonAction requires UIElement (Same Hen Batach Extend and Fade v3: Line 12)
                                                                                                                
                                                                                                                1. Mojave 10.14.6 PT 2021.12

                                                                                                                2. Jason King @Jason_King
                                                                                                                    2022-10-21 02:05:31.929Z

                                                                                                                    This script above doesn't seem to work for me.

                                                                                                                    1. You can't already be in object grabber (or the batch fade can't trigger), try that Jason. But for me it's still failing at 12, trying to press the preset button for some reason.

                                                                                                                      1. samuel henriques @samuel_henriques
                                                                                                                          2022-10-21 08:32:58.535Z

                                                                                                                          Hey guys, needed a few tweaks.
                                                                                                                          Just updated, please try and let me know how it works for you.

                                                                                                                          1. Line 12 is still sticking for me, but it's still faster then anything else I have to just press 1 and press enter at the end :P

                                                                                                                            I assume its a PT 2021.12 thing...

                                                                                                                            1. samuel henriques @samuel_henriques
                                                                                                                                2022-10-21 18:15:24.410Z

                                                                                                                                try to use the picker on the preset number and replace that line.
                                                                                                                                depending how you do it you might have to add .elementClick();at the end

                                                                                                                                1. My computer also melted yesterday so I eneded up having to upgrade to 2022.9, so this comment may be moot anyways.

                                                                                                                                  @Jason_King did you ever get this version working on your end?

                                                                                                                                  1. Jason King @Jason_King
                                                                                                                                      2022-10-23 21:01:45.182Z2022-10-23 23:16:13.624Z

                                                                                                                                      I've been using the original code above for months now and it saves me a TON of time. I usually select the BG sub (folder) and execute the script so the code works faster as it doesn't have to address each clip one by one; but rather all clips/clip groups. It would be great to be able to select all layers/subgroups and do it all in one pass.

                                                                                                                                      I'll try this new code on Monday. What is the "picker on the preset number"?

                                                                                                                                      But after getting Covid a couple of weeks ago and having to work remotely at home on PT 22.9 & macOS 12.6 the original code above does NOT work at all. It works just fine on PT 21.12.

                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:39.100 <info> [Backend]: #App: Activate "com.avid.ProTools" -> Do Nothing (Swallow Input) [cl5j1q2jb0003jn10hxcd8d58]
                                                                                                                                      #App: Activate "com.avid.ProTools" -> Mini Configs Page [cl5uhfzy5000oga10uono1e41]
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:39.100 <info> [Backend]: [AxDeckInstance] InstanceShow: user:cl5udjfqw0005ga1043cnw6vj:cl5udjnpy0006ga10fnji4ytb:streamDeckHid.BL52K1B02075.1398bc04-c24d-45a5-b9a7-9cda0b0ce641 (Mini Configs Page) Device: 'BL52K1B02075'
                                                                                                                                      [AxDeckInstance] TriggerDraw: user:cl5udjfqw0005ga1043cnw6vj:cl5udjnpy0006ga10fnji4ytb:streamDeckHid.BL52K1B02075.1398bc04-c24d-45a5-b9a7-9cda0b0ce641 (Mini Configs Page) Device: 'BL52K1B02075'
                                                                                                                                      [AxStreamDeckDevice id#1] Device 'BL52K1B02075' -> ShowDeckInstance: user:cl5udjfqw0005ga1043cnw6vj:cl5udjnpy0006ga10fnji4ytb:streamDeckHid.BL52K1B02075.1398bc04-c24d-45a5-b9a7-9cda0b0ce641
                                                                                                                                      [AxStreamDeckDevice id#1] DrawInstance. instance 'user:cl5udjfqw0005ga1043cnw6vj:cl5udjnpy0006ga10fnji4ytb:streamDeckHid.BL52K1B02075.1398bc04-c24d-45a5-b9a7-9cda0b0ce641'
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.28 <info> [Backend]: #StreamDeck: KeyDown (6,3) -> BG Fade Stretcher Copy
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.28 <info> [Backend]: >> Command: BG Fade Stretcher Copy [user:cl5g0p6h3000pzs10l5ghu0h5:cl9hu6g0d0000d310c92wnw8q]
                                                                                                                                      Checking for running apps with bundle 'com.avid.ProTools'
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.28 <info> [Backend]: NSArray.ArrayFromHandle count = 1
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.37 <info> [Backend]: Mouse current pos is: (1048.21875, 364.73828125)
                                                                                                                                      Clicking with mouse here: (13, 60)
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.37 <info> [Backend]: Moving mouse back to: (1048.21875, 364.73828125)
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.38 <info> [Backend]: Position is now: (1048.21875, 364.73828125)
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.41 <info> [Backend]: ProTools version: 21.12.0.97 class: PT2021_6
                                                                                                                                      ProTools processID: 1914
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.41 <info> [Backend]: ProTools version: 21.12.0.97 class: PT2021_6
                                                                                                                                      ProTools processID: 1914
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.65 <info> [Backend]: Mouse current pos is: (1048.21875, 364.73828125)
                                                                                                                                      Right-clicking with mouse here: (405, 63)
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.65 <info> [Backend]: Moving back...
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.66 <info> [Backend]: Position is now: (1048.21875, 364.73828125)
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.67 <info> [Backend]: PopupMenu full role:AXMenu
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:43.67 <info> [Backend]: Clicking popup menu element: Object
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:45.74 <info> [Backend]: Still running another command. Wait for its completion. Cmd received: user:cl5g6muun000uzs10gtijx8qo:cl5g6r1zo000xzs104zfhlp32
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:45.74 <info> [Backend]: Still running another command. Wait for its completion. Cmd received: user:cl5g6muun000uzs10gtijx8qo:cl5g6r1zo000xzs104zfhlp32
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:48.00 <info> [Backend]: Logging error in action (01) WaitForElementAction: Element was not found or removed after waiting 2000 ms
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:48.01 <info> [Backend]: !! Command Error: BG Fade Stretcher Copy [user:cl5g0p6h3000pzs10l5ghu0h5:cl9hu6g0d0000d310c92wnw8q]:
                                                                                                                                      Batch Fades Win Didn't Open. (BG Fade Stretcher Copy: Line 7)
                                                                                                                                          Element was not found or removed after waiting 2000 ms
                                                                                                                                      
                                                                                                                                      << Command: BG Fade Stretcher Copy [user:cl5g0p6h3000pzs10l5ghu0h5:cl9hu6g0d0000d310c92wnw8q]
                                                                                                                                      
                                                                                                                                      24.10.2022 10:13:51.89 <info> [Backend]: [SF_FIREBASE_WS]: Sending keep-alive
                                                                                                                                      

                                                                                                                                      Thats on PT 21.12

                                                                                                2. S
                                                                                                  In reply toJason_King:

                                                                                                  I am trying to sort through this very long thread and understand how it works. Is there a final version of this that works that someone could post. My understanding of this workflow if that, if I've cut BG's through a reel with hard cuts (no fades) on any clips, this will go through all selected tracks and extend the head/tail a specific amount and apply a batch fade preset to each clip. Is that correct? So the fade preset I would need to set would be in the Batch Fades window? And do I select the tracks or do I need to highlight all the clips I want effected?

                                                                                                  1. Hey Steve here's the one I'm using and it's all working.

                                                                                                    /**
                                                                                                    * @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 });
                                                                                                    

                                                                                                    And your understanding of the workflow is correct you will need to make your batchfade preset correct. In my case I want to extend all one frame and drop two frame fades throughout and not mess with existing crossfade lengths so my preset looks like this:

                                                                                                    you highlight a selection of clips in order for it to work on them. Selecting a track only will do nothing.

                                                                                                    Hope that helps!
                                                                                                    Owen

                                                                                                    1. Thanks! I'm getting a consistent error though...line 10. I'm a pretty basic coder so this code is a bit above my head. Not sure how to figure out the error. Any ideas?

                                                                                                      1. Jason King @Jason_King
                                                                                                          2022-10-27 00:11:02.408Z

                                                                                                          As I mentioned above this code doesn't work with PT 21.12.

                                                                                                          AND the original code above works with PT 21.1 but NOT with PT 22.9 (Current).

                                                                                                          1. Ah! Sorry for not seeing that. Well that's a bummer. Anyway, thanks for your quick reply.