<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Video Processing on KnightLi Blog</title>
        <link>https://knightli.com/en/tags/video-processing/</link>
        <description>Recent content in Video Processing on KnightLi Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <lastBuildDate>Thu, 02 Apr 2026 23:14:03 +0800</lastBuildDate><atom:link href="https://knightli.com/en/tags/video-processing/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>FFmpeg `-map` Explained: Precisely Select Video, Audio, and Subtitle Streams</title>
        <link>https://knightli.com/en/2026/04/02/ffmpeg-map-parameter-guide/</link>
        <pubDate>Thu, 02 Apr 2026 23:14:03 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/04/02/ffmpeg-map-parameter-guide/</guid>
        <description>&lt;p&gt;In multi-audio and multi-subtitle workflows, &lt;code&gt;-map&lt;/code&gt; is one of FFmpeg&amp;rsquo;s most important and most frequently misused options.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t explicitly specify &lt;code&gt;-map&lt;/code&gt;, FFmpeg auto-selects streams using default rules, and the output is often not what you expect. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Subtitles disappear after export&lt;/li&gt;
&lt;li&gt;The wrong language track is selected&lt;/li&gt;
&lt;li&gt;Unwanted data streams are included&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This article uses common real-world scenarios to explain how &lt;code&gt;-map&lt;/code&gt; works.&lt;/p&gt;
&lt;h2 id=&#34;first-understand-what-a-stream-is&#34;&gt;First, Understand What a &amp;ldquo;Stream&amp;rdquo; Is
&lt;/h2&gt;&lt;p&gt;A container file (such as &lt;code&gt;mp4&lt;/code&gt; or &lt;code&gt;mkv&lt;/code&gt;) usually contains multiple streams, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Video streams (&lt;code&gt;v&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Audio streams (&lt;code&gt;a&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Subtitle streams (&lt;code&gt;s&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Attachment/data streams (fonts, cover art, chapters, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can inspect streams with &lt;code&gt;ffprobe&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffprobe -hide_banner input.mkv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;basic--map-syntax&#34;&gt;Basic &lt;code&gt;-map&lt;/code&gt; Syntax
&lt;/h2&gt;&lt;p&gt;Most common pattern:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-map input_index[:stream_type][:stream_index]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;0:v&lt;/code&gt;: all video streams from the 1st input&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0:a:0&lt;/code&gt;: the 1st audio stream from the 1st input&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1:s:1&lt;/code&gt;: the 2nd subtitle stream from the 2nd input&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;input_index&lt;/code&gt; starts from &lt;code&gt;0&lt;/code&gt;, based on &lt;code&gt;-i&lt;/code&gt; order&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stream_index&lt;/code&gt; also starts from &lt;code&gt;0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;practical-examples&#34;&gt;Practical Examples
&lt;/h2&gt;&lt;h3 id=&#34;1-video-from-a-audio-from-b&#34;&gt;1) Video from A, audio from B
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffmpeg -i english.mp4 -i french.mp3 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -map 0:v:0 -map 1:a:0 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -c:v copy -c:a aac &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  french.mp4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Meaning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use the first video stream from &lt;code&gt;english.mp4&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use the first audio stream from &lt;code&gt;french.mp3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Merge into &lt;code&gt;french.mp4&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-keep-all-streams-from-input-1-then-add-one-more-audio-track&#34;&gt;2) Keep all streams from input 1, then add one more audio track
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffmpeg -i english.mp4 -i french.mp3 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -map &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; -map 1:a:0 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -c copy &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  english-french.mp4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Meaning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-map 0&lt;/code&gt; keeps all streams from the first input&lt;/li&gt;
&lt;li&gt;Then append the first audio stream from the second input&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;two-useful-advanced-tricks&#34;&gt;Two Useful Advanced Tricks
&lt;/h2&gt;&lt;h3 id=&#34;1-negative-mapping-exclude-unwanted-streams&#34;&gt;1) Negative mapping: exclude unwanted streams
&lt;/h3&gt;&lt;p&gt;For example, keep everything from input 1 but remove its second audio stream:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffmpeg -i input.mkv -map &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; -map -0:a:1 -c copy output.mkv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;2-optional-mapping-dont-fail-when-a-stream-is-missing&#34;&gt;2) Optional mapping: don&amp;rsquo;t fail when a stream is missing
&lt;/h3&gt;&lt;p&gt;If some files may not have subtitles, use &lt;code&gt;?&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ffmpeg -i input.mp4 -map 0:v -map 0:a -map 0:s? -c copy output.mp4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;0:s?&lt;/code&gt; means: map subtitles if present; otherwise skip without error.&lt;/p&gt;
&lt;h2 id=&#34;common-pitfalls&#34;&gt;Common Pitfalls
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;Once you use &lt;code&gt;-map&lt;/code&gt;, FFmpeg stops automatic stream selection, so you must map everything you need.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-c copy&lt;/code&gt; only remuxes without transcoding. If the target container doesn&amp;rsquo;t support a codec, it still fails.&lt;/li&gt;
&lt;li&gt;With multiple inputs, index mistakes are common. Input indices are determined only by &lt;code&gt;-i&lt;/code&gt; order.&lt;/li&gt;
&lt;li&gt;For robust scripts, inspect with &lt;code&gt;ffprobe&lt;/code&gt; first, then generate &lt;code&gt;-map&lt;/code&gt; dynamically.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;The core idea of &lt;code&gt;-map&lt;/code&gt; is simple: explicitly tell FFmpeg which input to use, what stream type to pick, and which stream index to select.&lt;/p&gt;
&lt;p&gt;Once you master this, you can reliably handle complex cases like multi-audio, multi-subtitle, and cross-file stream composition.&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
