Sign in Join

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

Mailing lists / lazarus / 2019-03

Problems using RunCommandIndir with Lazarus 2.0.0

9 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

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

Bo Berglund

I am trying to extract information from a video file (mp4) using ffmpeg in a Lazarus 2.0.0 program.
The command I want to use is:

ffmpeg -i testvideo.mp4 -hide_banner

(with a file name selected in Lazarus of course)

I created this test function:

uses Process;
function TForm1.GetVideoInfo(videofile: string): string;
(* ffmpeg -i testvideo.mp4 -hide_banner *)
var
  i: integer;
  arguments: array of string;
  returnstr: string;
  executable: string;
begin
  Result := '';
  lbxResult.Clear;
  SetLength(arguments,3);
  executable := 'c:\Programs\ffmpeg\bin\ffmpeg.exe';
  arguments[0] := '-i';
  arguments[1] := videofile;
  arguments[2] := '-hide_banner';
  if RunCommandIndir(ExtractFileDir(videofile),executable,arguments,
returnstr) then
    Result := returnstr
  else
    Result := 'Failed to run command';
end;

I call this from a button event:

procedure TForm1.btnSelectVideoClick(Sender: TObject);
begin
  dlgOpen.InitialDir := ReadIniString('Files', 'VideoDir', '');
  if not dlgOpen.Execute then exit;
  FVideoDir := ExtractFileDir(dlgOpen.FileName);
  FVideoFile := dlgOpen.FileName;
  edInputFile.Text := FVideoFile;
  WriteIniString('Files', 'VideoDir', FVideoDir);
  WriteIniString('Files', 'VideoFile', FVideoFile);
  lbxResult.Items.Text := GetVideoInfo(FVideoFile);
end;

PROBLEM:
----------
It always returns the error message "Failed to run command".

If I use the ffmpeg command used in the GetVideoInfo function directly in a command window in the directory containing the video file it works just fine (long lines are wrapped by the news reader):

D:\VIDEO\USA\test>ffmpeg -i testvideo.mp4 -hide_banner Input #0, mov,mp4,m4a,3gp,3g2,mj2, from
'D:\VIDEO\USA\test\testvideo.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isommp42
creation_time : 2018-11-17T02:08:51.000000Z
Duration: 00:42:54.54, start: 0.000000, bitrate: 377 kb/s Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 302 kb/s, 30 fps, 30 tbr, 15360 tbn
, 60 tbc (default)
Metadata:
creation_time : 2018-11-17T02:08:51.000000Z
handler_name : ISO Media file produced by Google Inc. Created on: 11/16/2018.
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 71 kb/s (default)
Metadata:
creation_time : 2018-11-17T02:08:51.000000Z
handler_name : ISO Media file produced by Google Inc. Created on: 11/16/2018.
At least one output file must be specified

I want to parse this text to extract the video playing time and some other data but I get a false result from the call to RunCommandIndir() and the string variable supposed to hold the returned data is empty.

What have I done wrong here?

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Bo Berglund
Bo Berglund wrote
What have I done wrong here?

Never mind, I found the problem:
The ffmpeg command returned an error code and the output was directed into stderr rather than stdout.
RunCommandIndir apparently did not receive any data on stdout...

Fixed problem after changing he call to add the command options:

if RunCommandIndir(ExtractFileDir(videofile),executable,arguments, returnstr, [poWaitOnExit,poStderrToOutPut]) then

    Result := returnstr
  else
    Result := 'Command returned error'#13#10 + returnstr;

ANOTHER LAZARUS PROBLEM:
------------------------
While testing this I also discovered that the FileOpen dialog is *EXTERMELY* slow to appear.
What can cause this?

  dlgOpen.InitialDir := ReadIniString('Files', 'VideoDir', '');
  dlgOpen.FileName := ExtractFileName(ReadIniString('Files',
'VideoFile', ''));
  if not dlgOpen.Execute then exit;

The dlgOpen.Execute call pops up an unpopulated window after 8 seconds, then chugs along painting the window for another 5 seconds until it is done 13-14 seconds after the call was made!!!

I have never experienced this kind of delay in earlier versions of Lazarus, so is there something in this new version running on Windows 7 X64 that is known to cause it?

