FFmpeg Stream Extraction & Merging

Extract individual streams (audio, video, subtitles) from media files and merge them back together.


List Streams in File

Show All Streams

 1# Detailed stream information
 2ffmpeg -i input.mp4
 3
 4# More detailed (includes codec details)
 5ffprobe -i input.mp4
 6
 7# JSON format (parseable)
 8ffprobe -v quiet -print_format json -show_streams input.mp4
 9
10# Show only specific stream types
11ffprobe -v quiet -select_streams v -show_streams input.mp4  # Video only
12ffprobe -v quiet -select_streams a -show_streams input.mp4  # Audio only
13ffprobe -v quiet -select_streams s -show_streams input.mp4  # Subtitles only
14
15# Compact format
16ffprobe -v error -show_entries stream=index,codec_type,codec_name:stream_tags=language \
17  -of compact input.mp4

Human-Readable Stream List

 1# Show streams in readable format
 2ffprobe -v error -show_entries stream=index,codec_name,codec_type,width,height,channels,sample_rate:stream_tags=language \
 3  -of default=noprint_wrappers=1 input.mp4
 4
 5# Example output:
 6# [STREAM]
 7# index=0
 8# codec_name=h264
 9# codec_type=video
10# width=1920
11# height=1080
12# [/STREAM]
13# [STREAM]
14# index=1
15# codec_name=aac
16# codec_type=audio
17# channels=2
18# sample_rate=48000
19# TAG:language=eng
20# [/STREAM]

Extract Video Stream

Extract Video Only (No Audio)

1# Copy video stream (no re-encoding, fast)
2ffmpeg -i input.mp4 -an -c:v copy output_video.mp4
3
4# Extract specific video stream (if multiple)
5ffmpeg -i input.mkv -map 0:v:0 -c copy output_video.mp4
6
7# Extract and re-encode video
8ffmpeg -i input.mp4 -an -c:v libx264 -crf 23 output_video.mp4

Flags:

  • -an: Remove audio
  • -c:v copy: Copy video without re-encoding
  • -map 0:v:0: Select first video stream

Extract Audio Stream

Extract Audio Only

 1# Copy audio stream (no re-encoding)
 2ffmpeg -i input.mp4 -vn -c:a copy output_audio.m4a
 3
 4# Extract to MP3
 5ffmpeg -i input.mp4 -vn -c:a libmp3lame -b:a 192k output_audio.mp3
 6
 7# Extract to WAV (uncompressed)
 8ffmpeg -i input.mp4 -vn -c:a pcm_s16le output_audio.wav
 9
10# Extract to FLAC (lossless)
11ffmpeg -i input.mp4 -vn -c:a flac output_audio.flac
12
13# Extract to Opus
14ffmpeg -i input.mp4 -vn -c:a libopus -b:a 128k output_audio.opus

Extract Specific Audio Track

1# Extract first audio track
2ffmpeg -i input.mkv -map 0:a:0 -c copy audio_track1.m4a
3
4# Extract second audio track
5ffmpeg -i input.mkv -map 0:a:1 -c copy audio_track2.m4a
6
7# Extract audio track by language
8ffmpeg -i input.mkv -map 0:m:language:eng -c copy audio_english.m4a

Flags:

  • -vn: Remove video
  • -c:a copy: Copy audio without re-encoding
  • -map 0:a:0: Select first audio stream
  • -map 0:a:1: Select second audio stream

Extract Subtitles

Extract Subtitle Tracks

 1# Extract first subtitle track to SRT
 2ffmpeg -i input.mkv -map 0:s:0 output.srt
 3
 4# Extract all subtitle tracks
 5ffmpeg -i input.mkv -map 0:s -c copy output_%d.srt
 6
 7# Extract subtitle by language
 8ffmpeg -i input.mkv -map 0:m:language:eng subtitle_english.srt
 9
10# Extract to ASS format
11ffmpeg -i input.mkv -map 0:s:0 output.ass
12
13# Extract to VTT (WebVTT)
14ffmpeg -i input.mkv -map 0:s:0 output.vtt
15
16# Extract embedded subtitles (e.g., from MP4)
17ffmpeg -i input.mp4 -map 0:s:0 -c copy output.srt

