e42.uk Circle Device

 

Quick Reference

Extract Audio from a Video File

This operation is possible in a number of different ways and choosing the correct one depends on you, the aim and the format of the audio stream in the file

Lossy... or is it? (dump then code)

First dump the audio from the file using a standard mplayer command:

mplayer videofile.avi -ao pcm:waveheader:file=output.wav

Or with mpv

mpv --no-video --speed=0.75 --ao=pcm --ao-pcm-waveheader=yes \
    --ao-pcm-file=audiodump.wav inputfilename.mp4

Then encode it with lame, faac (or flac for lossless but a big file!)

# lame
lame -abr -b 128 -q 9 output.wav
# faac
faac -w output.wav
# flac
flac output.wav

All these commands will produce a file with the same name but a different extension, .mp3, .m4a or .flac respectively.

For Gentoo users, the above commands reside in the following packages... though I am sure you could have easily worked it out!

media-libs/lame
media-libs/flac
media-libs/faac

Lossless when Container Required (no encoding)

Simple when you use FFMPEG, this will work to just dump the audio into a container. If the audio track is AAC thie file needs a container or mplayer will not be able to play it.

ffmpeg -i videoplayback -acodec copy -vn audiofile.mp4

Just dump from the stream

If the audio is already in a recognisable format... i.e. a media player can detect what it is and play it without the need for a container (mp3 is one) then you can ask MPlayer to dump the raw stream for you.

mplayer -dumpaudio -dumpfile rawstream.mp3 myvideofile.avi

It is likely that the file will be useless if it is not MP3... even RAW PCM won't work unless you provide additional command line parameters.

Get m4a out of mp4 file

ffmpeg -i input.mp4 -vn -c:a copy output.m4a

Or if you want to encode the audio, for example if the audio is in Opus format and your phone cannot play Opus (my Blackberry can't).

ffmpeg -i input.mp4 -c:a libfdk_aac -b:a 128k output.m4a

The -vn switch in the first example is something to do with not copying the video. The man page says: "Disable Video Recording".

Write Plain 16bit WAV from Video Section

ffmpeg -i MyVideo.mp4 -ss 1:19:10 -t 5:0.0 -f wav -acodec pcm_s16le Audio.wav

Encoding m4a from a wav file (with libavcodec)

Encode a wav file using libavcodec aac (rather than libfdk_aac)

$ ffmpeg -i input.wav -c:a aac -b:a 128k output.m4a

mplayer play section of file

Play a section of a file with MPlayer. Below will play 3.5 seconds at 19 minutes 19 seconds into the file... this may not be quite what you get because of keyframes etc so you may have to dump to a raw format first.

$ mplayer -ss 0:19:19 -endpos 3.5 <filename>

And maybe save the sound to a file...

$ mplayer -ss 0:19:19 -endpos 3.5 -ao \
pcm:waveheader:file=<filename> <filename>

You may also do something similar with ffmpeg, if you want to save just a bit of a movie or TV programme... like the starting theme for Eiken Club.

$ ffmpeg -ss 00:02:56 -i \[V-A\]_Eiken_-_01_\[D0246097\]_\[x264\].mkv \
-t 00:01:32 -vn -c:a libfdk_aac -b:a 128k ~/eiken_start.m4a

Normalisation

Sometimes the volume on the encoded audio file is not loud enough, this is quite common and to fix it you need to "normalise" the sound. This is quite easy but is a two step process, first add the filter argument for audio to the command line using the volumedetect filter:

$ ffmpeg -ss 00:02:55 -i \[V-A\]_Eiken_-_01_\[D0246097\]_\[x264\].mkv -t \
    00:01:32 -filter:a "volumedetect" -vn -c:a libfdk_aac -b:a 128k \
    ~/eiken_start.m4a

$ ffmpeg -i Eiken-01_x264.mkv -ss 00:02:55 -t 00:01:32 \
    -filter:a "volumedetect" -vn -c:a pcm_s16le eiken_start.wav

Then look for the line that tells you the max_volume, it should look a little like this:

[Parsed_volumedetect_0 @ 0x2874410] max_volume: -6.2 dB

Invert the number (remove the -) and use that value in the encoding line like so:

$ ffmpeg -ss 00:02:56 -i \[V-A\]_Eiken_-_01_\[D0246097\]_\[x264\].mkv \
    -t 00:01:32 -filter:a "volume=6.4dB" -vn -c:a libfdk_aac -b:a 128k \
    ~/eiken_start.m4a

Removing the mov_text stream

Some output files may contain a mov_text stream even after you spend some time playing with -map 0:1 etc. I found that to remove this stream on my Eiken encodes all I needed to do was add an odd switch to the command line -map_chapters -1. This works well in my situation and I found it in a comment on StackOverflow (see references if you are interested). The final command looks like this:

$ ffmpeg -ss 00:27:07 -i \[V-A\]_Eiken_-_01_\[D0246097\]_\[x264\].mkv \
    -map_chapters -1 -t 00:01:35 -filter:a "volume=6.4dB" -vn -sn \
    -c:a libfdk_aac -b:a 128k ~/eiken_end.m4a

Naturally there is no need to include this command for the first pass as you are only detecting the range of the audio amplitude. You may find the -map switch useful also, there is a nice description on the FFMPEG trac website... in references below also.

Merging Audio with a Video File

ffmpeg -i InputFileV.mp4 -i InputFileA.m4a \
    -c:v copy -c:a copy \
    -map 0:v:0 -map 1:a:0 OutputFile.mp4

Here we take the input files InputFileV.mp4 and InputFileA.m4a in the -map arguments refer to the file number, (0 = InputFileV.mp4) then the type of stream (v = Video) and finally stream number (0 = First stream of specified type, video, in file).

Mapping is fairly involved, please see more detail in the references.

References

Quick Links: Techie Stuff | General | Personal | Quick Reference