I had someone email me asking how to solve the following problem:
I would like to take video A, video B, and replace the audio in video A with the audio from video B
The approach they were trying was as follows:
- Extract only the video from video A
- Extract only the audio from video B, while also transcoding it a codec he needed it to be in
- Merge these two files together
Now, this approach is fine but he encountered an issue. He claimed to need the audio in the a WAV file format but the WAV format wasn't compatible with the codec he needed to transcode the audio into.
So what does he do?
I showed him you can do all this in one command, avoiding this file format issue, while also not creating the intermittent files.
Let me show you the example I showed him and I will break it down.
VIDEO=$1 AUDIO=$2 OUTPUT=$3 ffmpeg -an -i $VIDEO -vn -i $AUDIO -map [0:v] -map [1:a] -c:v copy -c:a pcm_s8_planar $OUTPUT
This is the file he wants to use the video stream from, so in his case its video A.
This is the file he wants to use the audio from, making this video B.
The file path to save the combined result to.
-an -i $VIDEO
The -an option before the input means ignore the audio stream. This will give us only the video stream for this file. It also speeds up the command by avoiding having to read the audio stream.
-vn -i $AUDIO
The -vn option before the input means ignore the video stream. This will give us only the audio stream for this file. It also speeds up the command by avoiding having to read the video stream.
-map [0:v] -map [1:a]
The -map options make it so that we explicitly tell ffmpeg what streams of data to write out to the output, instead of it just figuring it out. This may have not been needed but I'd rather be explicit when I need to be.
-c:v copy -c:a pcm_s8_planar $OUTPUT
The -c:v copy option makes so ffmpeg just copies the video stream over, avoiding a decode and re-encode. This makes it really fast.
the -c:a pcm_s8_planar option transcodes the audio stream to the codec he needed it to be in.
Lastly, we just tell ffmpeg to use the output path given
Drum roll please...
It worked like a charm! He was very happy to be able to continue with his project.