Extract Image-Based Subtitles (DVD/Blu-ray)

1# Extract DVD subtitles (VobSub)
2ffmpeg -i input.mkv -map 0:s:0 -c copy output.sub
3
4# Extract PGS subtitles (Blu-ray)
5ffmpeg -i input.mkv -map 0:s:0 -c copy output.sup

Extract Multiple Streams

Extract All Streams Separately

 1# Extract video
 2ffmpeg -i input.mkv -map 0:v:0 -c copy video.mp4
 3
 4# Extract all audio tracks
 5ffmpeg -i input.mkv -map 0:a:0 -c copy audio1.m4a
 6ffmpeg -i input.mkv -map 0:a:1 -c copy audio2.m4a
 7
 8# Extract all subtitles
 9ffmpeg -i input.mkv -map 0:s:0 subtitle1.srt
10ffmpeg -i input.mkv -map 0:s:1 subtitle2.srt

Batch Extract Script

 1#!/bin/bash
 2# Extract all streams from a file
 3
 4INPUT="input.mkv"
 5
 6# Extract video
 7ffmpeg -i "$INPUT" -map 0:v:0 -c copy video.mp4
 8
 9# Extract audio tracks
10for i in {0..9}; do
11  ffmpeg -i "$INPUT" -map 0:a:$i -c copy "audio_$i.m4a" 2>/dev/null || break
12done
13
14# Extract subtitles
15for i in {0..9}; do
16  ffmpeg -i "$INPUT" -map 0:s:$i "subtitle_$i.srt" 2>/dev/null || break
17done

Merge Streams

Merge Video and Audio

1# Merge video and audio (copy both)
2ffmpeg -i video.mp4 -i audio.m4a -c copy output.mp4
3
4# Merge with specific mapping
5ffmpeg -i video.mp4 -i audio.m4a -map 0:v -map 1:a -c copy output.mp4
6
7# Merge and re-encode audio
8ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -b:a 192k output.mp4

Merge Multiple Audio Tracks

 1# Add second audio track
 2ffmpeg -i video.mp4 -i audio1.m4a -i audio2.m4a \
 3  -map 0:v -map 1:a -map 2:a -c copy output.mkv
 4
 5# Set audio track metadata
 6ffmpeg -i video.mp4 -i audio_eng.m4a -i audio_spa.m4a \
 7  -map 0:v -map 1:a -map 2:a -c copy \
 8  -metadata:s:a:0 language=eng -metadata:s:a:0 title="English" \
 9  -metadata:s:a:1 language=spa -metadata:s:a:1 title="Spanish" \
10  output.mkv

Merge with Subtitles

 1# Add subtitle track
 2ffmpeg -i video.mp4 -i subtitle.srt -c copy -c:s mov_text output.mp4
 3
 4# Add multiple subtitle tracks
 5ffmpeg -i video.mp4 -i sub_eng.srt -i sub_spa.srt \
 6  -map 0:v -map 0:a -map 1:s -map 2:s -c copy -c:s mov_text \
 7  -metadata:s:s:0 language=eng -metadata:s:s:0 title="English" \
 8  -metadata:s:s:1 language=spa -metadata:s:s:1 title="Spanish" \
 9  output.mp4
10
11# For MKV (supports more subtitle formats)
12ffmpeg -i video.mp4 -i subtitle.srt -c copy -c:s srt output.mkv

Replace Streams

Replace Audio Track

1# Replace audio (keep video)
2ffmpeg -i input.mp4 -i new_audio.m4a -map 0:v -map 1:a -c copy output.mp4
3
4# Replace audio and re-sync (delay audio by 0.5 seconds)
5ffmpeg -i input.mp4 -i new_audio.m4a -map 0:v -map 1:a \
6  -c copy -itsoffset 0.5 output.mp4

Replace Video Track

1# Replace video (keep audio)
2ffmpeg -i input.mp4 -i new_video.mp4 -map 1:v -map 0:a -c copy output.mp4

Remove Stream

 1# Remove audio
 2ffmpeg -i input.mp4 -an -c:v copy output.mp4
 3
 4# Remove video
 5ffmpeg -i input.mp4 -vn -c:a copy output.m4a
 6
 7# Remove subtitles
 8ffmpeg -i input.mkv -map 0 -map -0:s -c copy output.mkv
 9
