How to merge two audio files while retaining correct timings with ffmpeg

2.8k views Asked by At

Disclaimer: I don't understand ffmpeg and mostly just copy commands

I have two webm video files. Their duration is off by about a second.

I converted these to mp4 and everything was fine:

ffmpeg -acodec libopus -i 1.webm -r 10 -cpu-used 5 -c:v libx264 -crf 20 -c:a aac -strict experimental -loglevel error 1.mp4

I then extracted the audio from each video and everything was fine. By fine, I mean, when I playback the audio files by themselves they match the timings on the original video. I used this command to extract the audio:

fmpeg -i 1.mp4 -map 0:a -vn -acodec copy 1audio.m4a

I now have two audio tracks and I want to combine them into one, I want to "overlay" them, AND I want to keep the timings the same as they were.

BUT, whenever I try and combine the audio the timings are off. The "seconds" don't match the original single audio files.

I have tried these commands to merge the audio:

ffmpeg -i 1audio.m4a -i 2audio.m4a -filter_complex "[0:a][1:a]amerge=inputs=2[a]" -map [a] -c:a libfdk_aac mergedaudio.m4a

ffmpeg -i 2audio.m4a -i 1audio.m4a -filter_complex amix=inputs=2:duration=first mergedaudio.m4a

ffmpeg -i 1audio.m4a -i 2audio.m4a -filter_complex amerge -ac 2 -c:a libfdk_aac -vbr 4 mergedaudio.m4a

All the above command have resulted in a merged audio file... but the timings are off.

What am I doing wrong?

1

There are 1 answers

0
andy On

I found the issue and the question is flawed but worth answering.

The issue is, before merging, the two audio files had start timestamps > 0.

But when the files got merged, they got "zeroed", thus their delayed start times were ignored and the audio started too early.

The solution then is to encode the audio again, but this time add a delay equal to the start delay so that when it gets zeroed you have the padding you need.

So lets run through that again:

  1. You start with two acc files which for whatever reason have start times of 3 and 5 seconds respectively.

  2. Next you "zero" each file:

ffmpeg -i 1audio.m4a -filter_complex "[0:a]adelay=3000[a0];[a0]amix=inputs=1[out]" -map "[out]" -ac 2 -c:a libfdk_aac 1zeroed.m4a

ffmpeg -i 2audio.m4a -filter_complex "[0:a]adelay=5000[a0];[a0]amix=inputs=1[out]" -map "[out]" -ac 2 -c:a libfdk_aac 2zeroed.m4a

The new audio files, 1zeroed and 2zeroed now have a 0 start time, but during the encoding padding was added so when each play, the audio only starts when it's supposed to.

Now when you merge the two files, everything is super cool! :-)

ffmpeg -i 1zeroed.m4a -i 2zeroed.m4a -filter_complex amerge -ac 2 -c:a libfdk_aac -vbr 4 mergedaudio.m4a