You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动