i have a program for converting videos from youtube using ffmpeg, and it downloads the videos using curl. on the progress window i have a cancel button, so i’m trying to figure out how to check if curl or ffmpeg is running and then cancel the process.
First, in order to be able to actually push the cancel button, you need to have curl return control to your application before curl completes its task. Normally your application will wait for a response from the do shell script call before it proceeds onto the next command in your app. So to do that you need to add something to your shell script call. You do that by adding “> /dev/null 2>&1 &” to the end of your command. The > /dev/null redirects the process’ stdout to /dev/null (you can use some other file path if you want to capture its output). 2>&1 redirects stderr to the same place as stdout (in this case, /dev/null) and the trailing & sends the process to the background.
For example run this applescript. It starts a sleep command using a call to the shell. Normally the script will wait 5 seconds before beeping, but you we told the command to return a response immediately so in applescript the beep happens right away.
do shell script "/bin/sleep 5 > /dev/null 2>&1 &"
beep
Now if you want to be able to kill (cancel) the process then you need to know the process id (pid) of it. You can get that when you call the command with “echo $!”
set the_pid to do shell script "/bin/sleep 5 > /dev/null 2>&1 & echo $!"
beep
the_pid
To check if the process is running or not… If “” is returned then the process is finished. If the pid number is returned then the process is still running.
set the_pid_answer to do shell script "ps ax | grep " & the_pid & " | grep -v grep | awk '{ print $1 }'"
and finally, to kill the process…
do shell script "kill " & the_pid
wow, thanks, i already had it writing the output to a file, that’s how i got the progress.but i have one more question…how do i make my app kill what it is doing. my code is like this
on clicked theObject
if theObject's name is "convert" then
--convert the video
else if theObject's name is "abort" then
--kill curl and ffmpeg
end if
end clicked
in the abort part, when abort is clicked i want it to cancel what is going on in the convert part.
thanks.
In the convert part you have to get the pid when you run your shell script command. Then in the abort part you check for the pid and if it exists then you kill it… using the code I supplied.
yeah i know how to kill the shell scripts, but i want to know how to kill everything else that goes on in that part of the code.
It sounds to me like you have 2 shell commands running in that part, 1) the curl command and 2) something with ffmpeg. Maybe I’m not understanding but wouldn’t this work…
– in convert part
set curl_pid to do shell script “curl commands” & " > /dev/null 2>&1 & echo $!"
set ffmpeg_pid to do shell script “ffmpeg commands” & “> /dev/null 2>&1 & echo $!”
– in abort part
do shell script "kill " & curl_pid
do shell script "kill " & ffmpeg_pid
yes i know, i have that. But the shell scripts arent the only things that happen when you click convert. the shell scripts write their outputs to 2 different files. when i click abort, it kills the shell scripts and delete those files. Then later on in the convert part of the script it accesses those files, and i get an error. So i want the abort button to cancel the shell scripts (done already) AND stop whatever is happening in the convert part of the script.
Well without knowing what else is happening it’s hard to give you advice. The part that errors if the files are missing… can’t you just put that in an if/then statement and check for the existence of the files before proceeding into that code? Or a try/on error block? Or if you’re in the middle of a repeat loop then you could set a variable to true/false. When it’s true you continue in the loop, and when it’s false you exit the repeat loop. You could set the true/false of that variable in the abort part of your code.
ok, the converting part is in a repeat loop, so i cane set a varibale to true when abort is cliked and make it global, but how would i use that to exit the repeat loop. would i just have to put this every other line?
if theAbort is true then exit repeat
Every other line doesn’t make sense. Just put the code in a try/on error block, so if it errors it stops executing the rest of the code and then the next loop will start. So the first line of the repeat loop would perform the check and exit the loop if you aborted.
Or place your code in sections according to what operation is being performed, and check on a section-by-section basis.
so like this?
try
if theAbort is true then exit repeat
--convert video....
end try
Or even a better idea then using a true/false variable is to use the code I supplied originally…
set the_pid_answer to do shell script “ps ax | grep " & the_pid & " | grep -v grep | awk ‘{ print $1 }’”
if the_pid_answer is “” then exit repeat
Try this…
set the_pid_answer to do shell script “ps ax | grep " & the_pid & " | grep -v grep | awk ‘{ print $1 }’”
if the_pid_answer is “” then exit repeat
try
– your code
end
i have to use the true or false because it’s not always doing a shell script. i tired what you said, and i still got the same error, so it’s not aborting.
are you sure there’s no way for it to just exit the on clicked handler?
Well, if you’re seeing an error then the error isn’t from the code within the try block because that won’t show an error. If the error occurs inside the try block it just ignores the error and exits the try block. Have you declared your true/false variable a property? In other words you first have to give it a value when your program launches, otherwise you will get an error because the variable doesn’t exists yet.
try…
property theAbort : false
yeah, i had that, and still it didnt work.
bump