Como dizer coxo para escrever cabeçalho VBR para transmitir?

1

Eu quero usar coxo para codificar arquivos mp3, mas em vez de escrevê-lo diretamente para um arquivo eu quero canalizá-lo em outro programa que acabará por escrevê-lo em algum lugar. O problema é que, se o lame detecta que sua saída é um fluxo, ele não grava o cabeçalho VBR e os jogadores calculam o comprimento do arquivo errado. Por exemplo, se eu fizer isso, o arquivo resultante estará errado:

lame infile.wav - >outfile.mp3

Eu tentei o seguinte truque:

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

Parece funcionar primeiro, mas apenas se o stdout for diretamente redirecionado para um arquivo. O caso a seguir não funciona:

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

Se eu usar ffmpeg (ou avconv) como um front end para lame, eu tenho exatamente o mesmo problema.

Existe alguma maneira de dizer lame que eu quero escrever o cabeçalho VBR mesmo se ele acha que está escrevendo para um fluxo?

petersohn
fonte

Respostas:

1

Parece que não pode ser feito assim. O problema é que o cabeçalho VBR é gravado no início do arquivo, mas é calculado apenas no final da codificação. Isso requer a busca no arquivo, o que não é possível se a saída for um pipe.

Eu corri um strace em todas as variantes acima. Na segunda versão (quando escrevo para um arquivo normal), recebo o seguinte no final:

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

Na 1ª versão, onde eu uso - como argumento de saída, o lame nem sequer tenta escrever o cabeçalho. Na terceira versão, no entanto, ele tenta, mas falha porque a saída é um pipe.

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

Ele também grava uma mensagem de erro no final, que é facilmente ignorada por causa da outra saída que normalmente é impressa em stderr, a menos que eu execute com o comando --silent opção (o que eu fiz, para tornar o limpador de strace de saída):

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

A solução para esse problema é gravar em um arquivo temporário, depois canalizar isso mais adiante ou usar codificação de taxa de bits constante (caso em que nenhum cabeçalho adicional é gravado no início do arquivo após a codificação).

petersohn
fonte
Obrigado por esta informação, depois de todos esses anos =)
Niloct