Как сказать хромать писать заголовок VBR в поток?

503
petersohn

Я хочу использовать lame для кодирования mp3-файлов, но вместо того, чтобы записывать его непосредственно в файл, я хочу передать его в другую программу, которая в конечном итоге запишет его куда-нибудь. Проблема в том, что если lame обнаруживает, что его вывод является потоком, он не записывает заголовок VBR, и проигрыватели неправильно определяют длину файла. Например, если я сделаю это, то полученный файл будет неправильным:

lame infile.wav - >outfile.mp3 

Я попробовал следующий трюк:

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

Сначала это работает, но только если stdout напрямую перенаправлен в файл. Следующий случай не работает:

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

Если я использую ffmpeg (или avconv) в качестве внешнего интерфейса для lame, у меня точно такая же проблема.

Есть ли способ сказать lame, что я хочу, чтобы он записывал заголовок VBR, даже если он думает, что пишет в поток?

1

1 ответ на вопрос

1
petersohn

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).

Спасибо за эту информацию, после всех этих лет =) Niloct 5 лет назад 0

Похожие вопросы