I have a functional AppleScript for a complex workflow. Parts of it were professionally done and due to recent changes, I added in my own portions. Those parts are mainly tell application finder and do shell commands. I have to add delays or display dialog to verify the steps are done before moving on. I will be tackling this one at a time, so I wanted to start with what I think will be the easiest.
This opens a new WAV file with Levelator. The app launches, does its thing and then the script moves on. I want to add some smarts. When *.output.wav finally shows up in the folder wait 10 seconds, close Levelator and move on. I don’t know how to monitor a folder for a new file and I don’t know how to get the Process ID for the app finder launched (if that is even the right approach).
Sorry I am new so I may have pasted this code in wrong.
Here is the code I am dealing with:
-- LEVELATOR ---
set fullWav to localTempDir & getCurrentTimestamp("ymd", "") & "_FULL.wav"
set leveledWav to localTempDir & getCurrentTimestamp("ymd", "") & "_FULL.output.wav"
tell application "Finder"
open file fullWav using ((path to applications folder as text) & "Levelator.app")
end tell
-- HELP don't know when the file is complete and would like to close the app. Levelator does add the file to the folder at the last second so we could check for that wait 10 and move on.
delay 120
If Levelator is writing out to a file at that path, then it’s added to the folder immediately. Finder may take some time before updating the visual representation shown to you of what the folder contains, but it’s definitely there. (This won’t necessarily be the case if Levelator writes out to a swap file initially—which is a technique used to prevent loss of data if the process does get interrupted—as it will wait until completing the write before moving the file to its final location.)
Let’s assume it’s not using swap files. Then the issue of determining whether a file has finished being written out to is a well-established problem that interestingly hasn’t got a single, simple, or foolproof solution unless you happen to have low-level filesystem access and can distinguish between file handles that are open versus those that have been closed (although this also isn’t a very good solution, as a file can have more than one handle to it at any one time, but there’s also nothing stopping a new handle being opened immediately after the last one was closed).
A Solution
So, yes, one method you alluded to could be to monitor the file, polling for something that can indicate whether the file is still being changed or not, e.g. file size, modification date, etc. This is along the lines of what macOS folder actions does, which isn’t what you’d necessarily expect from a built-in feature of the system, but it probably illustrates that what seems like a simple problem to solve doesn’t necessarily mean it’s simple to solve at any level. But, folder actions is probably the technology that I’d choose to leverage in this situation.
If you’re not aware of folder actions, in their simplest form, they are a single AppleScript that is attached to a one or more folders with a specialised handler that responds to a specific event occurring on those folders There’s only about four events that can be catered to, but one of them will trigger the handler called adding folder items to, which is called after the folder detects it has had a new file (or folder) added to its contents, or a group of files (and/or folders) added to its contents performed as a singular operation. It will only call the handler at the point when it believes that any writing to or updating of the file has been completed.
It won’t be a perfect solve in every possible scenario that might arise, but it will be good enough for over 99% of them, and unequivocally better than relying on an arbitrary delay.
This isn’t optimal, but making it optimal is very easy.
In a new, separate script, run the following command:
the id of the application named "Levelator"
This will return a string similar to "com.company.Levelator", which is the bundle identifier for the Levelator application.
Copy the returned bundle identifier, then replace† that portion of your script above in your original script with the following:
tell application "Finder" to open the file fullWav ¬
using application file id "com.company.Levelator"
This is assuming that simply asking Levelator itself to open the file doesn’t work, which a short time ago, almost certainly would have, but nowadays, seems lot less likely to:
tell the application named "Levelator" to open (my alias named fullWav)
or †
tell application id "com.company.Levelator" to open (my alias named fullWav)
†Obviously, substituting “com.company.Levelator” for Levelator’s actual bundle identifier.
I found the location of where The Levelator stores temp files
/private/var/tmp/tmp.(random number).wav
So if we can look for when the output shows up (date).output.wav in localTempDir
We could create a loop that senses that file ADD and then use your ID of application to find a way to kill the id later right? The code I included above works without the Bundle ID (at least on Mojave) I will be testing on newer system next week.
FYI the new script only code returned “org.conversationsnetwork.levelator”
set fullWav to "Macintosh HD:test.wav"
tell application "Finder" to open the file fullWav using application id “org.conversationsnetwork.levelator”
-- Thats all one line above
Returns an error when trying to save or run a test script.
Syntax Error
Expected end of line, etc. but found unknown token.
The script editor highlights the " in front of org.
So lets see if we can tackle the file is created so it is ok to quit portion.
I did get an error using CJK code (included in sample with error). We can deal with that later, but how to I check a folder for the *.output.wav file, wait 10 sec then quit the app?
set localTempDir to "ext-Trooper:MP3Tagging"
set fullWav to localTempDir & ":test.wav"
(*
tell application "Finder" to open the file fullWav ¬
using application id "org.conversationsnetwork.levelator"
-- Returns error Script Error - Finder got an error: Can’t make application "Levelator" into type application file.
*)
tell application "Finder"
open file fullWav using ((path to applications folder as text) & "Levelator.app")
end tell
delay 120
tell application "Levelator" to if it is running then quit
Thank you. That got me past that error, but showed me a new error in with:
tell application "Finder" to open the file fullWav ¬
using application id "org.conversationsnetwork.levelator"
-- Returns error Script Error - Finder got an error: Can’t make application "Levelator" into type application file.
Thank you all for your help. I got a solution, unless you want to find out why I get the error from:
tell application "Finder" to open the file fullWav ¬
using application id "org.conversationsnetwork.levelator"
-- Returns error Script Error - Finder got an error: Can’t make application "Levelator" into type application file.
Here is my final section:
-- LEVELATOR ---
set localTempDir to "ext-Trooper:WavsToProcess"
set fullWav to localTempDir & ":test.wav"
tell application "Finder"
open file fullWav using ((path to applications folder as text) & "Levelator.app")
end tell
tell application "System Events"
repeat until (exists (files of folder localTempDir whose name contains ".output"))
delay 10
end repeat
-- extra small delay just in case we pickup file before it finishes copy
delay 10
end tell
tell application "Levelator" to if it is running then quit
I will need help with some do shell commands which I will post separately.
The open command requires an application file. What you are providing it is an application object. (see open’s parameters/using below from Finder dictionary)
If you select an application in the Finder and run just this line in script editor:
tell application "Finder" to selection
You should get a result like this:
{application file "Fission.app" of folder "Applications" of folder ¬
"username" of folder "Users" of startup disk of application "Finder"}
So, to flesh it out… this works for me:
set fullWav to POSIX file ¬
"/Users/username/Documents/audio/audioclip.wav" as «class furl» as text
tell application "Finder" to open the file fullWav using ¬
(application file "Fission.app" of folder "Applications" of folder ¬
"username" of folder "Users" of startup disk of application "Finder")
open
open (verb)
Open the specified object(s) (from Standard Suite)
Thank you. I will play with that. I was just sharing that I got an error from CJK response and thought it might be related to my current system Mojave.