7

I want my python program to extract the audio tracks from various video files without changing the audio codec. For this I call the following command:

ffmpeg -i "input" -vn -acodec copy "output.???"

However this only works, if the file extension of the output file is known. Is there a way to find out the corresponding file extension?

seenorth
  • 17
  • 1
  • 9
  • 1
    Not possible. There's no mapping from a codec ID to supported containers or raw bitstream muxers. You can sort of work around this by creating a list of supported extensions for each of the common audio codecs (MP3, AAC, PCM, AC3, Opus, Vorbis) and then probing the audio codec of the input and setting the output extension as per the list. – Gyan May 23 '17 at 06:59
  • OK, i'll do that. Thanks for your answer! – seenorth May 23 '17 at 10:17

2 Answers2

2

You can use ffprobe to return the audio information:

ffprobe videofilexample.mp4 would return something like:

ffprobe version 4.0 Copyright (c) 2007-2018 the FFmpeg developers
  built with gcc 8.1.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avresample --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-nvenc --enable-omx --enable-shared --enable-version3
  libavutil      56. 14.100 / 56. 14.100
  libavcodec     58. 18.100 / 58. 18.100
  libavformat    58. 12.100 / 58. 12.100
  libavdevice    58.  3.100 / 58.  3.100
  libavfilter     7. 16.100 /  7. 16.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  1.100 /  5.  1.100
  libswresample   3.  1.100 /  3.  1.100
  libpostproc    55.  1.100 / 55.  1.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'tidalsunday3-2018-05-20_19.43.45':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf57.83.100
  Duration: 00:44:13.40, start: 0.000000, bitrate: 1035 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 3840x2160 [SAR 1:1 DAR 16:9], 782 kb/s, 24 fps, 24 tbr, 12288 tbn, 48 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 247 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286
  • 3
    The default stderr output may be informative as a quick reference, but it is not meant to be parsed by a script. A better solution is to use [`ffprobe` with appropriate options to output only the codec name of the audio stream(s)](https://stackoverflow.com/a/35280871/1109017). In the linked example change `-select_streams v:0` to `-select_streams a` (select all audio streams) or `-select_streams a:0` (select first audio stream only). – llogan Jun 06 '18 at 19:21
0

If you're using python with a small number of input types you might write code to use the filename extension to determine a copy.ext choice?

if filename[-4:] == '.mp4':
    my_ext = '.m4a'  #etc....
outnames = []
for i in range(len(filenames)):
    outnames.append(filenames[i][:-4]+my_ext[i]) #list of .ext

Then create a full 'command list' to pipe through to windows via subprocess.Popen(). When executing use a try:except: block to take any of your first.guess.failures and do a quick '-vn -ab 256k -y' switch and ffmpeg will almost always pick a suitable codec for a fast audio encode.