2

I have this file, and would be cool use ffmpeg for extract all audio channels to separate files..

I know how to extract a single channel at time in a way like:

ffmpeg -i input.mov -map 0:1 -c:a copy output.mov

However this will work for the first channel only.

Aside with for $i 0 to 15, is there a way to extract all the audio channels at one in a specific directory?

ffprobe says:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'D:\myfile.mov':
  Metadata:
    creation_time   : 2016-04-25T14:10:57.000000Z
    timecode        : 10:00:00:00
  Duration: 01:30:36.32, start: 0.000000, bitrate: 193036 kb/s
    Stream #0:0(eng): Video: prores (apch / 0x68637061), yuv422p10le(bt709, progressive), 1920x1080, 174295 kb/s, SAR 1:1 DAR 16:9, 25 fps, 25 tbr, 25 tbn, 25 t
bc (default)
    Metadata:
      creation_time   : 2016-04-25T14:10:57.000000Z
      handler_name    : Apple Alias Data Handler
      encoder         : Apple ProRes 422 (HQ)
    Stream #0:1(eng): Data: none (tmcd / 0x64636D74), 0 kb/s (default)
    Metadata:
      creation_time   : 2016-04-25T14:10:57.000000Z
      handler_name    : Apple Alias Data Handler
      reel_name       : Unnamed
      timecode        : 10:00:00:00
    Stream #0:2(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, 16 channels, s32 (24 bit), 18432 kb/s (default)
    Metadata:
      creation_time   : 2016-04-25T14:10:57.000000Z
      handler_name    : Apple Alias Data Handler

Unsupported codec with id 0 for input stream 1

EDIT: It should be something like this..

ffmpeg -i input.mov -filter_complex \
"[0:a]pan=mono|c0=c0[a0]; \
 [0:a]pan=mono|c0=c1[a1]; \
 [0:a]pan=mono|c0=c2[a2]; \
 [0:a]pan=mono|c0=c3[a3]; \
 [0:a]pan=mono|c0=c4[a4]; \
 [0:a]pan=mono|c0=c5[a5]; \
 [0:a]pan=mono|c0=c6[a6]; \
 [0:a]pan=mono|c0=c7[a7]; \
 [0:a]pan=mono|c0=c8[a8]; \
 [0:a]pan=mono|c0=c9[a9]; \
 [0:a]pan=mono|c0=c10[a10]; \
 [0:a]pan=mono|c0=c11[a11]" \
 [0:a]pan=mono|c0=c12[a12]" \
 [0:a]pan=mono|c0=c13[a13]" \
 [0:a]pan=mono|c0=c14[a14]" \
 [0:a]pan=mono|c0=c15[a15]" \

-c copy -c:a pcm_s24le
-map 0 -map -0:a -map "[a0]" audio_00.wav -map "[a1]" audio_01.wav -map "[a2]" audio_02.wav -map "[a3]" audio_03.wav \
-map "[a4]" audio_04.wav -map "[a5]" audio_05.wav -map "[a6]" audio_06.wav -map "[a7]" audio_07.wav \
-map "[a8]" audio_08.wav -map "[a9]" audio_09.wav -map "[a10]" audio_10.wav -map "[a11]" audio_11.wav
-map "[a12]" audio_12.wav -map "[a13]" audio_13.wav -map "[a14]" audio_14.wav -map "[a15]" audio_15.wav
7
  • Not possible...
    – Gyan
    Aug 2, 2017 at 5:01
  • @Mulvya hello Mulvya, it seems to be possible looking this answer: superuser.com/questions/964629/… Aug 2, 2017 at 9:05
  • yes, its possible. Even with channelsplit filter.
    – user12174
    Aug 2, 2017 at 9:40
  • Sorry, I didn't understand at first. I thought you wanted an automatic way to route separate streams into separate outputs. Your example command uses -map 0:1 which maps a stream, not a channel. There's -map_channel which just calls pan. You still have to manually probe # of channels and compose the filtergraph.
    – Gyan
    Aug 2, 2017 at 10:03
  • @Mulvya I see, so I should write in another language a script that could match the # of channels and write the ffmpeg command to be executed, ffmpeg can't do it by itself, is that what you meant ? Aug 2, 2017 at 10:09

2 Answers 2

1

Why not use the channelsplit filter?

First, get audio streams:

ffprobe "$f" 2>&1 | grep Stream | grep Audio
Stream #0:1(eng): Audio: dts (DTS-HD MA), 48000 Hz, 7.1, s32p (24 bit) (default)
Stream #0:2(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s

Choose Stream #0:1 and get layout:

