Having an MPEG4 (MP4 container, H264 AVC video, AAC audio) video clip downloaded from YouTube, how to separate its audio channel into an independent audio (without de&re-compressing the audio preferably) file with free Linux tools?
2 Answers
Considering Youtube videos, extracting audio from video may not be necessary, as the audio tracks can be downloaded separately as such by using Firefox with the latest Flashgot addon or by using mps-youtube (it is a tool meant to play and download audio tracks from youtube: more here).
Considering mp4 video files:
As answered here, one can us a more generic command without the need for the specific names of the files, and add that to the File Manager custom menu, like:
ffmpeg -i "$0" -map 0:1 -c:a copy "${0%%.*}".m4a
(Using .m4a
is preferable as it is more largely supported as a container for .aac
, but you can use the raw .aac
instead if you wish.)
Also, this command run in a terminal will extract audio tracks from all mp4 files in the current folder:
for i in *.mp4; do ffmpeg -i "${i}" -map 0:1 -c:a copy "${i%.mp4}.m4a"; done
(here the source post)
See comments and related info in the linked answers and questions on how to use such commands in the context-menus of file managers.
Above and other similar commands can be used also for extracting audio from other types of video files, by replacing accordingly the input and output extensions.
The first command works as such for flv
too; but for other video, just replace m4a
with whatever audio is contained by the video clip. The second command needs replacing both video and audio extensions if applied to different types of video files.
Usually, mp4
and flv
files contain aac
audio, Webm
files contain ogg
and avi
files contain mp3
audio. To be sure what audio is contained by the video, use mediainfo
: mediainfo-GUI, or just install mediainfo
and in Terminal: mediainfo <file>
.
If you know there is only 1 audio stream and that it is aac
, then you only need this:
ffmpeg -acodec copy -i "movie.mp4" -y "audio.aac"
If you want to script the first audio stream ID and codec-type/file-extension, you can use this:
eval $(ffmpeg -i "movie.mp4" 2>&1 |awk '/Stream.*Audio/{print "stream=" $2 ";codec=" $4}' |head -n1)
stream=${stream:1}; stream=${stream/:/}
extn=${codec/,/}; [[ $extn == "aac" ]] ||
{ echo "You need to manually set the fiie extension. Codec type is: $codec"; exit 1; }
ffmpeg -map $stream -acodec copy -i "movie.mp4" "audio.$extn"
-
-
1Perhaps
ffmpeg -i
in not outputing a single line which matches/Stream.*Audio/
line... If there is more than one, then to grab the first one, you needeval $(ffmpeg -i "movie.mp4" 2>&1 |awk '/Stream.*Audio/{print "stream=" $2 ";codec=" $4} |head -n1)
.... Otherwise just experiment withffmpeg -i
and see what it needs, or for a one-off, manually enter the correct filetype...– Peter.OApr 11, 2012 at 20:13 -
By the way, do you happen to know a similar trick for FLV files? ffmpeg says "Unable to find a suitable output format for 'audioFile'". Seems it thinks it's webm.– IvanJun 20, 2012 at 0:33