Hey there,
I'm wondering if it's at all possible to get the file location of the selected (or even better, multiple selected) audio clips in the Logic timeline window, by pointing to it's source file from the Audio Files folder?
I'm aware there's a 'Show in Finder' button which could probably be macro'd, but is there a simple way of just getting the selected audio file's location without having to go through finder?
Thanks!
Nick
- Kitch Membery @Kitch2025-05-27 18:49:35.234Z
Hi @Yarnak
Unfortunately, the names of clips in the timeline do not always match the actual audio file's path name(s).
However, if you have a single selected audio clip in the timeline, you can get the file path from the project browser, with this script...
const logic = sf.ui.logic; logic.appActivate(); const projectBtn = sf.ui.logic.mainWindow.radioGroups.first.radioButtons.whoseDescription.is("Project").first; if (!projectBtn.exists) { logic.menuClick({ menuPath: ["View"] }); logic.menuClick({ menuPath: ["View", "Show Browsers"] }); } sf.waitFor({ callback: () => { sf.ui.logic.mainWindow.invalidate(); const btnCount = sf.ui.logic.mainWindow.radioGroups.first.radioButtons.length === 2 const projectBtnExists = sf.ui.logic.mainWindow.radioGroups.first.radioButtons.whoseDescription.is("Project").first.exists; const allFilesBtnExists = sf.ui.logic.mainWindow.radioGroups.first.radioButtons.whoseDescription.is("All Files").first.exists; return btnCount && projectBtnExists && allFilesBtnExists; }, timeout: 1000, }); projectBtn.elementClick(); let filePathComponents = []; const projectGroup = logic.mainWindow .groups.allItems[4] .groups.whoseDescription.is("Project").first; projectGroup.elementWaitFor(); const pathList = projectGroup .children.whoseRole.is("AXList") .whoseDescription.is("Path").first; const pathItems = pathList.childrenByRole("AXStaticText"); if (pathItems.length <= 0) throw `No file path available`; pathItems.forEach(pathItem => { const segment = pathItem.value.value; if (segment) filePathComponents.push(segment); }); const filePath = "/" + filePathComponents.join("/"); log(filePath);
- YNick Rose @Yarnak
Hey @Kitch
Thanks a bunch for this. This looks great, but I'm getting an error that seems to relate to the Project Browser menu:
Element was not found or removed after waiting 2000 ms (Line 33)
I also tried replacing line 33 with an sf.wait to test out the result, but it seems each time it returns 'No file path available'.
Sorry I'm not super codey and couldn't tell you if that relates to Project Browser bit, but I really appreciate if you have any ideas?
Thank you for all the help
NickKitch Membery @Kitch2025-05-27 19:13:26.211Z
Hi @Yarnak
This will only work if you have a single clip selected in the timeline.
Does it work if that is the case?
- YNick Rose @Yarnak
Hey @Kitch
Yeah, this is just with a single clip selected. It brings up the Project Browser and seems to identify the clip correctly though which is good.
Kitch Membery @Kitch2025-05-27 19:19:30.184Z
Hi @Yarnak
I see... Here is an improved version that does not rely on the index of the project browser group.
const logic = sf.ui.logic; logic.appActivate(); const projectBtn = sf.ui.logic.mainWindow.radioGroups.first.radioButtons.whoseDescription.is("Project").first; if (!projectBtn.exists) { logic.menuClick({ menuPath: ["View"] }); logic.menuClick({ menuPath: ["View", "Show Browsers"] }); } sf.waitFor({ callback: () => { sf.ui.logic.mainWindow.invalidate(); const btnCount = sf.ui.logic.mainWindow.radioGroups.first.radioButtons.length === 2 const projectBtnExists = sf.ui.logic.mainWindow.radioGroups.first.radioButtons.whoseDescription.is("Project").first.exists; const allFilesBtnExists = sf.ui.logic.mainWindow.radioGroups.first.radioButtons.whoseDescription.is("All Files").first.exists; return btnCount && projectBtnExists && allFilesBtnExists; }, timeout: 1000, }); projectBtn.elementClick(); let filePathComponents = []; const projectGroup = logic.mainWindow .groups.filter(g => g.groups.whoseDescription.is("Project").exists)[0] .groups.whoseDescription.is("Project").first; projectGroup.elementWaitFor(); const pathList = projectGroup .children.whoseRole.is("AXList") .whoseDescription.is("Path").first; const pathItems = pathList.childrenByRole("AXStaticText"); if (pathItems.length <= 0) throw `No file path available`; pathItems.forEach(pathItem => { const segment = pathItem.value.value; if (segment) filePathComponents.push(segment); }); const filePath = "/" + filePathComponents.join("/"); log(filePath);
Let me know if that works for you.
- YNick Rose @Yarnak
Ahh. This one works perfectly, thank you Kitch!
Kitch Membery @Kitch2025-05-29 16:43:28.849Z
Nice. I’m glad that fixed the issue.
Rock on!