Get lenght of current file/selection in Soundly
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?
Kitch Membery @Kitch2025-01-24 03:58:22.901ZHi @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 :-)
- MMartin Wrang @Martin_Wrang
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!
- In reply toKitch⬆:MMartin Wrang @Martin_Wrang
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.483ZHi @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);
Kitch Membery @Kitch2025-01-24 19:59:52.178ZWe 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);