1

Я хочу использовать 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

Кажется, что это не может быть сделано таким образом. Проблема в том, что заголовок VBR записывается в начало файла, но вычисляется только в конце кодировки. Это требует поиска в файле, что невозможно, если вывод представляет собой канал.

Я побежал strace на все вышеперечисленные варианты. Во 2-й версии (при записи в обычный файл) в конце я получаю следующее:

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

В 1-й версии, где я использую - качестве выходного аргумента, lame даже не пытается написать заголовок. В 3-й версии, однако, он пытается, но терпит неудачу, потому что вывод - труба.

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

В конце он также пишет сообщение об ошибке, которое легко пропустить из-за другого вывода, который он обычно печатает в stderr, если я не запускаю его с опцией --silent (что я и сделал, чтобы сделать вывод strace более чистым):

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

Решением этой проблемы является либо запись во временный файл, затем дальнейшая передача, либо использование кодировки с постоянным битрейтом (в этом случае дополнительный заголовок не записывается в начале файла после кодирования).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .