No internet connection
  1. Home
  2. How to

Save a session with timecode stamp in name

By Danny @Danny_van_Spreuwel
    2022-02-08 13:07:36.489Z2022-03-13 09:52:09.411Z

    During mixing i'm using save copy in with the current timecode as an indiciator to where this session is progressed. Very usefull when restoring lost data. ("the write to all nightmare") I want to automate this. At the moment i tried a lot of key press actions. With no succes.

    This should be the workflow:

    • Get current timecode
    • Save a session copy with the timecode as text at the end (and lose the "Copy of" prefix)

    The "save a new version" macro comes close.

    Any ideas how to tackle this one?

    The solution got a bonus feature. It is now a template. You can choose whether to add the timecode or a user value to the end of your saved session name.

    Solved in post #10, click to view
    • 20 replies

    There are 20 replies. Estimated reading time: 17 minutes

    1. Danny @Danny_van_Spreuwel
        2022-02-11 16:02:58.974Z

        What could help if the "Copy of .. session" name can be changed. The new alterted name can then be pasted into the text field of the Save Copy In window. What the new name need to be is strip of the "Copy Of [space]" prefix, add TC t the end and add the copied TC from the clipboard.

        1. Raphael Sepulveda @raphaelsepulveda2022-02-11 20:10:42.721Z2022-02-12 19:11:49.701Z

          @Danny_van_Spreuwel, give this a try.

          Change the savePath at the end of the script to whatever you'd like, in this example, I'm just putting it in the Downloads folder.

          Also, I'm not sure what settings you prefer to have on the Save Copy In window, so I just enabled the Audio Files checkbox. Let me know if you need help customizing that more.

          Finally, since ":" are not supported in macOS filenames, you'll notice they'll get replaced with "-" in the timecode part of the filename.

          Hopefully, that helps!

          /** @param {{ savePath: string, newSessionName: string }} args */
          function saveCopyIn({ savePath, newSessionName }) {
              const saveCopyInWin = sf.ui.proTools.windows.whoseTitle.is('Save Copy In...').first;
          
              sf.ui.proTools.menuClick({ menuPath: ['File', 'Save Copy In...'] });
              saveCopyInWin.elementWaitFor({ waitType: "Appear", });
          
              saveCopyInWin.buttons.whoseTitle.is('OK').first.elementClick();
              saveCopyInWin.elementWaitFor({ waitType: "Disappear", });
          
              // Save Window
              const saveWin = sf.ui.proTools.windows.whoseTitle.is("Save").first;
              const saveWinSheet = saveWin.sheets.first;
          
              saveWin.elementWaitFor();
          
              // Open the "Go to the folder" sheet
              sf.keyboard.press({ keys: 'slash' });
              saveWinSheet.elementWaitFor();
          
              // Set the path to the sessions folder
              saveWinSheet.comboBoxes.first.value.value = savePath;
          
              // Click 'Go'
              saveWinSheet.buttons.whoseTitle.is("Go").first.elementClick();
              saveWinSheet.elementWaitFor({ waitType: 'Disappear' });
          
              // Set name of Save Copy In Session
              saveWin.textFields.first.elementSetTextFieldWithAreaValue({
                  value: newSessionName
              });
          
              // Click 'Save' and wait for window to dissapear 
              saveWin.buttons.whoseTitle.is("Save").first.elementClick();
              saveWin.elementWaitFor({ waitType: 'Disappear' });
          
              sf.ui.proTools.waitForNoModals();
          }
          
          function saveCopyInAndAppendTimecodeInFilename() {
              sf.ui.proTools.appActivateMainWindow();
              sf.ui.proTools.mainWindow.invalidate();
          
              const sessionPath = sf.ui.proTools.mainWindow.invalidate().sessionPath;
              const sessionParentPath = sessionPath.split("/").slice(0, -1).join("/");
              const sessionName = sessionPath.split("/").slice(-1)[0].split(".")[0];
          
              let currentTimecode;
          
              sf.ui.proTools.mainCounterDoWithValue({
                  targetValue: "Timecode",
                  action: () => currentTimecode = sf.ui.proTools.getCurrentTimecode().stringValue
              });
          
              saveCopyIn({
                  savePath: function () {
                      const savePath = `${sessionParentPath}/Session File Snapshots`;
          
                      if (!sf.file.directoryExists({ path: savePath }).exists) {
                          sf.file.directoryCreate({ path: savePath });
                      }
                      return savePath;
                  }(),
                  newSessionName: `${sessionName}_TC${currentTimecode}`,
              });
          }
          
          saveCopyInAndAppendTimecodeInFilename();
          
          1. Danny @Danny_van_Spreuwel
              2022-02-12 10:45:41.786Z

              Like magic! Raphael, thank you for your code (again). This is a great start. Would you convert the script with these changes:

              • The savePath is the same as the current Pro Tools session with a folder called "Session File Snapshots". Extra bonus: if the folder does not exist it needs to be created.
              • The included Audio Files checkbox can be unchecked. Just the Pro Tools session will be saved.
              • The new name ends "_TChh-mm-ss-ff" (e.g. TC01-34-00-12).

              Update: With my little knowledge of JavaScript I converted the naming:

              return `${sessionName}_TC${currentTimecode}
              
              1. No problem! Just updated the script above with the changes.

                1. Danny @Danny_van_Spreuwel
                    2022-02-12 19:51:35.082Z

                    Absolutely loving this. Another time saving script. Thank you for all your work and helping me out with this!

                    1. My pleasure!

                2. Danny @Danny_van_Spreuwel
                    2022-03-11 09:24:29.990Z

                    @raphaelsepulveda I like to take the script a bit further. An option to have a suffix as a template.

                    Property:
                    Suffix

                    Values:
                    TC
                    User value

                    I know how to make the template. I'm missing some JavaScript programming to decide witch suffix naming to use.

                    If event.props.suffix = "TC" then sessionName + "TC {currentTimecode} else sessionName + "{event.props.suffix}"

                    Can you help me out to write this peace of code?

                    1. Yeah! I'll have some time later in the weekend to get this done for ya. I'll report back when I do!

                      1. @Danny_van_Spreuwel, this should do!

                        Set up your template to look like this and the code below takes care of the rest:

                        const { suffix, userValue } = event.props;
                        
                        /** @param {{ savePath: string, newSessionName: string }} args */
                        function saveCopyIn({ savePath, newSessionName }) {
                            const saveCopyInWin = sf.ui.proTools.windows.whoseTitle.is('Save Copy In...').first;
                        
                            sf.ui.proTools.menuClick({ menuPath: ['File', 'Save Copy In...'] });
                            saveCopyInWin.elementWaitFor({ waitType: "Appear", });
                        
                            saveCopyInWin.buttons.whoseTitle.is('OK').first.elementClick();
                            saveCopyInWin.elementWaitFor({ waitType: "Disappear", });
                        
                            // Save Window
                            const saveWin = sf.ui.proTools.windows.whoseTitle.is("Save").first;
                            const saveWinSheet = saveWin.sheets.first;
                        
                            saveWin.elementWaitFor();
                        
                            // Open the "Go to the folder" sheet
                            sf.keyboard.press({ keys: 'slash' });
                            saveWinSheet.elementWaitFor();
                        
                            // Set the path to the sessions folder
                            saveWinSheet.comboBoxes.first.value.value = savePath;
                        
                            // Click 'Go'
                            saveWinSheet.buttons.whoseTitle.is("Go").first.elementClick();
                            saveWinSheet.elementWaitFor({ waitType: 'Disappear' });
                        
                            // Set name of Save Copy In Session
                            saveWin.textFields.first.elementSetTextFieldWithAreaValue({
                                value: newSessionName
                            });
                        
                            // Click 'Save' and wait for window to dissapear 
                            saveWin.buttons.whoseTitle.is("Save").first.elementClick();
                            saveWin.elementWaitFor({ waitType: 'Disappear' });
                        
                            sf.ui.proTools.waitForNoModals();
                        }
                        
                        function main() {
                            if (suffix === "User Value" && userValue === undefined) throw 'No User Value was passed in template.'
                        
                            sf.ui.proTools.appActivateMainWindow();
                            sf.ui.proTools.mainWindow.invalidate();
                        
                            const sessionPath = sf.ui.proTools.mainWindow.invalidate().sessionPath;
                            const sessionParentPath = sessionPath.split("/").slice(0, -1).join("/");
                            const sessionName = sessionPath.split("/").slice(-1)[0].split(".")[0];
                        
                            const newSessionName = function () {
                                if (suffix === 'TC') {
                                    let currentTimecode;
                        
                                    sf.ui.proTools.mainCounterDoWithValue({
                                        targetValue: "Timecode",
                                        action: () => currentTimecode = sf.ui.proTools.getCurrentTimecode().stringValue
                                    });
                        
                                    return `${sessionName}_TC${currentTimecode}`;
                                }
                        
                                if (suffix === 'User Value') {
                                    return `${sessionName}_${userValue}`;
                                }
                            }();
                        
                            saveCopyIn({
                                savePath: function () {
                                    const savePath = `${sessionParentPath}/Session File Snapshots`;
                        
                                    if (!sf.file.directoryExists({ path: savePath }).exists) {
                                        sf.file.directoryCreate({ path: savePath });
                                    }
                                    return savePath;
                                }(),
                                newSessionName,
                            });
                        }
                        
                        main();
                        
                        Reply1 LikeSolution
                        1. Danny @Danny_van_Spreuwel
                            2022-03-13 09:50:10.823Z

                            YES YES YES! Thank you so much. It looks like an ease when you do this. I tried it myself but didn't work out. You even added an error handler. You use be a pro coder.

                            1. Awesome!

                              Thanks for the kind words. Definitely not a pro coder but have learned a lot from the great people in this forum!

                    2. Danny @Danny_van_Spreuwel
                        2022-05-27 16:54:02.985Z

                        @raphaelsepulveda

                        Hi Raphael,

                        I switched to a M1 machine with Monterey. Now our nice macro got stuck on the target path. I think that element has been changed in this new OS. See log output in the image. Do you have Monterey to be able to fix this element?

                        1. Hey @Danny_van_Spreuwel!

                          Ah yes, I know that in Monterey they changed that window completely. Unfortunately, I'm still in Catalina.

                          @Kitch, is one of your computers in Monterey? If so, could you take a look at this? This post seems to have a way to deal with it but I can't test it to make sure it works in this context. The full script for Danny is the one marked as the solution in this thread.

                          1. Kitch Membery @Kitch2022-05-27 19:54:52.847Z

                            Hi @raphaelsepulveda!

                            I'll take a look at it this afternoon.

                            Rock on!

                            1. Kitch Membery @Kitch2022-05-27 20:16:07.908Z

                              @Danny_van_Spreuwel & @raphaelsepulveda,

                              Try replacing the saveCopyIn function with this one, legends;

                              /** @param {{ savePath: string, newSessionName: string }} args */
                              function saveCopyIn({ savePath, newSessionName }) {
                                  const saveCopyInWin = sf.ui.proTools.windows.whoseTitle.is('Save Copy In...').first;
                              
                                  sf.ui.proTools.menuClick({ menuPath: ['File', 'Save Copy In...'] });
                                  saveCopyInWin.elementWaitFor({ waitType: "Appear", });
                              
                                  saveCopyInWin.buttons.whoseTitle.is('OK').first.elementClick();
                                  saveCopyInWin.elementWaitFor({ waitType: "Disappear", });
                              
                                  // Save Window
                                  const saveWin = sf.ui.proTools.windows.whoseTitle.is("Save").first;
                                  const saveWinSheet = saveWin.sheets.first;
                              
                                  saveWin.elementWaitFor();
                              
                                  // Open the "Go to the folder" sheet
                                  sf.keyboard.press({ keys: 'slash' });
                                  saveWinSheet.elementWaitFor();
                              
                                  // Set the path to the sessions folder
                                  if (saveWinSheet.comboBoxes.first.exists) {
                                      saveWinSheet.comboBoxes.first.value.value = savePath;
                              
                                      // Click 'Go'
                                      saveWinSheet.buttons.whoseTitle.is("Go").first.elementClick();
                                  } else {
                                      saveWinSheet.textFields.first.value.value = savePath;
                              
                                      sf.keyboard.press({ keys: 'return' });
                                  }
                              
                                  saveWinSheet.elementWaitFor({ waitType: 'Disappear' });
                              
                                  // Set name of Save Copy In Session
                                  saveWin.textFields.first.elementSetTextFieldWithAreaValue({
                                      value: newSessionName
                                  });
                              
                                  // Click 'Save' and wait for window to dissapear 
                                  saveWin.buttons.whoseTitle.is("Save").first.elementClick();
                                  saveWin.elementWaitFor({ waitType: 'Disappear' });
                              
                                  sf.ui.proTools.waitForNoModals();
                              }
                              

                              Note: @raphaelsepulveda I have not checked it on my non Monterey rig but let me know if this new function works for you also. (The logic looks sound and has not changed but I've not tested it.)

                              Rock on!

                              1. Yessir, still works in Catalina! Thank you!!

                                1. Kitch Membery @Kitch2022-05-27 20:26:27.915Z

                                  Wooo!!! Hopefully it works for @Danny_van_Spreuwel!

                                  1. Danny @Danny_van_Spreuwel
                                      2022-05-30 09:17:07.452Z

                                      Thank you Kitch for your time and repair!

                                      The "done" version works. When using the "TC" workflow it got stuck on Line 38 (counting in the full script, see screenshot).

                                      1. Danny @Danny_van_Spreuwel
                                          2022-05-30 19:05:31.254Z

                                          Strange. I tried after awhile and now it works. I'll keep on using this function and w'll see if it was an unlucky shot at the beginning.

                                          1. Kitch Membery @Kitch2022-05-30 19:06:23.891Z

                                            Great to hear! :-)