Questão Tendo dificuldade em entender o comando ffmpeg -map


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

Eu li isso https://trac.ffmpeg.org/wiki/How%20to%20use%20-map%20option mas não entendi realmente. Por que é -map 0: 1 escrito duas vezes no exemplo 1? O que faz o -c: s? O que seria um comando para copiar # 0: 0 para vídeo e # 0: 2 para o áudio?


2


origem




Respostas:


-map <inputNo>:<streamNo> diz ao ffmpeg para transmitir streamNo da entrada inputNo e 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:1 no exemplo) porque você pode codificar cada um com diferentes codecs / parâmetros. 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 -map comando), um vídeo, um fluxo de á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 pode significar apenas uma coisa: sua trilha de vídeo é codificada com um codec que pode ser alterado em MKV, mas não em MP4. Por isso, é descartado automaticamente. Você pode postar um log de ffmpeg -i input.mkv para que possamos verificar com quais codecs as faixas são codificadas?

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


5



"Por padrão (ou seja, sem nenhum comando -map), todos os fluxos de todas as entradas são capturados uma vez." - isso não é verdade. ffmpeg só vai levar 1 fluxo de áudio, vídeo e legendas. Se você quiser todos os fluxos mapeados, você precisa -map 0. - slhck


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: tears_of_steel.mkv. É por isso que todos os nossos mapas começam com # 0: ...

Em seguida, 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 do mapa, ela será mapeada para o primeiro fluxo em nosso arquivo de saída (tears_of_steel-v2.mkv).

Em seguida, 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 do 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


1





Isso deve funcionar, não pode testar nesta máquina:

ffmpeg -i input.mkv
-map 0:0 -map 0:2 \
-c:v copy \
-c:a aac \
-b:a 128k \
output.mp4

ou

ffmpeg -i input.mkv -map 0:0 -map 0:2 -c:v copy -c:a aac -b:a 128k output.mp4

Explicações

c: s é um alias para o codec -scodec, que especifica o codec de legendas.

-map 0: 1 está lá duas vezes porque o exemplo tem uma saída aac e mp3.


0



Não vai funcionar porque -c:a aac necessidades -strict experimental também. - slhck


Esta é uma resposta simples para pessoas como eu, que gostam de explicações simples de trabalho. Esta é uma solução quando você copia mkv para mp4 e quer escolher transmissões de áudio:

Você tem que escrever -map 0: numberofstreamminusonena frente de -c: uma cópia

Digamos que o vídeo tenha 3 streams (você pode ver isso em mediainfo). O primeiro fluxo é o vídeo, o segundo é o áudio padrão e o terceiro é o á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 copy porque se você não fizer isso, o ffmpeg não copiará o fluxo de vídeo e você obterá apenas o fluxo de áudio (se o vídeo tiver dois fluxos de vídeo e você quiser copiar o segundo, será necessário gravar o mapa em 0: 1)

Então o linha de comando final se 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ê receberá 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"

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

Eu espero que isso ajude


0