Add audio to video using FFmpeg

96,392

By default, FFmpeg will only take one audio and one video stream. In your case that's taken from the first file only.

You need to map the streams correctly:

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

Some notes:

  • The order mapping options determine which streams from the input are mapped to the output.
  • 0:v:0 is the first video stream of the first file and 1:a:0 is the first audio stream of the second file. The v/a are not strictly necessary, but in case your input files contain multiple streams, that helps to disambiguate. More info about mapping can be found on the FFmpeg Wiki.
  • If your audio stream is longer than the video file, or vice-versa, you can use the -shortest option to have ffmpeg stop the conversion when the shorter of the two ends.
  • -c copy copies the audio and video streams. This means that the process will be fast and the quality will be the same. But when adding, say, WAV audio to an existing video file, it'd be better to compress that audio first. For example:

    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
    

    Here, we only copy the video stream (-c:v copy), and re-encode the audio stream with the ffmpeg built-in AAC encoder (-c:a aac) at 192 kBit/s.

  • If your output format does not support a particular codec (e.g., when adding WAV to MP4, or AAC to AVI, etc.), re-encoding is also required.
Share:
96,392
Arlen Beiler
Author by

Arlen Beiler

I like programming, astronomy, history, language, and music. Come unto me, all ye that labor and are heavy laden, and I will give you rest. Take my yoke upon you and learn of me for I am meek and lowly in heart and ye shall find rest unto your soul. For my yoke is easy and my burden is light.

Updated on September 18, 2022

Comments

  • Arlen Beiler
    Arlen Beiler 8 months

    I’m trying to add sound to a video using FFmpeg, but for some reason, when I play the resulting file, it doesn't have any sound. I also tried doing it with an aac audio file, as well as leaving out -acodec copy and giving it a wav file.

    Here is the complete output:

    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
    Arlen Beiler about 10 years
    Thank you very much, that works perfect. What's the -c copy? Is that shorthand for -acodec copy -vcodec copy?
  • slhck
    slhck about 10 years
    Yeah, basically it tells it to copy all kinds of streams – this also includes subtitles.
  • erik
    erik over 9 years
    To see how the streams are named/referenced in your input videos (e.g. if you have a video with multichannel audio), you can just start ffmpeg with one or several input file(s) – and nothing else. Than all the streams are listed and named 0:0, 0:1, 0:2, 1:0, 1:1 and so on. Example: ffmpeg -i videofile.mp4 -i anothervideofile.mp4
  • Akash Dubey
    Akash Dubey almost 6 years
    out of curiosity what if the audio or video length are not same! does video remains same and audio length automatically matches with video size!
  • slhck
    slhck almost 6 years
    @Akash ffmpeg will always use the longer of the two streams and add black video or silent audio at the end. Unless you specify the -shortest option, in which case the shortest stream terminates the encoding process.
  • Akash Dubey
    Akash Dubey almost 6 years
    Thanks for quick reply, May I know where to add -shortest in the above command whether it goes like this - ffmpeg -i input.mp4 -i input.mp3 -c copy -map 0:0 -map 1:0 -shortest output.mp4
  • slhck
    slhck almost 6 years
    @AkashDubey That's how you use it, yes. Anywhere between -i <input> and the output file.
  • Akash Dubey
    Akash Dubey almost 6 years
    I have used this command for changing audio stream of a video file but it throws : Output file #0 does not contain any stream
  • Akash Dubey
    Akash Dubey almost 6 years
    Output #0, mp4, to 'ffmpeg -i /document/video:4632 -i /document/audio:4650 -c copy -map 0:v:0 -map 1:a:0 /storage/emulated/0/output.mp4': Output file #0 does not contain any stream
  • slhck
    slhck almost 6 years
    @AkashDubey Please ask a new question including the full command-line log. Make sure your input files actually contain audio and video, and that you use a recent ffmpeg version.
  • Akash Dubey
    Akash Dubey almost 6 years
  • android developer
    android developer about 4 years
    @slhck What if the input audio file is shorter than the input video file, but I want the output video file to always have the same duration as the input video file, while having the audio content to loop ?
  • slhck
    slhck about 4 years
    @androiddeveloper You can use the -stream_loop option for the audio part: video.stackexchange.com/a/23402/525
  • android developer
    android developer about 4 years
    @slhck Thank you . I got it here: superuser.com/a/1319950/152400 , github.com/umair13adil/KotlinFFMpeg/issues/11 . Gave you +1 for helping .
  • Carson
    Carson over 1 year
    -shortest option will make the output the same duration as the shortest input.