FFmpeg合并EAC3音频到MKV并设置为默认主音轨的实现问题
FFmpeg合并EAC3音频到MKV并设置为默认主音轨的实现问题
嘿,我完全懂你的烦恼——每次看剧都要手动切换音轨真的很麻烦!咱们来调整下你的Python脚本和FFmpeg命令,一次性解决所有需求:把EAC3音轨设为默认且排在最前面,同时保留原MKV里的所有字幕和其他音频轨道。
核心FFmpeg命令解析
问题的关键在于用FFmpeg的-map参数控制轨道顺序,再用-disposition设置默认音轨。针对单个文件的正确命令应该是这样的:
ffmpeg -i show.eac3 -i show.mkv -map 0:a -map 1:v -map 1:a -map 1:s -c copy -disposition:a:0 default output.mkv
我来拆解下每个参数的作用:
-i show.eac3:先指定EAC3音频文件为第一个输入源-i show.mkv:再指定原MKV文件为第二个输入源-map 0:a:把第一个输入(EAC3音频)的所有音频流放在最前面(这会让它成为轨道1)-map 1:v:导入原MKV的视频流-map 1:a:导入原MKV的所有音频流(排在EAC3之后)-map 1:s:导入原MKV的所有字幕流(全部保留)-c copy:直接复制所有流,不重新编码,既快又不会损失画质音质-disposition:a:0 default:把第一个音频流(也就是我们加的EAC3)设为默认播放音轨
如果原MKV里有默认音轨,这个命令会自动把它的默认属性取消,确保只有EAC3是默认。
修改后的Python批量处理脚本
把上面的命令整合到你的脚本里,就能批量处理所有文件夹里的MKV和对应EAC3文件了。这里我优化了脚本的安全性和易用性:
import os import subprocess # 定义根目录 root_dir = r'Z:\TV_shows_ended\XXXX\Season 2' def process_files(root_dir): for subdir, _, files in os.walk(root_dir): mkv_files = [f for f in files if f.endswith('.mkv')] for mkv_file in mkv_files: # 构造对应的EAC3文件路径 base_name = os.path.splitext(mkv_file)[0] eac3_file = f"{base_name}.eac3" eac3_path = os.path.join(subdir, eac3_file) # 检查EAC3文件是否存在 if not os.path.exists(eac3_path): print(f"⚠️ 未找到对应EAC3文件:{eac3_path},跳过") continue # 构造输出文件路径(避免覆盖原文件,你可以根据需求修改) output_mkv = os.path.join(subdir, f"{base_name}_merged.mkv") # 构造FFmpeg命令(用列表形式更安全,避免shell注入风险) ffmpeg_cmd = [ 'ffmpeg', '-i', eac3_path, '-i', os.path.join(subdir, mkv_file), '-map', '0:a', # 取第一个输入的音频(EAC3) '-map', '1:v', # 取第二个输入的视频 '-map', '1:a', # 取第二个输入的所有音频 '-map', '1:s', # 取第二个输入的所有字幕 '-c', 'copy', '-disposition:a:0', 'default', '-y', # 如果输出文件已存在,直接覆盖(可选,根据需求去掉) output_mkv ] try: # 执行命令 subprocess.run(ffmpeg_cmd, check=True, capture_output=True, text=True) print(f"✅ 处理完成:{output_mkv}") except subprocess.CalledProcessError as e: print(f"❌ 处理失败:{mkv_file},错误信息:{e.stderr}") if __name__ == "__main__": process_files(root_dir)
脚本说明
- 我把输入顺序调整了:先EAC3再MKV,这样
-map 0:a就是EAC3音频,逻辑更直观 - 加入了文件存在检查,避免因为找不到EAC3文件报错中断
- 输出文件默认加了
_merged后缀,防止误删原文件,你可以改成直接覆盖(把output_mkv改成原路径,同时保留-y参数) - 用列表形式传递FFmpeg命令,比字符串拼接更安全,能避免特殊文件名导致的执行失败
- 加入了错误捕获,方便排查处理失败的文件
测试建议
先找一个单独的文件夹测试单个文件,确认FFmpeg命令能生成符合要求的MKV(EAC3是默认且排在第一位,字幕和其他音轨都保留),再批量运行整个脚本,这样更稳妥。
备注:内容来源于stack exchange,提问作者LimpKittyBiscuit




