# [FFmpeg] 音訊聲道處理 ## 聲道編號與布局名稱 ### 查詢各音訊布局各聲道編號 * mono: FC 聲道布局名稱為 `mono`,單聲道,聲道 #0 就是 `FC` * stereo: FL+FR 聲道布局名稱為 `stereo` ,2 聲道。聲道 #0 - 1: `FL`, `FR` * 5.1(side): FL+FR+FC+LFE+SL+SR 聲道布局名稱為 `5.1(side)`,6 聲道,聲道 #0 - 5: `FL`, `FR`, `FC`, `LFE`, `SL`, `SR`。 可用 `-layouts` 查詢得知更多布局: ```powershell ffmpeg -layouts ``` ### 查詢音訊的聲道布局 使用 ffmpeg 讀取影片檔: ```powershell ffmpeg -i movie.mkv ``` 假設輸出結果是這樣: ```text Input #0, matroska,webm, from 'movie.mkv': Duration: 00:40:38.08, start: 0.000000, bitrate: 21128 kb/s Stream #0:0(eng): Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x800 [SAR 1:1 DAR 12:5], 24 fps, 24 tbr, 1k tbn, 48 tbc Stream #0:1(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s Stream #0:3(eng): Subtitle: subrip ``` 由以上結果可知音訊布局是 `5.1(side)` ## 降混聲道 (Dwonmix) 要將聲道以混合的方式由多變少可以使用 `-ac` 選項。當設定的輸出的聲道數量數比輸入還要少時,會以混合輸入聲道的方式減少聲道。 ### 降混 2 聲道以上至立體聲 (stereo) 使用 `-ac 2` 降混為雙聲道: ```powershell ffmpeg -i input.wav -ac 2 output.wav ``` ## 特殊降混 表面上是將多個聲道降混到較少的聲道,但透多聲道的訊息被矩陣編碼給隱藏到輸出的聲道內容之中,特過支援的解碼器或與設備可以將隱藏的多聲道訊息還原回多聲道。 ### 降混 6 聲道以上至 Dolby Pro Logic II 使用 `aresample` 篩選器提供的 `matrix_encoding` 選項降混為 DPL2: ```powershell ffmpeg -i input.wav -ac 2 -af "aresample=matrix_encoding=dplii" output.m4a" ``` ## 提取聲道 ### 提取 1 個聲道為單聲道 (mono) 使用 `channelsplit` 篩選器提取第一個(#0)聲道: ```powershell ffmpeg -i input.wav -filter_complex "channelsplit=channel_layout=stereo[c0][c1]" -map "[c0]" channel_0.wav ``` 使用 `-map_channel` 選項提取第一個(#0)聲道: ```powershell ffmpeg -i input.flac -map_channel 0.0.0 output.flac ``` 使用 `pan` 篩選器提取第一個(#0)聲道: ```powershell ffmpeg -i input.flac -af "pan=1c|c0=c0" output.flac ``` 使用 `pan` 篩選器提取輸入音訊的左聲道: ```powershell ffmpeg -i input.flac -af "pan=1c|FC=FL" output.flac ``` ### 提取 2 個聲道為立體聲 (stereo) 使用 `pan` 篩選器提取 FL 與 FR 輸出為雙聲道: ```powershell ffmpeg -i input.wav -af "pan=stereo|c0=FL|c1=FR" output.wav ``` 使用 `pan` 篩選器提取聲道編號0與1輸出為雙聲道: ```powershell ffmpeg -i input.wav -af "pan=stereo|c0=c0|c1=c1" output.wav ``` 使用 `-map_channel` 提取聲道編號0與1輸出為雙聲道: ```powershell ffmpeg -i input.wav -map_channel 0.0.0 -map_channel 0.0.1 output.wav ``` ## 複製聲道 要將聲道以複製的方式由少變多可以使用 `-ac` 選項。當設定的輸出的聲道數量數比輸入還要多時,會以複製輸入聲道的方式增加聲道。也可以使用 `-map_channel` 重複選取同樣的輸入聲道來得到相同的內容的新聲道。 ### mono → stereo ```text FL = input_FC FR = input_FC ``` 使用 `-ac` 選項: ```powershell ffmpeg -i input.wav -ac 2 output.wav ``` 使用 `pan` 篩選器: ```powershell ffmpeg -i input.wav -af "pan=stereo|c0=c0|c1=c0" output.wav ``` `-map_channel` 選項: ```powershell ffmpeg -i input.wav -map_channel 0.0.0 -map_channel 0.0.0 output.wav ``` `amerge` 篩選器: ```powershell ffmpeg -i input.wav -filter_complex "[0:a][0:a]amerge=inputs=2[aout]" -map "[aout]" output.wav ``` ## 混合聲道 ### stereo → stereo 兩個聲道互相混合 ```text FL = input_FL + input_FR FR = input_FL + input_FR ``` 使用 `pan` 篩選器來互相混合左右聲道: ```powershell ffmpeg -i input.wav -af "pan=stereo|c0<c0+c1|c1<c0+c1" output.flac ``` ## 混合不同音訊串流的聲道 如果要把兩個雙聲道(stereo)音訊混合為一個雙聲道音訊,可以使用以下這兩種做法。 ### 混合相同位置聲道 ```text FL = input0_FL + input1_FL FR = input0_FR + input1_FR ``` `amerge` 篩選器 → `pan` 篩選器: ```powershell ffmpeg -i input0.wav -i input1.wav -filter_complex "[0:a][1:a]amerge=inputs=2,pan=stereo|c0<c0+c2|c1<c1+c3[aout]" -map "[aout]" output.flac ``` `amerge` 篩選器 → `-ac` 選項: ```powershell ffmpeg -i input0.wav -i input1.wav -filter_complex "[0:a][1:a]amerge=inputs=2[aout]" -map "[aout]" -ac 2 output.flac ``` ### 混合相同音源聲道 ```text FL = input0_FL + input0_FR FR = input1_FL + input1_FR ``` `amerge` 篩選器 → `pan` 篩選器: ```powershell ffmpeg -i input0.wav -i input1.wav -filter_complex "[0:a][1:a]amerge=inputs=2,pan=stereo|c0<c0+c1|c1<c2+c3[aout]" -map "[aout]" output.flac ``` ## 交換聲道位置 ```text FL = input0_FR FR = input0_FL ``` 使用 `-map_channel` 選項來交換聲道位置: ```powershell ffmpeg -i stereo.flac -map_channel 0.0.1 -map_channel 0.0.0 output.wav ``` 使用 `pan` 篩選器來交換聲道位置: ```powershell ffmpeg -i stereo.ogg -af "pan=stereo|c0=c1|c1=c0" output.wav ``` ## 靜音聲道 使用 `pan` 篩選器,將目標聲道乘以零已得到即可得到一個靜音的聲道。或者是使用 `-map_channel` 選取需要的聲道再用選取 `-1` 代表一個靜音聲道。 ```text FL = 0 FR = input0_FR ``` 使用 `-map_channel -1` 將輸入雙聲道的左聲道靜音: ```powershell ffmpeg -i stereo.wav -map_channel -1 -map_channel 0.0.1 output.wav ``` 使用 `pan` 篩選器將輸入雙聲道的左聲道靜音: ```powershell ffmpeg -i stereo.ogg -af "pan=stereo|c0=0*c0|c1=c1" output.wav ``` ## 分割聲道 如果要分割每個聲道為單聲道音訊串流,可以使用 `channelsplit` / `pan` 篩選器來做到這點。 使用 `channelsplit` 篩選器分割 6 聲道輸出為個別個音軌: ```powershell ffmpeg -i input.flac -filter_complex channelsplit=channel_layout=stereo output.mka ``` 使用 `-map_channel` 選項分割 6 聲道輸出為個別個音軌: ```powershell ffmpeg -i input.flac -map 0:0 -map 0:0 -map 0:0 -map 0:0 -map 0:0 -map 0:0 -map_channel 0.0.0:0.0 -map_channel 0.0.1:0.1 -map_channel 0.0.2:0.2 -map_channel 0.0.3:0.3 -map_channel 0.0.4:0.4 -map_channel 0.0.5:0.5 output.mka ``` 使用 `pan` 篩選器分割6聲道輸出為個別個音軌: ```powershell ffmpeg -i input.flac -filter_complex "[0:a:0]pan=1c|c0=c0[a0],[0:a:0]pan=1c|c0=c1[a1],[0:a:0]pan=1c|c0=c2[a2],[0:a:0]pan=1c|c0=c3[a3],[0:a:0]pan=1c|c0=c4[a4],[0:a:0]pan=1c|c0=c5[a5]" -map "[a0]" -map "[a1]" -map "[a2]" -map "[a3]" -map "[a4]" -map "[a5]" output.mka ``` 使用 `channelsplit` 篩選器分割 6 聲道輸出為個別檔案: ```powershell ffmpeg -i input.wav -filter_complex "channelsplit=channel_layout=5.1[c0][c1][c2][c3][c4][c5]" -map "[c0]" channel_0.wav -map "[c1]" channel_1.wav -map "[c2]" channel_2.wav -map "[c3]" channel_3.wav -map "[c4]" channel_4.wav -map "[c5]" channel_5.wav ``` 使用 `-map_channel` 分割 6 聲道輸出為個別檔案: ```powershell ffmpeg -i input.flac -map_channel 0.0.0 channel_0.wav -map_channel 0.0.1 channel_1.wav -map_channel 0.0.2 channel_2.wav -map_channel 0.0.3 channel_3.wav -map_channel 0.0.4 channel_4.wav -map_channel 0.0.5 channel_5.wav ``` 使用 `pan` 篩選器分割 6 聲道分割輸出為個別檔案: ```powershell ffmpeg -i input.flac -filter_complex "[0:a:0]pan=1c|c0=c0[c0],[0:a:0]pan=1c|c0=c1[c1],[0:a:0]pan=1c|c0=c2[c2],[0:a:0]pan=1c|c0=c3[c3],[0:a:0]pan=1c|c0=c4[c4],[0:a:0]pan=1c|c0=c5[c5]" -map "[c0]" channel_0.wav -map "[c1]" channel_1.wav -map "[c2]" channel_2.wav -map "[c3]" channel_3.wav -map "[c4]" channel_4.wav -map "[c5]" channel_5.wav ``` ## 合併多個單聲道為多聲道 如果合併多個單聲道為為一個多聲道串流,可以使用 `amerge` 篩選器來做到這點。 2 × mono → stereo: ```powershell ffmpeg -i left.wav -i right.wav -filter_complex "[0:a][1:a]amerge=inputs=2[aout]" -map "[aout]" output.wav ``` 6 × mono → 5.1: ```powershell ffmpeg -i front_left.wav -i front_right.wav -i front_center.wav -i lfe.wav -i back_left.wav -i back_right.wav -filter_complex "[0:a][1:a][2:a][3:a][4:a][5:a]amerge=inputs=6[aout]" -map "[aout]" output.wav ``` ###### tags: `ffmpeg`