No internet connection
  1. Home
  2. How to

Get lenght of current file/selection in Soundly

By Martin Wrang @Martin_Wrang
    2025-01-23 16:53:54.278Z2025-01-24 18:19:26.090Z

    I'm trying to get Soundflow to read the lenght of the current file or selection in Soundly.
    It is the second field from the left in the picture.

    I want this data for a script that spots between markers in Pro Tools. If the Pro Tools selection is larger than the selection in Soundly it should throw a dialogbox asking whether to spot or not.

    When I try the click UI element method, it is recognised as a UI element, but I just get the value, which will of course change for every file.

    sf.ui.app("com.soundly.Soundly").mainWindow.splitGroups.first.children.whoseRole.is("AXStaticText").whoseValue.is("0:05.52").first
    

    Any ideas if this is possible currently? Or any chances of getting tighter integration with Soundly?

    • 5 replies
    1. Kitch Membery @Kitch2025-01-24 03:58:22.901Z

      Hi @Martin_Wrang,

      I assume you mean the second text field from the left (not right)? The one whose value is "0:05.52".

      Finding this data should be fairly straightforward. So if that's the text field's value you want let me know :-)

      1. MMartin Wrang @Martin_Wrang
          2025-01-24 11:35:42.878Z

          Hi Kitch

          Yes I do mean the left. I don’t know how to get the title of the element. Your help would be much appreciated!

          1. In reply toKitch:
            MMartin Wrang @Martin_Wrang
              2025-01-24 11:53:15.320Z

              Just found the solution in an old video of yours @ 2:50.

              Can one change between the “x static text” and ‘first with static text y’ options inside of the script editor? I always use the UI element picker in the editor, rather than have to create a macro and then copy it as JavaScript.

            • In reply toMartin_Wrang:
              Kitch Membery @Kitch2025-01-24 19:41:49.058Z2025-01-24 20:01:45.483Z

              Hi @Martin_Wrang,

              To help you and the community create more robust scripts, I've put together a video of how I would approach what you're after using the UI Picker. I hope it helps.

              Here is the final script for getting the value :-)

              const soundly = sf.ui.app("com.soundly.Soundly");
              const mainWindow = soundly.mainWindow;
              const firstSplitGroup = mainWindow.splitGroups.first;
              const textFields = firstSplitGroup.children.whoseRole.is("AXStaticText");
              
              const timeTextFields = textFields.filter(tf =>
                  [":", "."].every(character => tf.value.value.includes(character))
              ).map(tf => tf.value.value);
              
              const targetTimeValue = timeTextFields[timeTextFields.length - 1];
              
              log(targetTimeValue);
              
              1. Kitch Membery @Kitch2025-01-24 19:59:52.178Z

                We could also use regex to be more explicit, like this. :-)

                const soundly = sf.ui.app("com.soundly.Soundly");
                const mainWindow = soundly.mainWindow;
                const firstSplitGroup = mainWindow.splitGroups.first;
                const textFields = firstSplitGroup.children.whoseRole.is("AXStaticText");
                
                // Regex description.
                // ^ - Asserts the start of the string, ensuring no characters come before the match.
                // \d* - Matches zero or more digits (this allows for flexibility in the number of digits before the colon, e.g., "0:", "12:", "123:").
                // : - Matches a literal colon, which separates the minutes and seconds.
                // \d{2} - Matches exactly two digits, representing the seconds part.
                // \. - Matches a literal period, which separates the seconds and fractions of a second.
                // \d{2} - Matches exactly two digits, representing the fractional seconds.
                // $ - Asserts the end of the string, ensuring no characters come after the match.
                const regex = /^\d*:\d{2}\.\d{2}$/;
                
                const timeTextFields = textFields.filter(tf =>
                    tf.value.value.match(regex)
                ).map(tf => tf.value.value);
                
                
                const targetTimeValue = timeTextFields[timeTextFields.length - 1];
                
                log(targetTimeValue);