108

I would like to place the audio from a video to another video without an audio (in one command):

ffmpeg.exe -i video1_noAudio.mov -i video2_wAudio.mov -vcodec copy -acodec copy video1_audioFromVideo2.mov

I guess "-map" is the correct way to do it but I got confused with it.

Can you suggest how to resolve it?

blackgreen
  • 34,072
  • 23
  • 111
  • 129
Mark
  • 1,540
  • 2
  • 13
  • 21
  • Same question on SU: [How to merge audio and video file in ffmpeg - Super User](https://superuser.com/questions/277642/how-to-merge-audio-and-video-file-in-ffmpeg) – user202729 May 15 '22 at 14:58

3 Answers3

299

Overview of inputs

input_0.mp4 has the desired video stream and input_1.mp4 has the desired audio stream:

mapping diagram

In ffmpeg the streams look like this:

$ ffmpeg -i input_0.mp4 -i input_1.mp4

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input_0.mp4':
  Duration: 00:01:48.50, start: 0.000000, bitrate: 4144 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720, 4014 kb/s, SAR 115:87 DAR 1840:783, 23.98 fps, 23.98 tbr, 16k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 124 kb/s (default)

Input #1, mov,mp4,m4a,3gp,3g2,mj2, from 'input_1.mp4':
  Duration: 00:00:30.05, start: 0.000000, bitrate: 1754 kb/s
    Stream #1:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 720x480 [SAR 8:9 DAR 4:3], 1687 kb/s, 59.94 fps, 59.94 tbr, 60k tbn, 119.88 tbc (default)
    Stream #1:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 55 kb/s (default)

ID numbers

ffmpeg refers to input files and streams with index numbers. The format is input_file_id:input_stream_id. Since ffmpeg starts counting from 0, stream 1:1 refers to the audio from input_1.mp4.

Stream specifiers

This can be enhanced with stream specifiers. For example, you can tell ffmpeg that you want the first video stream from the first input (0:v:0), and the first audio stream from the second input (1:a:0). I prefer this method because it's more efficient. Also, it is less prone to accidental mapping because 1:1 can refer to any type of stream, while 2:v:3 only refers to the fourth video stream of the third input file.

Examples

The -map option instructs ffmpeg what streams you want. To copy the video from input_0.mp4 and audio from input_1.mp4:

$ ffmpeg -i input_0.mp4 -i input_1.mp4 -c copy -map 0:0 -map 1:1 -shortest out.mp4

This next example will do the same thing:

$ ffmpeg -i input_0.mp4 -i input_1.mp4 -c copy -map 0:v:0 -map 1:a:0 -shortest out.mp4
  • -map 0:v:0 can be translated as: from the first input (0), select video stream type (v), first video stream (0)

  • -map 1:a:0 can be translated as: from the second input (1), select audio stream type (a), first audio stream (0)

Additional Notes

Fernando Espinosa
  • 4,625
  • 1
  • 30
  • 37
llogan
  • 121,796
  • 28
  • 232
  • 243
  • I agree that it's safer to use `0:v:0` and `1:a:0`, because `0:0` isn't always video, and `0:1` isn't always audio. I recorded a Quicktime video that set `0:0` as audio, `0:1` as video. – wisbucky May 18 '20 at 06:14
  • fix: has to be `-map 0:0 -map 1:0` in order to be equivalent to `-map 0:v:0 -map 1:a:0` – Fernando Espinosa Jul 07 '20 at 06:03
7

The accepted answer is an excellent explanation of ffmpeg's flexible stream selection using the -map option.

However, the documentation linked above also describes a simpler syntax to do what the questioner asks, without -map:

ffmpeg -an -i video1_noAudio.mov -vn -i video2_wAudio.mov -c:a copy -c:v copy video1_audioFromVideo2.mov

Here -an means discard any audio from the first input file, -vn discards any video from the audio recording. ffmpeg then combines them in the obvious way to produce a single output file.

(-c:a and -c:v are just alternatives for -acodec and -vcodec in the question, which can be used to copy for speed, or re-encode a stream if needed. -c copy matches all streams, so is a shorter equivalent for both options.)

Extra options to consider

Without any further options, if the two streams are of different length, they are included in their entirety. If the audio stream is shorter than the video, the player should continue silently. If the video is shorter it should display the final frame or black.

If you want to stop with the shortest stream, add -shortest, or to stop at another point, use -to and a position argument. If an audio track is incidental music, you can also repeat it one or more times with -stream_loop. For example:

ffmpeg -an -i video1_noAudio.mov -vn -stream_loop 1 -i video2_wAudio.mov -to 8:02 -c copy video1_audioFromVideo2.mov

Re-encoding options can also be added in place of copy if a particular format of finished file is required.

Cedric Knight
  • 249
  • 2
  • 4
  • I tried this solution and it's works . – Salem Aug 18 '22 at 19:03
  • If final video and audio are not the same in length there should also be a -shortest correct? – Ricardo Bohner May 07 '23 at 12:05
  • 1
    @RicardoBohner You can add `-shortest` if that is the effect you desire. That wasn't in the original question, so I assume it would only complicate the answer. Without `-shortest`, a player should pad short audio with silence; or a shorter video would be padded with the final frame or black; those at least preserve all the input streams. An alternative for different lengths might be to apply `-stream_loop 2` to the shorter stream, and instead of `-shortest` maybe `-to` to trim to a particular point. Many options are possible. – Cedric Knight May 07 '23 at 18:41
2

I have a new command for merging audio to video

ffmpeg -i video.mp4 -i audio.mp4 -map 0.0 -map 1.0 -acodec copy -qscale 4 -vcodec mpeg4 outvideo.mp4

-qscale is option set quality to video of ffmpeg

-acodec copy is option copy default quality of audio to output video

-vcodec mpeg4 is option copy default quality of video to output video

HoangHieu
  • 2,802
  • 3
  • 28
  • 44
  • 1
    `-vcodec` has been around forever. It is the same as the newer aliases `-codec:v` and `-c:v`. – llogan Apr 10 '15 at 07:39
  • @HoangHieu can i add wav audio to mp4 video ? i have try `ffmpeg -i 1.mp4 -i 0.wav -map 0 -map 1 -codec copy -shortest new.mp4` the command but not work – Allan Aug 14 '15 at 03:00
  • ?? your command. **0.0** not **0**, **1.0** not **1** - 1.0 it mean: index [1] channel [0]... - **acodec copy** not **-codec copy**, it mean copy audio codec – HoangHieu Aug 14 '15 at 08:31
  • You probably want to `-vcodec copy` to avoid re-encoding the video – wolfd Jul 14 '17 at 00:21