audiovideocmdffmpegmkv

Extract every audio and subtitles from a video with ffmpeg


I have multiple audio tracks and subtitles to extract in a single .mkv file. I'm new to ffmpeg commands, this is what I've tried (audio):

ffmpeg -i VIDEO.mkv -vn -acodec copy AUDIO.aac

It just extract 1 audio. What I want is tell ffmpeg to extract every single audio files and subtitle files to a destination, and keep the original name of each files and extensions. (Because I don't know which extension does the audio files are, sometimes maybe .flac or .aac).

I'm not sure about the solutions I'd found online, because it's quite complicated, and I need explanations to know how it's works, so that I can manipulate the command in the future. By the way, I planned to run the code from Windows CMD.

Thanks.


Solution

  • There is no option yet in ffmpeg to automatically extract all streams into an appropriate container, but it is certainly possible to do manually.

    You only need to know the appropriate containers for the formats you want to extract.

    Default stream selection only chooses one stream per stream type, so you have to manually map each stream with the -map option.

    1. Get input info

    Using ffmpeg or ffprobe you can get the info in each individual stream, and there is a wide variety of formats (xml, json, cvs, etc) available to fit your needs.

    ffmpeg example

    ffmpeg -i input.mkv
    

    The resulting output (I cut out some extra stuff, the stream numbers and format info are what is important):

    Input #0, matroska,webm, from 'input.mkv':
      Metadata:
      Duration: 00:00:05.00, start: 0.000000, bitrate: 106 kb/s
        Stream #0:0: Video: h264 (High 4:4:4 Predictive), yuv444p, 320x240 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
        Stream #0:1: Audio: vorbis, 44100 Hz, mono, fltp (default)
        Stream #0:2: Audio: aac, 44100 Hz, mono, fltp (default)
        Stream #0:3: Audio: flac, 44100 Hz, mono, fltp (default)
        Stream #0:4: Subtitle: ass (default)
    

    ffprobe example

    ffprobe -v error -show_entries stream=index,codec_name,codec_type input.mkv
    

    The resulting output:

    [STREAM]
    index=0
    codec_name=h264
    codec_type=video
    [/STREAM]
    [STREAM]
    index=1
    codec_name=vorbis
    codec_type=audio
    [/STREAM]
    [STREAM]
    index=2
    codec_name=aac
    codec_type=audio
    [/STREAM]
    [STREAM]
    index=3
    codec_name=flac
    codec_type=audio
    [/STREAM]
    [STREAM]
    index=4
    codec_name=ass
    codec_type=subtitle
    [/STREAM]
    

    2. Extract the streams

    Using the info from one of the commands above:

    ffmpeg -i input.mkv \
    -map 0:v -c copy video_h264.mkv \
    -map 0:a:0 -c copy audio0_vorbis.oga \
    -map 0:a:1 -c copy audio1_aac.m4a \
    -map 0:a:2 -c copy audio2.flac \
    -map 0:s -c copy subtitles.ass
    

    In this case, the example above is the same as:

    ffmpeg -i input.mkv \
    -map 0:0 -c copy video_h264.mkv \
    -map 0:1 -c copy audio0_vorbis.oga \
    -map 0:2 -c copy audio1_aac.m4a \
    -map 0:3 -c copy audio2.flac \
    -map 0:4 -c copy subtitles.ass
    

    Container formats

    A partial list to match the stream with the output extension for some common formats:

    Video Format Extensions
    H.264 .mp4, .m4v, .mov, .h264, .264
    H.265/HEVC .mp4, .h265, .265
    VP8/VP9 .webm
    AV1 .mp4
    MPEG-4 .mp4, .avi
    MPEG-2 .mpg, .vob, .ts
    DV .dv, .avi, .mov
    Theora .ogv/.ogg
    FFV1 .mkv
    Almost anything .mkv, .nut
    Audio Format Extensions
    AAC .m4a, .aac
    MP3 .mp3
    PCM .wav
    Vorbis .oga/.ogg
    Opus .opus, .oga/.ogg, .mp4
    FLAC .flac, .oga/.ogg
    Almost anything .mka, .nut
    Subtitle Format Extensions
    Subrip/SRT .srt
    SubStation Alpha/ASS .ass