[Lazarus] TProcess.Input hangs
Andrew Haines
andrewd207 at aol.com
Sat Oct 18 01:54:36 CEST 2014
On 10/17/14 11:46, "Leonardo M. Ramé" wrote:
> Hi, I'm using this code to convert WAV files to MP3 on the fly, using
> lame. It was working great until today.
>
> It looks like this code has problems with large files sent to stdin.
>
> lProcess := TProcess.Create(nil);
> lProcess.Executable := '/usr/bin/lame';
> lProcess.Parameters.Add('-'); // stdin
> lProcess.Parameters.Add('-'); // stdout
> lProcess.Options := [poUsePipes];
> lProcess.Execute;
> lWav.LoadFromFile('/home/leonardo/16310.wav');
> lWav.Position:= 0;
> lWav.SaveToStream(lProcess.Input); // <-- here hangs
> lProcess.CloseInput;
>
>
> I also tried using this:
>
> repeat
> lReadCount := lProcess.Input.Write(lWav.Memory^, 500);
> if lReadCount < 500 then
> lReadCount := 0;
> until lReadCount = 0;
>
> But also hangs before lReadCount < 500.
>
> Any hint?
You are writing to stdin while the process is generating data to stdout.
If you don't empty stdout and stderr the process will hang.
There's lots of info here:
http://wiki.freepascal.org/Executing_External_Programs
You need something like
while lProcess.Running or (lProcess.StdOut.NumBytesAvailable > 0) do
begin
while lProcess.StdOut.NumBytesAvailable > 0 do
begin
lReadCount := lProcess.StdOut.Read(Buffer, SizeOf(Buffer);
if lReadCount > 0 then
// do something with encoded data
end;
// also you need to keep lProcess.StdErr empty or it can hang if it
gets full.
while lProcess.StdErr.NumBytesAvailable > 0 do
begin
lReadCount := lProcess.StdErr.Read(Buffer, SizeOf(Buffer);
if lReadCount > 0 then
// do something with Stderr data
end;
// now write data to be encoded.
lReadCount := lWav.Read(Buffer, SizeOf(Buffer));
lProcess.Input.Write(Buffer, lReadCount);
end;
Regards,
Andrew Haines
More information about the Lazarus
mailing list