Adicione áudio ao vídeo usando o FFmpeg

26

Estou tentando adicionar som a um vídeo usando o FFmpeg, mas por algum motivo, quando reproduzo o arquivo resultante, ele não tem som. Também tentei fazê-lo com um arquivo de áudio aac, além de deixar de fora -acodec copye fornecer um arquivo wav.

Aqui está a saída completa:

C:\Users\SM-Audio\Desktop>ffmpeg -i PrintingCDs.mp4 -i AudioPrintCDs.mp3 -acodec
 copy -vcodec copy PrintCDs1.mp4
ffmpeg version N-48886-g5ce023b Copyright (c) 2000-2013 the FFmpeg developers
  built on Jan 14 2013 19:16:33 with gcc 4.7.2 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-av
isynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enab
le-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libg
sm --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --e
nable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --e
nable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --en
able-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable
-libxavs --enable-libxvid --enable-zlib --enable-filter=frei0r
  libavutil      52. 14.100 / 52. 14.100
  libavcodec     54. 89.100 / 54. 89.100
  libavformat    54. 59.107 / 54. 59.107
  libavdevice    54.  3.102 / 54.  3.102
  libavfilter     3. 32.100 /  3. 32.100
  libswscale      2.  1.103 /  2.  1.103
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  2.100 / 52.  2.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'PrintingCDs.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2013-05-01 13:35:52
  Duration: 00:02:35.57, start: 0.000000, bitrate: 585 kb/s
    Stream #0:0(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 1024x
768 [SAR 1:1 DAR 4:3], 457 kb/s, 10 fps, 10 tbr, 30k tbn, 30 tbc
    Metadata:
      creation_time   : 2013-05-01 13:35:53
      handler_name    : Mainconcept MP4 Video Media Handler
    Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 22050 Hz, mono, fltp, 126
kb/s
    Metadata:
      creation_time   : 2013-05-01 13:35:53
      handler_name    : Mainconcept MP4 Sound Media Handler
[mp3 @ 003dd6c0] max_analyze_duration 5000000 reached at 5015510 microseconds
Input #1, mp3, from 'AudioPrintCDs.mp3':
  Metadata:
    encoder         : Lavf54.59.107
  Duration: 00:02:36.21, start: 0.000000, bitrate: 64 kb/s
    Stream #1:0: Audio: mp3, 44100 Hz, mono, s16p, 64 kb/s
File 'PrintCDs1.mp4' already exists. Overwrite ? [y/N] y
Output #0, mp4, to 'PrintCDs1.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    encoder         : Lavf54.59.107
    Stream #0:0(eng): Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1024x768 [S
AR 1:1 DAR 4:3], q=2-31, 457 kb/s, 10 fps, 30k tbn, 30k tbc
    Metadata:
      creation_time   : 2013-05-01 13:35:53
      handler_name    : Mainconcept MP4 Video Media Handler
    Stream #0:1(eng): Audio: aac ([64][0][0][0] / 0x0040), 22050 Hz, mono, 126 k
b/s
    Metadata:
      creation_time   : 2013-05-01 13:35:53
      handler_name    : Mainconcept MP4 Sound Media Handler
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 1555 fps=0.0 q=-1.0 Lsize=   11133kB time=00:02:35.57 bitrate= 586.2kbits
/s
video:8674kB audio:2408kB subtitle:0 global headers:0kB muxing overhead 0.459569
%
Arlen Beiler
fonte
Observe que o comando na pergunta é completamente suficiente no caso de mesclar um arquivo somente de vídeo mp4 sem trilha de áudio incorporada com um arquivo somente de áudio mp4 separado.
Vadzim

Respostas:

50

Por padrão, o FFmpeg aceita apenas um fluxo de áudio e um vídeo. No seu caso, isso é retirado apenas do primeiro arquivo.

Você precisa mapear os fluxos corretamente:

ffmpeg -i input.mp4 -i input.mp3 -c copy -map 0:v:0 -map 1:a:0 output.mp4

Algumas notas:

  • As opções de mapeamento de pedidos determinam quais fluxos da entrada são mapeados para a saída.
  • 0:v:0é o primeiro fluxo de vídeo do primeiro arquivo e 1:a:0é o primeiro fluxo de áudio do segundo arquivo. O v/ anão é estritamente necessário, mas caso seus arquivos de entrada contenham vários fluxos, isso ajuda a desambiguar. Mais informações sobre mapeamento podem ser encontradas no FFmpeg Wiki .
  • Se o seu fluxo de áudio for maior que o arquivo de vídeo ou vice-versa, você poderá usar a -shortestopção para que o ffmpeg pare a conversão quando o menor dos dois terminar.
  • -c copycopia os fluxos de áudio e vídeo. Isso significa que o processo será rápido e a qualidade será a mesma. Mas, ao adicionar, digamos, áudio WAV a um arquivo de vídeo existente, seria melhor compactar esse áudio primeiro. Por exemplo:

    ffmpeg -i input.mp4 -i input.wav -c:v copy -map 0:v:0 -map 1:a:0 -c:a aac -b:a 192k output.mp4
    

    Aqui, apenas copiamos o fluxo de vídeo ( -c:v copy) e recodificamos o fluxo de áudio com o codificador AAC interno ffmpeg ( -c:a aac) a 192 kBit / s.

  • Se o seu formato de saída não suportar um codec específico (por exemplo, ao adicionar WAV ao MP4 ou AAC ao AVI, etc.), também será necessário recodificar.
slhck
fonte
11
Muito obrigado, isso funciona perfeitamente. Qual é o -c copy? Isso é abreviação para -acodec copy -vcodec copy?
Arlen Beiler
11
Sim, basicamente ele diz para copiar todos os tipos de fluxos - isso também inclui legendas.
Slhck
11
por curiosidade e se a duração do áudio ou vídeo não for a mesma! o vídeo permanece o mesmo e a duração do áudio corresponde automaticamente ao tamanho do vídeo!
Akash Dubey 25/05
11
O @Akash ffmpeg sempre usará o mais longo dos dois fluxos e adicionará vídeo preto ou áudio silencioso no final. A menos que você especifique a -shortestopção, nesse caso o fluxo mais curto termina o processo de codificação.
Slhck # 25/17
11
@AkashDubey É assim que você usa, sim. Em qualquer lugar entre -i <input>e o arquivo de saída.
Slhck # 25/17