批量自动移除MKV文件指定单音轨并验证移除结果的技术方案咨询
批量自动移除MKV文件指定单音轨并验证移除结果的技术方案咨询
兄弟,太懂你这种几千集剧集手动处理的崩溃了——光手动验证轨道都要熬好几天,完全是没必要的体力活!我给你一套自动化方案,从识别轨道、批量处理到自动验证全搞定,彻底解放双手:
核心思路:靠语言而非轨道号识别
你之前用固定轨道号的问题就是怕轨道顺序乱,那咱们换个思路:根据轨道的语言标签来筛选要保留的音轨/字幕轨,不管轨道号怎么变,只要语言匹配就留,从根源解决轨道顺序变动的问题。
所需工具
首先确保你装了这俩工具:
mkvtoolnix:自带mkvmerge、mkvinfo,用来处理MKV文件jq:轻量JSON解析工具,用来提取轨道的语言信息(大部分Linux发行版、Mac用brew都能装,Windows也有对应版本)
自动化脚本示例(Bash)
下面是一套完整的批量处理+自动验证脚本,你可以根据自己的需求修改语言参数:
#!/bin/bash # 配置参数:改成你要保留的音轨/字幕语言(比如eng、jpn、chs等) TARGET_AUDIO_LANG="eng" TARGET_SUB_LANG="eng" # 输出目录(提前创建好) OUTPUT_DIR="./processed_mkv" # 临时目录用来存轨道信息 TEMP_DIR="./temp_track_info" # 创建必要目录 mkdir -p "$OUTPUT_DIR" "$TEMP_DIR" # 验证处理后文件的函数 verify_processed_file() { local FILE_PATH=$1 local EXPECTED_AUDIO=$2 local EXPECTED_SUB=$3 # 提取处理后文件的轨道JSON信息 mkvmerge -J "$FILE_PATH" > "$TEMP_DIR/verify_$(basename "$FILE_PATH").json" # 检查所有音频轨的语言 actual_audio_langs=$(jq -r '.tracks[] | select(.type == "audio") | .properties.language' "$TEMP_DIR/verify_$(basename "$FILE_PATH").json" | sort | uniq) # 检查所有字幕轨的语言 actual_sub_langs=$(jq -r '.tracks[] | select(.type == "subtitle") | .properties.language' "$TEMP_DIR/verify_$(basename "$FILE_PATH").json" | sort | uniq) # 检查是否有默认音频轨 has_default_audio=$(jq -r '.tracks[] | select(.type == "audio" and .properties.default_track == true) | .id' "$TEMP_DIR/verify_$(basename "$FILE_PATH").json") # 检查是否有默认字幕轨 has_default_sub=$(jq -r '.tracks[] | select(.type == "subtitle" and .properties.default_track == true) | .id' "$TEMP_DIR/verify_$(basename "$FILE_PATH").json") # 验证逻辑 if [[ "$actual_audio_langs" != "$EXPECTED_AUDIO" || -z "$has_default_audio" ]]; then echo "❌ 验证失败:$FILE_PATH 音频轨不符合要求(语言/默认轨异常)" return 1 fi if [[ "$actual_sub_langs" != "$EXPECTED_SUB" || -z "$has_default_sub" ]]; then echo "❌ 验证失败:$FILE_PATH 字幕轨不符合要求(语言/默认轨异常)" return 1 fi echo "✅ 验证通过:$FILE_PATH" return 0 } # 批量处理所有MKV文件 for mkv_file in *.mkv; do echo "正在处理:$mkv_file" # 提取当前文件的轨道JSON信息 mkvmerge -J "$mkv_file" > "$TEMP_DIR/$(basename "$mkv_file").json" # 筛选出目标语言的音频轨ID(用逗号分隔多个轨,如果你要留多个同语言轨的话) audio_track_ids=$(jq -r ".tracks[] | select(.type == \"audio\" and .properties.language == \"$TARGET_AUDIO_LANG\") | .id" "$TEMP_DIR/$(basename "$mkv_file").json" | paste -sd "," -) # 筛选出目标语言的字幕轨ID sub_track_ids=$(jq -r ".tracks[] | select(.type == \"subtitle\" and .properties.language == \"$TARGET_SUB_LANG\") | .id" "$TEMP_DIR/$(basename "$mkv_file").json" | paste -sd "," -) # 如果没有找到目标轨道,跳过并标记 if [[ -z "$audio_track_ids" ]]; then echo "⚠️ 跳过:$mkv_file 未找到目标音频轨" continue fi if [[ -z "$sub_track_ids" ]]; then echo "⚠️ 跳过:$mkv_file 未找到目标字幕轨" continue fi # 执行mkvmerge处理 mkvmerge -o "$OUTPUT_DIR/$mkv_file" \ --audio-tracks "$audio_track_ids" \ --subtitle-tracks "$sub_track_ids" \ --default-track "$audio_track_ids" \ --default-track "$sub_track_ids" \ "$mkv_file" # 验证处理后的文件 verify_processed_file "$OUTPUT_DIR/$mkv_file" "$TARGET_AUDIO_LANG" "$TARGET_SUB_LANG" done # 清理临时文件 rm -rf "$TEMP_DIR" echo "所有文件处理完成!"
使用说明
- 把脚本存成
batch_process_mkv.sh,给执行权限:chmod +x batch_process_mkv.sh - 把脚本放到MKV文件所在的目录,修改开头的
TARGET_AUDIO_LANG和TARGET_SUB_LANG为你要保留的语言(比如日语是jpn,中文是chs) - 运行脚本:
./batch_process_mkv.sh
额外建议
- 先测试:拿几集不同的剧集先跑一遍,确认脚本逻辑符合你的需求
- 备份原文件:处理前最好把原文件备份到其他目录,避免意外
- 异常处理:脚本里已经加了跳过无目标轨道文件的逻辑,你还可以根据需要加更多判断(比如只保留单条音频轨)
备注:内容来源于stack exchange,提问作者Tsumuri
相关产品推荐
相关产品推荐