10# Remove specific audio track (keep others)
11ffmpeg -i input.mkv -map 0 -map -0:a:1 -c copy output.mkv

Advanced Stream Selection

Select by Stream Index

1# Stream indices start at 0
2# Example: input has video(0), audio(1), audio(2), subtitle(3)
3
4# Select specific streams
5ffmpeg -i input.mkv -map 0:0 -map 0:2 -c copy output.mkv  # video + audio2
6
7# Select all except one
8ffmpeg -i input.mkv -map 0 -map -0:1 -c copy output.mkv  # Remove audio1

Select by Language

1# Extract English audio
2ffmpeg -i input.mkv -map 0:v -map 0:m:language:eng -c copy output.mkv
3
4# Extract all English streams (audio + subtitles)
5ffmpeg -i input.mkv -map 0:v -map 0:m:language:eng -c copy output.mkv

Select by Codec

1# Select only H.264 video
2ffmpeg -i input.mkv -map 0:v:0 -c:v copy output.mp4
3
4# Select only AAC audio
5ffmpeg -i input.mkv -map 0:a:0 -c:a copy output.m4a

Set Default Stream

Set Default Audio Track

1# Mark first audio as default
2ffmpeg -i input.mkv -map 0 -c copy \
3  -disposition:a:0 default -disposition:a:1 0 output.mkv
4
5# Set second audio as default
6ffmpeg -i input.mkv -map 0 -c copy \
7  -disposition:a:0 0 -disposition:a:1 default output.mkv

Set Default Subtitle Track

1# Mark first subtitle as default
2ffmpeg -i input.mkv -map 0 -c copy \
3  -disposition:s:0 default -disposition:s:1 0 output.mkv

Stream Metadata

Add Metadata to Streams

 1# Set stream titles and languages
 2ffmpeg -i input.mp4 -i audio.m4a -i subtitle.srt \
 3  -map 0:v -map 1:a -map 2:s -c copy -c:s mov_text \
 4  -metadata:s:v:0 title="Main Video" \
 5  -metadata:s:a:0 language=eng -metadata:s:a:0 title="English Audio" \
 6  -metadata:s:s:0 language=eng -metadata:s:s:0 title="English Subtitles" \
 7  output.mp4
 8
 9# Set global metadata
10ffmpeg -i input.mp4 -c copy \
11  -metadata title="My Movie" \
12  -metadata author="Director Name" \
13  -metadata year="2024" \
14  output.mp4

Extract Chapters

List Chapters

1# Show chapters
2ffprobe -v quiet -print_format json -show_chapters input.mkv
3
4# Extract chapter information
5ffprobe -v quiet -show_entries chapter=start_time,end_time:chapter_tags=title \
6  -of compact input.mkv

Extract Chapter as Separate File

1# Extract specific chapter (e.g., chapter 2: 120-240 seconds)
2ffmpeg -i input.mkv -ss 120 -to 240 -c copy chapter2.mkv

Quick Reference

TaskCommand
List streamsffprobe -i input.mp4
Extract videoffmpeg -i input.mp4 -an -c:v copy video.mp4
Extract audioffmpeg -i input.mp4 -vn -c:a copy audio.m4a
Extract subtitleffmpeg -i input.mkv -map 0:s:0 subtitle.srt
Merge video+audioffmpeg -i video.mp4 -i audio.m4a -c copy output.mp4
Add subtitleffmpeg -i video.mp4 -i sub.srt -c copy -c:s mov_text output.mp4
Remove audioffmpeg -i input.mp4 -an -c:v copy output.mp4
Replace audioffmpeg -i input.mp4 -i new_audio.m4a -map 0:v -map 1:a -c copy output.mp4

Tips

  • Use -c copy to avoid re-encoding (faster, no quality loss)
  • Use -map for precise stream selection
  • MKV supports more stream types than MP4
  • Use -metadata:s:a:0 to set metadata for first audio stream
  • Use -disposition:a:0 default to mark stream as default
  • Check stream indices with ffprobe before extraction
  • Use -vn to remove video, -an to remove audio, -sn to remove subtitles

Related Snippets