Up until recently I used Quicktime to switch audio tracks for the odd music and showreel video, but since it will no longer be updated for Windows, and can possibly lead to your PC getting the clap, I figured I'd better find an alternative option. Enter ffmpeg. It's a very powerful, free command line tool that I'd previously only worked with in tandem with some sort of GUI or partner app, and had never really tried to work with it on its own due to its bewildering plethora of options. But after a little trial and error I've settled on the following commands to replace audio streams in video files, (re)encoding where necessary, and avoiding video transcoding if possible in order to retain video image quality.
I installed ffmpeg using Chocolatey, a very useful package manager for Windows, similar in operation to those you'd find on Linux (well, it's not quite as good as APT or DNF/YUM, say, but it's the best we've got at the moment).
In Windows 10, you can shift-right click in the Explorer directory that houses your video file to open a command window (just select the very handy 'Open command window here' option).
Firstly, if you'd like to strip the audio from a video file, you can use this command:
ffmpeg -i INPUT.mp4 -codec copy -an OUTPUT.mp4
Specifying the INPUT and OUTPUT files accordingly, with file extension (needless to say, it doesn't have to be .mp4).
-i
precedes the file you wish to strip the audio from.-codec copy
is to send the video stream to the output file
without transcoding, which will maintain video quality, as well as save you
loads of time not having to crunch video.
-an
will remove the audio file. Similarly, you could use
-vn
to remove a video stream instead.
Then you can add your audio track by typing:
ffmpeg -i INPUT.mp4 -i AUDIO.wav -shortest -c:v copy -c:a aac -b:a 256k
OUTPUT.mp4
As you can see, I have two input streams to be muxed together, the silent video file and the audio wav, to the output file at the end of the command. But there are a couple of other handy commands involved this time.
-c
is a shorthand of the -codec
command we used in
the first example, and is used here to specify the audio and video codecs
individually. As before, the video is passed through, but I've chosen to
encode the audio as an aac file instead of simply adding the wav audio to the
video, and have specified the audio bitrate using -b:a
.
The -shortest
option will truncate whichever stream between the
audio and video is longest down to the length of the shortest. This is handy
for crudely chopping audio down to the video length, say.
So far so good, but you might be wondering if you can just combine those two commands into a single command for even quicker results. Absolutely:
ffmpeg -i INPUT.mp4 -i AUDIO.wav -map 0:0 -map 1:0 -c:v copy -c:a aac -b:a
256k -shortest OUTPUT.mp4
This time we use the -map
commands to specify which streams from
the input files respectively should be included the output file. Any stream
not explicitly specified will be ignored. I think the left side of
the map option denotes the input file index (according to the order in which
they were typed in the command), and the right side is the stream ID within
the file. You can always check the stream IDs by running ffmpeg specifying
only an input file and no output, which will just list all the streams in the
media file. Similarly, you could also check the streams in something like
VideoLAN, too.
Anyway, I hope this post is useful. If nothing else, it's a good way for me to consolidate tips for myself (isn't that termed 'Ako', or something?) and help me remember for future use.