[Lazarus] How to use RunCommandIndir() in a thread?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[Lazarus] How to use RunCommandIndir() in a thread?

Free Pascal - Lazarus mailing list
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

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] How to use RunCommandIndir() in a thread?

Free Pascal - Lazarus mailing list
On Mon, 15 Apr 2019 00:59:16 +0200, Bo Berglund via lazarus
<[hidden email]> wrote:

>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

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] How to use RunCommandIndir() in a thread?

Free Pascal - Lazarus mailing list
On Mon, 15 Apr 2019 14:49:49 +0200, Bo Berglund via lazarus
<[hidden email]> 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

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] How to use RunCommandIndir() in a thread?

Free Pascal - Lazarus mailing list
G'day,

Sorry for not replying earlier, I'm under the pump at work.

I 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



--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus
Reply | Threaded
Open this post in threaded view
|

Re: [Lazarus] How to use RunCommandIndir() in a thread?

Free Pascal - Lazarus mailing list
On Tue, 16 Apr 2019 12:49:02 +0800, Michael Thompson via lazarus
<[hidden email]> wrote:

>Sorry for not replying earlier, I'm under the pump at work.

Don'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 happening at least.
But it requires me to run the actual process in a separate thread of
course.

--
Bo Berglund
Developer in Sweden

--
_______________________________________________
lazarus mailing list
[hidden email]
https://lists.lazarus-ide.org/listinfo/lazarus