I installed Lazarus 2.0.0 yesterday on my Windows 7 X64 workstation when starting this new project since I only had 1.8.0 and earlier installed before (with fpc 3.0.4).
I have used the dialogs in other projects and never seen this sluggish behaviour before....

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Bo Berglund
Bo Berglund wrote 24 lines
ANOTHER LAZARUS PROBLEM: ------------------------ While testing this I also discovered that the FileOpen dialog is *EXTERMELY* slow to appear. What can cause this? dlgOpen.InitialDir := ReadIniString('Files', 'VideoDir', ''); dlgOpen.FileName := ExtractFileName(ReadIniString('Files', 'VideoFile', '')); if not dlgOpen.Execute then exit; The dlgOpen.Execute call pops up an unpopulated window after 8 seconds, then chugs along painting the window for another 5 seconds until it is done 13-14 seconds after the call was made!!! I have never experienced this kind of delay in earlier versions of Lazarus, so is there something in this new version running on Windows 7 X64 that is known to cause it? I installed Lazarus 2.0.0 yesterday on my Windows 7 X64 workstation when starting this new project since I only had 1.8.0 and earlier installed before (with fpc 3.0.4). I have used the dialogs in other projects and never seen this sluggish behaviour before....

I have now tested with both 32 and 64 bit Lazarus installations on my Windows 7 x64 workstation and they both are very sluggish when bringing up the file select dialog. This happens when I run in the IDE by using the green arrow button.

Then I stripped the exe file of symbols and started it directly. In this execution mode the OpenDialog.Execute function is no longer so slow. It behaves more natural now.

So it seems like the problem is because of debugging from the IDE inside of a Windows 7 x64 environment using Lazarus 2.0.0. Why this would be slow in bringing up a file select dialog is not clear to me...

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Bo Berglund: I am trying to extract information from a video file (mp4) using ffmpeg in a Lazarus…
Bo Berglund wrote
I am trying to extract information from a video file (mp4) using ffmpeg in a Lazarus 2.0.0 program.

I found that ffmpeg is not optimum when just needing the video data I was after, instead ffprobe is more suited to this. It is also installed with ffmpeg.

Now for another RunCommandInDir problem:
----------------------------------------
When I run the command to extract the information a black command window is briefly flashed on screen and then disappears.

Is there some way to make this window minimized or invisible while it runs?

The available options for RunCommandInDir seem to be:

type TProcessOptions = set of (
poRunSuspended, //Start the process in suspended state. poWaitOnExit, //Wait for the process to terminate before returning. poUsePipes, //Use pipes to redirect standard input and output. poStderrToOutPut, //Redirect standard error to the standard output. poNoConsole, //Do not allow access to the console window for the process (Win32 only)
poNewConsole, //Start a new console window for the process (Win32 only)
poDefaultErrorMode, //Use default error handling.
poNewProcessGroup, //Start the process in a new process group (Win32 only)
poDebugProcess, //Allow debugging of the process (Win32 only) poDebugOnlyThisProcess //Do not follow processes started by this process (Win32 only)
);

It seems like poNoConsole could be what I am after, but it is Win32 only...

No option to hide the console?

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Bo Berglund
Bo Berglund wrote 7 lines
Now for another RunCommandInDir problem: ---------------------------------------- When I run the command to extract the information a black command window is briefly flashed on screen and then disappears. Is there some way to make this window minimized or invisible while it runs?

So I have solved the general problems of using RunCommandInDir with ffmpeg. It does work.

But if I command a video edit with multiple cuts being extracted and later combined there is a succession of many black command windows being shown on top of the main GUI form for a fraction of a second up to a couple of seconds.
It really looks very ugly.

Is there absolutely no way to hide or minimize these windows during execution?

I am using Lazarus 2.0.0 with fpc 3.0.4 (64 bit versions) in Windows 7 x64.

This is till a problem that fits the topic of this thread...

This is the function I call in a loop once for each cutout part of the video file:

function ExtractVideoSection(InputFile, OutputFile: string; Start,
Duration: integer; OverwriteOutput: boolean = true): boolean;
var
  arguments: array of string;
  returnstr: string;
  executable: string;
begin
  Result := false;
  if not FileExists(InputFile) then exit;
  if (not OverwriteOutput) and FileExists(OutputFile) then exit;
  if FileExists(OutputFile) then DeleteFile(OutputFile);
  SetLength(arguments, 10);
  executable := 'ffmpeg.exe';
  arguments[0] := '-ss';
  arguments[1] := FormatTimeDiff(Start);
  arguments[2] := '-i';
  arguments[3] := InputFile;
  arguments[4] :=  '-to';
  arguments[5] :=  FormatTimeDiff(Duration);
  arguments[6] :=  '-c';
  arguments[7] :=  'copy';
  arguments[8] :=  OutputFile;
  arguments[9] :=  '-hide_banner';
  Result := RunCommandIndir(ExtractFileDir(OutputFile), executable,
arguments, returnstr, [poWaitOnExit,poStderrToOutPut]);
end;

