Como posso canalizar dados sem perdas de e para o FFmpeg?

Como posso canalizar dados sem perdas de e para o FFmpeg?

Canalizei um stream de uma instância do FFmpeg para outra, mas como a compactação foi usada no stream intermediário, o resultado final foi feio. Preciso de um canal sem perdas para evitar isso e quero que ele contenha áudio e vídeo.

Suspeito que haja mais de uma resposta para esse problema, então os pontos extras vão para qualquer um que forneça uma lista exaustiva de soluções (contêineres e codecs compatíveis que podem ser canalizados). Os pontos de bônus também vão para quem contabiliza outros dados, como legendas.

EDIT: Estou procurando combinações adequadas de codec/contêiner. Não sei por que as pessoas estavam tendo dificuldade em descobrir isso, já que eu disse que já usei um cano e agora preciso que ele não tenha perdas.

Não sei como explicar isso sem parecer vaidoso, mas este é um site de perguntas frequentes. Fazer perguntas que exigem respostas extremamente específicas não ajudará os milhões de usuários que chegam a este site inserindo seus próprios problemas nos motores de busca. Minha pergunta foi projetada para ajudar qualquer pessoa que precise canalizar dados sem perdas entre instâncias do FFmpeg, sem distrair a todos com uma parede de narrativa e código explicando o que eu estava fazendo, por que não funcionou e por que essa é a única opção.

Responder1

Como canalizar vídeo e áudio sem perdas de ffmpegparaffmpeg

Requisitos do questionador:

  • canalizar sem perdas de uma instância ffmpegpara outra
  • não importa se vai e vem/dev/null

Exemplo:

ffmpeg -s 1280x720 -f rawvideo -i /dev/zero -ar 48000 -ac 2 -f s16le -i \
/dev/zero -c copy -f nut pipe:1 | ffmpeg -y -i pipe:0 -c copy -f nut /dev/null

Não vejo razão para alguém fazer isso.Além disso, há poucos motivos para mudar para ffmpegquando ffmpegvocê provavelmente poderá usar apenas um ffmpegprocesso para fazer o que quiser.

O que as opções fazem:

  • -s 1280x720 -f rawvideo– Opções para descrever a entrada desde/dev/zeronão é um formato de entrada típico e, portanto, essas opções adicionais são necessárias.

  • -i /dev/zero– A entrada de vídeo. Ele está sendo usado neste exemplo para gerar um fluxo de vídeo do “nada”. Isso foi usado no exemplo porque o questionador se recusou a fornecer qualquer informação sobre as entradas usadas.

  • -ar 48000 -ac 2 -f s16le– Opções para descrever a entrada desde/dev/zeronão é um formato de áudio típico.

  • -i /dev/zero– A entrada de áudio. Ele está sendo usado neste exemplo para gerar um fluxo de áudio do “nada”.

  • -c copyCópia de fluxo, ou re-mux, as entradas para a saída. Nenhuma recodificação está sendo executada, portanto o processo é sem perdas. Não se sabe se a cópia do fluxo é aceitável ou não para quem faz a pergunta. Talvez a recodificação seja desejada?

  • -f nut– Você precisa informar ffmpegqual formato usar para o tubo. Nut é um formato de contêiner. Veja ffmpeg -formatspara obter uma lista completa. Outro formato flexível é -f matroska, mas é impossível sugerir um formato de contêiner de saída apropriado ou específico para usar sem mais informações do autor da pergunta.

  • pipe:1- Use opipeprotocolopara saída para stdout. Alternativamente, o número pode ser omitido (apenas pipe:) e por padrão o descritor de arquivo stdout será usado para escrita e stdin será usado para leitura.

Responder2

A maneira como aprendi a fazer isso (com partes das respostas anteriores) é usar o rawvideocodec para o vídeo, o pcm_s16lecodec de áudio e nuto wrapper do FFmpeg para codificar o fluxo. nutnão é suportado pelos principais programas fora do FFmpeg, mas é o único contêiner que conheço atualmente que pode suportar os formatos descompactados necessários para canalizar dados entre processos com eficiência.

Os argumentos para esta codificação podem ser assim:

... -c:v rawvideo -c:a pcm_16le -f nut - ...

Parte do áudio é armazenado com amostras de 24 bits ou maiores e, para isso, você deve usar pcm_24leou um formato diferente. A lista completa de formatos de áudio não compactados será listada em execução ffmpeg -codecs(você terá que procurá-los na lista). Se você não sabe qual é o tamanho da amostra do seu áudio, o uso pcm_16lenão deve causar perda perceptível de qualidade.

Na extremidade receptora do tubo, defina a entrada como entrada padrão e o ffmpeg detectará o formato e decodificará o fluxo.

... ffmpeg -i - ...

As reticências (...) nesta resposta não fazem parte do código. É para onde vai o seu código. Os hífens solitários (-) dizem ao FFmpeg para usar a entrada padrão ou a saída padrão, dependendo de onde aparecem.

ATUALIZAR:

Eu tentei um experimento simples para melhorar isso, e parece que um contêiner melhor é o AVI, porque outros programas irão entendê-lo (pelo menos o VLC).

... -c:v rawvideo -c:a pcm_16le -f avi - ...

Funcionará exatamente como a versão antiga, com o bônus adicional de compatibilidade.

Pensando bem, me arrependi de ter postado uma pergunta que não foi útil em muitas situações, apesar de afirmar que as perguntas deveriam ser úteis para todos. Isso torna a resposta mais útil.

Responder3

O único problema com a outra resposta é que é pcm_s16le, não s16le. Além disso, inclui muitos parâmetros redundantes.

Eu usaria pcm em vez de flac no pipe, porque leva muito menos tempo para processar (PCM é áudio bruto, FLAC leva muito tempo para codificar).

De qualquer forma, aqui está como eu faria isso.

ffmpeg -i <input video file/stream> -vcodec rawvideo -acodec pcm_s16le pipe:1 | ffmpeg -f rawvideo -i - -vcodec <video output codec> -acodec <audio output codec> -vb <video bitrate if applicable> -ab <audio bitrate if applicable> <final-output-filename>

Isso funcionou para mim na última tentativa, mas meu objetivo era canalizar o ffmpeg para o ffplay, que é um processo um pouco diferente.

exemplo:

Isso canaliza um vídeo do ffmpeg para outra instância como saída de vídeo bruto e PCM little-endian de 16 bits (ambos sem perdas, a menos que você tenha PCM de 24 bits e substitua pcm_s24le). Em seguida, converte-os para h.264 na segunda instância, com o fraunhoefer Biblioteca AAC do projeto Android ( libfaacé mais comumente incluída nas compilações do ffmpeg. Você pode substituí-la por esta).

ffmpeg -i montypythonsflyingcircus-s1e1.avi -vcodec rawvideo -acodec pcm_s16le pipe:1 | ffmpeg -i - -vcodec libx264 -acodec libfdk_aac -vb 1200k -ab 96k mpfc-s1e01-output.mkv

Se isso não canalizar as legendas, você sempre pode copiá-las para SRT e depois mixá-las novamente mais tarde, ou adicioná-las facilmente aos canais acima.

informação relacionada