Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2019-04

How to use RunCommandIndir() in a thread?

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bo Berglund

I havr written a wrapper for some ffmpeg functions to make them easier to work with.
However, some of the functions are rather longish so the GUI application gets unresponsive...
I would like to fix this perhaps by running the commands inside a thread, but I don't really know how that can be done... RunCommandIndir() is a command line interface I use to start ffmpeg with selected arguments.
I would like to implement some solution that puts the RunCommandIndir() call into a thread so the main application could for instance show a running clock and have a button to interrupt the task if it turns out to be too long.
Any suggestions on how to do this?`
Or is there already a threaded version of RunCommandIndir() somewhere?

I use Fpc 3.0.4 and Lazarus 2.0.0 on Windows 7 and Ubuntu Linux to compile for both environments.

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Bo Berglund
Bo Berglund wrote 18 lines
I havr written a wrapper for some ffmpeg functions to make them easier to work with. However, some of the functions are rather longish so the GUI application gets unresponsive... I would like to fix this perhaps by running the commands inside a thread, but I don't really know how that can be done... RunCommandIndir() is a command line interface I use to start ffmpeg with selected arguments. I would like to implement some solution that puts the RunCommandIndir() call into a thread so the main application could for instance show a running clock and have a button to interrupt the task if it turns out to be too long. Any suggestions on how to do this?` Or is there already a threaded version of RunCommandIndir() somewhere? I use Fpc 3.0.4 and Lazarus 2.0.0 on Windows 7 and Ubuntu Linux to compile for both environments.

I found a webpage describing basically the same as I am looking for: https://www.sigmdel.ca/michel/program/fpl/yweather/process_thread_en.html However this uses a TProcess object and I don't think that the call I am making (RunCommandIndir) will work in the Execute loop...

He has the following in Execute():

...
var PlayProc: TProcess;
begin PlayProc := TProcess.create(nil);
  try
    PlayProc.executable := 'aplay';
    PlayProc.parameters.add(FFilename);
    PlayProc.Options := [poNoConsole];
    PlayProc.execute; // <== Will this really return before done?
    while PlayProc.Running do  // If not then we will not get here....
    begin
      if StopPlay or AppClosing then
      begin
        if StopPlay or FTerminateProcess then
          PlayProc.terminate(1);
        exit;
      end
      else
        sleep(1);
    end;
  finally
....

Seems like if one places a blocking call to a lengthy process in Execute() then one loses the ability to interrupt the running process, right?

So how could it be done instead?

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Bo Berglund
Bo Berglund wrote
PlayProc.execute; // <== Will this really return before done?

Just checked and it will unless the poWaitOnExit option is speciufied. One can use a call to Running in the loop toi check if it is still active.

So I guess if I adapt my code to use a TProcess object instead of the RunCommandInDir() call I could run it in a thread?

Bo Berglund Developer in Sweden

Reply by email

Michael Thompson
to Bo Berglund

G'day,

Sorry for not replying earlier, I'm under the run multiple ffprobe calls, each in their own thread. I can report there is no problem. So ffprobe itself is threadsafe. I also use a (Lazarus) app called dmMediaConverter that calls ffmpeg in threads to convert video, so again ffmpeg is threadsafe.

I use TProcess directly. It will be a day or two, but I can flick you through the code that sets up my TProcess, and I put together something on my thread logic.

I can tell you that I have only ever written one threaded app in my life - and that was to thread ffprobe. The whole thing was much easier to develop than I thought. For resources I used the wiki, but mainly the Example Programs that ship with Lazarus.

Apologies for the lack of actual info here.

Mike
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20190416/4f19906d/attachment.html>

Reply by email

Bo Berglund
to Michael Thompson
Michael Thompson wrote
Sorry for not replying earlier, I'm under the 't be sorry! This is a peer-to-peer list AFAIK and anyone can pop

in at their leisure. Noone is *required* to comment. But thanks for your comments!

I have added a video recoding function to my existing non-threaded application now. And as I feared it is not very good because it disappears out into nothing-land for 5 minutes when it recodes a 5 minute test video.
Looks like ffmpeg is actually "playing" the video at normal speed and saving a modified stream to the file.
So it would be 45 minutes to recode a 45 min video with the wrong codec to begin with...

So I will try my hand at using the hints from the article I linked to in order to have some user feedback. Maybe just write a period to the console every second and add a linefeed and the time in minutes every minute.
This way the user can see something is it requires me to run the actual process in a separate thread of course.

Bo Berglund Developer in Sweden

Reply by email