Every invocation of RunCommandInDir() causes a command window to be shown on screen.

Bo Berglund Developer in Sweden

Reply by email

Unknown author
to Bo Berglund

Just done a quick google,
would telling ffmpeg to log output to errlog or nul help.

https://superuser.com/questions/555289/is-there-a-way-to-disable-or-hide-output-thrown-by-ffmpeg

Just a thiught

Josh

Earlier message 77 lines
-----Original Message----- From: Bo Berglund via lazarus Sent: Tuesday, March 5, 2019 7:48 PM To: Cc: Bo Berglund Subject: Re: [Lazarus] Problems using RunCommandIndir with Lazarus 2.0.0 On Sat, 02 Mar 2019 09:56:07 +0100, Bo Berglund via lazarus wrote: >Now for another RunCommandInDir problem: >---------------------------------------- >When I run the command to extract the information a black command >window is briefly flashed on screen and then disappears. > >Is there some way to make this window minimized or invisible while it >runs? So I have solved the general problems of using RunCommandInDir with ffmpeg. It does work. But if I command a video edit with multiple cuts being extracted and later combined there is a succession of many black command windows being shown on top of the main GUI form for a fraction of a second up to a couple of seconds. It really looks very ugly. Is there absolutely no way to hide or minimize these windows during execution? I am using Lazarus 2.0.0 with fpc 3.0.4 (64 bit versions) in Windows 7 x64. This is till a problem that fits the topic of this thread... This is the function I call in a loop once for each cutout part of the video file: function ExtractVideoSection(InputFile, OutputFile: string; Start, Duration: integer; OverwriteOutput: boolean = true): boolean; var arguments: array of string; returnstr: string; executable: string; begin Result := false; if not FileExists(InputFile) then exit; if (not OverwriteOutput) and FileExists(OutputFile) then exit; if FileExists(OutputFile) then DeleteFile(OutputFile); SetLength(arguments, 10); executable := 'ffmpeg.exe'; arguments[0] := '-ss'; arguments[1] := FormatTimeDiff(Start); arguments[2] := '-i'; arguments[3] := InputFile; arguments[4] := '-to'; arguments[5] := FormatTimeDiff(Duration); arguments[6] := '-c'; arguments[7] := 'copy'; arguments[8] := OutputFile; arguments[9] := '-hide_banner'; Result := RunCommandIndir(ExtractFileDir(OutputFile), executable, arguments, returnstr, [poWaitOnExit,poStderrToOutPut]); end; Every invocation of RunCommandInDir() causes a command window to be shown on screen. -- Bo Berglund Developer in Sweden --

Reply by email

Bo Berglund
to Unknown author
Josh wrote 5 lines
Just done a quick google, would telling ffmpeg to log output to errlog or nul help. https://superuser.com/questions/555289/is-there-a-way-to-disable-or-hide-output-thrown-by-ffmpeg

The problem is not that some output goes to the stderr output. I have already solved that part.

The question now concerns the way RunCommandIndir() throws up a black command window on screen when it executes.

If I use ffmpeg calls many times in an execution it gets really annoying.

There should be an option to at least minimize the window so it is not in plain view on screen. Best if it can be set to run hidden.

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Bo Berglund
Bo Berglund wrote 9 lines
The question now concerns the way RunCommandIndir() throws up a black command window on screen when it executes. If I use ffmpeg calls many times in an execution it gets really annoying. There should be an option to at least minimize the window so it is not in plain view on screen. Best if it can be set to run hidden.

I finally used the poNoConsole flag in the options even though the Lazarus help specifically states it ONLY works in Win32. But amazingly it did the job of hiding the console windows even though my Lazarus 2.0.0 program is built as a 64 bit program and runs in Windows7 x64!

So the note in the help is misleading...

Bo Berglund Developer in Sweden

Reply by email

Joost van der Sluis
to Bo Berglund

Op 06-03-19 om 08:52 schreef Bo Berglund via lazarus:

I finally used the poNoConsole flag in the options even though the Lazarus help specifically states it ONLY works in Win32.

This was probably written when there was no Win64 LCL-widgetset yet. At that time, 'Win32' was synonymous to 'The Windows widgetset). In other words: it only works on Windows.

Regards,

Joost.

Reply by email