ffmpeg -layouts 2>&1 | grep "7.1"
7.1            FL+FR+FC+LFE+BL+BR+SL+SR
7.1(wide)      FL+FR+FC+LFE+BL+BR+FLC+FRC
7.1(wide-side) FL+FR+FC+LFE+FLC+FRC+SL+SR
7.1(top)       FL+FR+FC+LFE+BL+BR+TFL+TFR

Choose: 7.1 FL+FR+FC+LFE+BL+BR+SL+SR

Use:

"[0:1]channelsplit=channel_layout=7.1[FL][FR][FC][LFE][BL][BR][SL][SR]"

Note that stream 0:1 is in [] . This is how to specify a specific stream out of more than one stream. Note that the channel order follows the chosen layout.

Extract channels as W64 wavs. This insures that output files greater than 4GB don't trigger the error 'Filesize ####### invalid for wav, output file will be broken' . This format is compatible with most DAWs.

ffmpeg -y -i "$f" -vn -sn -map_chapters -1 \
-filter_complex "[0:1]channelsplit=channel_layout=7.1[FL][FR][FC][LFE][BL][BR][SL][SR]" \
-c:a pcm_s32le -map "[FL]" FL.w64 \
-c:a pcm_s32le -map "[FR]" FR.w64 \
-c:a pcm_s32le -map "[FC]" FC.w64 \
-c:a pcm_s32le -map "[LFE]" LFE.w64 \
-c:a pcm_s32le -map "[BL]" BL.w64 \
-c:a pcm_s32le -map "[BR]" BR.w64 \
-c:a pcm_s32le -map "[SL]" SL.w64 \
-c:a pcm_s32le -map "[SR]" SR.w64

4

For me the -map_channel option did the trick: get the file layout using ffprobe multichannelinputfile.mov

ffprobe version 4.1 Copyright (c) 2007-2018 the FFmpeg developers
  built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gpl --enable-libmp3lame --enable-libopus --enable-libsnappy --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-opencl --enable-videotoolbox
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
[aac @ 0x7f903d01fa00] Assuming an incorrectly encoded 7.1 channel layout instead of a spec-compliant 7.1(wide) layout, use -strict 1 to decode according to the specification instead.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'set1permeke.mov':
  Metadata:
    major_brand     : qt
    minor_version   : 0
    compatible_brands: qt
    creation_time   : 2019-01-05T22:00:13.000000Z
    com.apple.quicktime.make: Apple
    com.apple.quicktime.model: MacBookPro15,1
    com.apple.quicktime.software: Mac OS X 10.13.6 (17G4015)
    com.apple.quicktime.creationdate: 2019-01-05T21:58:54+0100
  Duration: 00:57:02.28, start: 0.000000, bitrate: 23693 kb/s
    Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1040 [SAR 1:1 DAR 24:13], 22756 kb/s, 60 fps, 60 tbr, 6k tbn, 12k tbc (default)
    Metadata:
      creation_time   : 2019-01-05T22:00:13.000000Z
      handler_name    : Core Media Video
      encoder         : H.264
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, 7.1, fltp, 928 kb/s (default)
    Metadata:
      creation_time   : 2019-01-05T22:00:13.000000Z
      handler_name    : Core Media Audio
[aac @ 0x7f903d019600] Assuming an incorrectly encoded 7.1 channel layout instead of a spec-compliant 7.1(wide) layout, use -strict 1 to decode according to the specification instead.`

I then mapped all the audio channels to separate files for easier editing in my DAW:

ffmpeg -i multichannelinputfile.mov -map_channel 0.1.0 ch0.wav -map_channel 0.1.1 ch1.wav -map_channel 0.1.2 ch2.wav -map_channel 0.1.3 ch3.wav

and so on producing the required separate wav files.

4
  • 2
    If you have a lot of channels (e.g. 32): printf -v channelmap " -map_channel 0.1.%s -c copy 'OUTPUT_CHANNEL_%02d.wav'" {0..31}{,}; eval ffmpeg -i INPUT.WAV $channelmap
    – Duvrai
    Dec 17, 2019 at 16:13
  • @kaosbeat Can you show the ffprobe command you actually used, to make your answer stand-alone? Feb 12, 2021 at 10:34
  • 1
    @QuantumMechanic it's just "ffprobe filename.mov", It'll try and update it in the answer
    – kaosbeat
    Feb 15, 2021 at 9:31
  • 1
    "The -map_channel option is deprecated and will be removed. It can be replaced by the 'pan' filter, or in some cases by combinations of 'channelsplit', 'channelmap', 'amerge' filters." Jan 9, 2023 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.