Tendo problemas para entender o comando ffmpeg -map

Tendo problemas para entender o comando ffmpeg -map

Estou tentando copiar vídeo/áudio de um contêiner mkv para mp4. Quando corro, ffmpeg -i input.mkv -c:v copy -c:a copy output.mp4não recebo nenhum vídeo com áudio polido. Há apenas um stream de vídeo, stream #0:0. Stream #0:1 é áudio polonês, #0:2 inglês e #0:3 - #0:5 são legendas.

Eu leioWiki FFmpeg: Mapamas não entendo isso realmente. Por que está -map 0:1escrito duas vezes no exemplo 1? O que -c:sfaz? Como seria um comando para copiar #0:0 para vídeo e #0:2 para áudio?

Responder1

-map <inputNo>:<streamNo>diz ao ffmpeg para fazer streamstreamNãoda entradaentradaNãoe adicioná-lo à saída, onde <inputNo>começa com 0.

Às vezes, você pode querer usar o mesmo fluxo de entrada duas vezes (como -map 0:1 -map 0:1no exemplo) porque pode codificar cada um com codecs/parâmetros diferentes. No exemplo, a saída contém o mesmo fluxo de áudio duas vezes, uma em MP3 e outra em AAC.

Por padrão (ou seja, sem nenhum -mapcomando), um vídeo, um áudio e um fluxo de legenda das entradas são obtidos. Se você quiser mapear todos os fluxos de uma entrada, use -map <inputNo>.

O fato de você não obter vídeo com seu comando só pode significar uma coisa: sua trilha de vídeo é codificada com um codec que pode ser mixado em MKV, mas não em MP4. Portanto, ele é descartado automaticamente. Você pode postar um log ffmpeg -i input.mkvpara que possamos verificar com quais codecs as faixas estão codificadas?

Finalmente, -c:sé usado para codec de legenda (enquanto -c:aé para áudio e -c:vvídeo)

Responder2

Este foi o exemplo que me permitiu entender. Imagine o seguinte comando:

ffmpeg -i tears_of_steel.mkv -map 0:0 -map 0:2 -map 0:1 -map 0:4 -map 0:3 -c copy tears_of_steel-v2.mkv 

E aqui está como o ffmpeg faz o mapeamento:

Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:2 -> #0:1 (copy)
Stream #0:1 -> #0:2 (copy)
Stream #0:4 -> #0:3 (copy)
Stream #0:3 -> #0:4 (copy)

O que aconteceu?

No comando, temos apenas uma entrada: tear_of_steel.mkv. É por isso que todos os nossos mapas começam com #0:...

Então escrevemos uma primeira opção de mapa: -map 0:0, que se refere ao primeiro fluxo de nossa entrada (tears_of_steel.mkv), que pode ser um fluxo de vídeo, mas isso não importa.

Por ser a primeira opção de mapa, ela será mapeada para o primeiro fluxo em nosso arquivo de saída (tears_of_steel-v2.mkv).

Então escrevemos uma segunda opção de mapa: -map 0:2, que se refere ao terceiro fluxo de nossa entrada. Por ser a segunda opção de mapa, ela é mapeada para o segundo fluxo em nossa saída.

E assim por diante...

Eu escrevi isso no meu github:https://github.com/lingtalfi/ffmpeg-notes/blob/master/ffmpeg-map.md

Responder3

Veja como funcionam as opções -c(selecionar codecs) e -map(selecionar streams):

-c:a -> select first or best supported audio (transcoded)
-c:a copy -> best supported audio (copied)
-map 0:a -> all audio from 1st input file (transcoded)
-map 1:a:0 -> 1st audio stream from 2nd input file (transcoded)
-map 1:a:1 -c:a copy -> 2nd audio stream from 2nd input file (copied)

Para copiar todos os fluxos de legendas do primeiro arquivo de entrada sem transcodificação:

-map 0:s -c:s copy 

Seu arquivo de saída é mp4 e o arquivo de entrada é mkv e você optou por ter saída de vídeo sem transcodificação ( -c:v copy) para um formato compatível com mp4, então você acaba com um arquivo mp4 sem vídeo (reproduzível).

Especifique o codificador de vídeo compatível com mp4, por exemplo. -c:v libx264em vez de -c:v copyou deixe em branco (ou seja, não mencione um codificador & ffmpegos codificadores escolhidos serão os padrão registrados por cada formato de saída)

Se você não quiser transcodificar o vídeo (porque pode levar um tempo considerável), copie o fluxo de vídeo para o mesmo contêiner, mas selecione o áudio desejado, por exemplo. MKV. Para obter um arquivo mp4 com vídeo transcodificado e áudio selecionado:

ffmpeg -i input.mkv -map 0:0 -c:v libx264 -map 0:2 -c:a copy output.mp4

Responder4

Esta é uma resposta simples para pessoas como eu, que gostam de explicações simples e práticas. Esta é uma solução quando você copia mkv para mp4 e desejaescolha fluxos de áudio:

Você tem que escrever-mapa 0: número de fluxo menos umna frente de -c: uma cópia

Digamos que o vídeo tenha 3 streams (você pode ver isso em mediainfo). O primeiro fluxo é de vídeo, o segundo é de áudio padrão e o terceiro é de áudio não padrão no idioma desejado. Então você tem que escrever -map 0:2 NÃO -map 0:3

Além disso, você tem que escrever-map 0:0 na frente de -c:v copiarporque se você não fizer isso, o ffmpeg não copiará o stream de vídeo e você obterá apenas o stream de áudio (se o vídeo tiver dois streams de vídeo e você quiser copiar o segundo, você terá que escrever -map 0:1)

Então olinha de comando finalse parece com isso:

ffmpeg -i "inputpath\input.mkv" -map 0:0 -c:v copy -map 0:2 -c:a copy "outputpath\output.mp4"

Neste caso, você obterá o primeiro fluxo de vídeo e o terceiro fluxo de áudio

Outro exemplo:

ffmpeg -i "inputpath\input.mkv" -map 0:1 -c:v copy -map 0:6 -c:a copy "outputpath\output.mp4"

Neste caso você deve obter o segundo fluxo de vídeo e o sétimo fluxo de áudio

Eu espero que isso ajude

informação relacionada