On 17/10/14 20:54, Andrew Haines wrote:
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
Thanks Andrew!, that fixed the issue.
--
Leonardo M. Ramé
http://leonardorame.blogspot.com
--
_______________________________________________
Lazarus mailing list
[email protected]
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus