Pagina1 van 1
Forum

Welkom bij de Tweaking4All gemeenschapsforums!
Voor je gaat deelnemen, bekijk de Forum Regels!

Specifieke onderwerpen: Start het onderwerp met de naam van het programma of systeem.
Bijvoorbeeld “MacOS X – Jouw vraag“, of bijvoorbeeld “MS Word – Jouw Tip of Truc“.

Merk op: Omschakelen naar een andere taal zal niet werken als je een post aan het lezen bent aangezien er waarschijnlijk geen vertaling beschikbaar is.



Deel:
Meldingen
Alles wissen

[Opgelost] Lazarus - Hoe lees je de output van ffmpeg of ffprobe?

4 Berichten
1 Gebruikers
0 Reactions
1,043 Bekeken
 Hans
(@hans)
Famed Member Admin
Deelgenomen: 12 jaar geleden
Berichten: 2864
Topic starter  

Ik was aan het experimenteren met ffprobe (ffmpeg kan hetzelfde probleem hebben) waarbij ik ffprobe aanriep vanuit een Lazarus programma, m.b.v. TProcess, om vervolgens te ontdekken dat het maar geen output gaf. 
Om de een of andere (onduidelijke) reden geeft ffprobe geen output via stdout maar via stderr
Hieronder de code die ik gebruik om fprobe aan te roepen in mijn Lazarus programma:

procedure TForm1.Button1Click(Sender: TObject);
var fExec, Args : string;
begin
fExec := './ffprobe';
Args := '';
with TProcess.Create(self) do
begin
CurrentDirectory := '.';
Options := [poUsePipes];
CommandLine := fExec + ' ' + Args;
Execute;
Memo1.Lines.LoadFromStream(Stderr); // gebruik de Stderr property i.p.v. de Output property
end;
end;          

Dit zou cross platform moeten zijn. Het kan natuurlijk nodig zijn om het pad van ffprobe in de fExec string aan te passen als je bijvoorbeeld Windows draait.
Vergeet niet Process aan de Uses clausule toe te voegen.


   
BeantwoordenCiteren
 Hans
(@hans)
Famed Member Admin
Deelgenomen: 12 jaar geleden
Berichten: 2864
Topic starter  

Woops ... ik zie nu dat ik het mis had ...

1) De standaard ffprobe info (versie, libs etc) gaat via stderr.

2) De film informatie echter gaat via stdout.


   
BeantwoordenCiteren
 Hans
(@hans)
Famed Member Admin
Deelgenomen: 12 jaar geleden
Berichten: 2864
Topic starter  

Omdat de output soms groot kan zijn van ffprobe, overweeg om regel 9 te veranderen naar:

Options := [poWaitOnExit,poUsePipes];

   
BeantwoordenCiteren
 Hans
(@hans)
Famed Member Admin
Deelgenomen: 12 jaar geleden
Berichten: 2864
Topic starter  

Uiteindelijk gebruikte ik voor zowel MacOS X als Windows:

{$IFDEF DARWIN} // Mac
fExec := ProgramDirectory+'ffprobe';
{$ENDIF}
{$IFDEF WINDOWS} // Windows
fExec := 'ffprobe.exe';
{$ENDIF}
MyShell := TProcess.Create(self);
ShellResult := TStringList.Create;
MemStream := TMemoryStream.Create;
BytesRead := 0;
with MyShell do
begin
Options:=[poUsePipes];
ShowWindow:=swoHIDE;
Executable:=fExec;
Parameters.Add('-show_format');
Parameters.Add('-show_streams');
Parameters.Add('-v');
Parameters.Add('quiet');
Parameters.Add('-print_format');
Parameters.Add('ini');
Parameters.Add(movieFile);
Execute;
end;
while MyShell.Running do
begin
MemStream.SetSize(BytesRead + READ_BYTES);
NumBytes := MyShell.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES);
if NumBytes > 0 then
begin
Inc(BytesRead, NumBytes);
end
else
begin
Sleep(100);
end;
end;
repeat
// make sure we have room
MemStream.SetSize(BytesRead + READ_BYTES);
// try reading it
NumBytes := MyShell.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES);
if NumBytes > 0 then
begin
Inc(BytesRead, NumBytes);
end;
until NumBytes <= 0;
MemStream.SetSize(BytesRead);
ShellResult.LoadFromStream(MemStream);
MemStream.Free;
MyShell.Free;      


   
BeantwoordenCiteren
Deel: