Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save adamarthurryan/3afc8225e50a8738f2b0176669519891 to your computer and use it in GitHub Desktop.
Save adamarthurryan/3afc8225e50a8738f2b0176669519891 to your computer and use it in GitHub Desktop.

Batch recombining audio

ffmpeg

Per this SuperUser thread, the command for recombining an audio track with an mp4 video already containing audio is as follows:

ffmpeg -i 2-2.mp4 -i 2.2.wav -c:v copy -c:a aac -strict experimental -map 0:v:0 -map 1:a:0 render-2.2.mp4

Breaking it down:

  • ffmpeg -i 2-2.mp4 -i 2.2.wav - call ffmpeg with the input video and audio
  • -c:v copy -c:a aac - copy the video channel and encode the audio as AAC
  • -strict experimental - don't know!
  • -map 0:v:0 -map 1:a:0 - file 0 maps to video channel 0 and file 1 maps to audio channel 0
  • render-2.2.mp4 - the output file

Renaming

For this technique, it's best if the files all have the same form of name.

First, I renamed the files with Cygwin's mmv command from names like 2.1. Working From Linux.mp4 to names like 2-1.mp4. (To coorespond to the names I used for the wave files.)

mmv -m "[1-9].[1-9]*.mp4" "#1-#2.mp4"

Batch find and execute

File list

Next thing we need is a command to output the base names of all the MP4 files in the current folder. find lists the files and xargs acts on them. For example, the following command will find all MP4 (-name \*.mp4) files (-type f) in the current folder (. -maxdepth 1), extract the base name (-exec basename {} \.mp4 \;) and pass them off to xargs (| xargs). Then xargs will write them to the console (echo), one per line (-n1), just to demonstrate.

find . -maxdepth 1 -name \*.mp4 -type f -exec basename {} \.mp4 \; | xargs -n1 echo

Building an xargs command

If we want to use the base file names in a command, we can use the xargs insert parameter -I FILENAME. This will replace all subsequent instances of FILENAME with the base names returned by find. So the following command will output a list of all our input files and output files.

find . -maxdepth 1 -name \*.mp4 -type f -exec basename {} \.mp4 \; | xargs -n1 -I FILENAME FILENAME.mp4 FILENAME.wav render-FILENAME.mp4

Putting it all together

Now, we can put all of this together to build a batch recombining command.

find . -maxdepth 1 -name \*.mp4 -type f -exec basename {} \.mp4 \; | xargs -n1 -I FILENAME  ffmpeg -i FILENAME.mp4 -i FILENAME.wav -c:v copy -c:a aac -strict experimental -map 0:v:0 -map 1:a:0 render-FILENAME.mp4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment