How to tell lame to write VBR header to stream?

1

I want to use lame to encode mp3 files, but instead of writing it directly to a file I want to pipe it into another program that will eventually write it out somewhere. The problem is that if lame detects that its output is a stream then it doesn't write the VBR header and players figure out the length of the file wrong. For example, if I do this, then the resulting file will be wrong:

lame infile.wav - >outfile.mp3

I tried the following trick:

lame infile.wav /dev/stdout >outfile.mp3

It seems to work at first, but only if the stdout is directly redirected to a file. The following case doesn't work:

lame infile.wav /dev/stdout | cat >outfile.mp3

If I use ffmpeg (or avconv) as a front end to lame, I got exactly the same problem.

Is there any way to tell lame that I want it to write the VBR header even if it thinks it is writing to a stream?

petersohn

Posted 2015-02-14T19:57:32.107

Reputation: 2 554

Answers

1

It seems that it cannot be done this way. The problem is that the VBR header is written to the beginning of the file, but is only calculated at the end of the encoding. This requires seeking in the file, which is not possible if the output is a pipe.

I ran an strace on all of the variants above. In the 2nd version (when writing to a normal file), I get the following at the end:

lseek(4, 0, SEEK_SET)                   = 0
write(4, "\377\373\220d\0\0\0"..., 417) = 417
close(4)                                = 0

In the 1st version, where I use - as output argument, lame doesn't even try to write the header. In the 3rd version, however, it tries but fails because the output is a pipe.

lseek(4, 0, SEEK_SET)                   = -1 ESPIPE (Illegal seek)

It also writes an error message at the end, which is easily overlooked because of the other output it normally prints to stderr, unless I run it with the --silent option (which I did, to make the strace output cleaner):

fatal error: can't update LAME-tag frame!

The solution to this problem is either to write to a temporary file, then pipe that further, or to use constant bitrate encoding (in which case no additional header is written at the beggining of the file after encoding).

petersohn

Posted 2015-02-14T19:57:32.107

Reputation: 2 554

Thanks for this information, after all these years =) – Niloct – 2018-10-27T06:18:32.657