本文目录导读:

- 方案一:使用 Python 脚本(推荐,跨平台)
- 方案二:使用 Bash 脚本(仅限 Linux/macOS,需安装
midicsv) - 方案三:使用 Python + 外部工具(更简单,适合一次性修改)
- 常见问题与注意点
- 推荐选择
批量修改MIDI文件的速度(BPM),通常有以下几种方法,取决于你使用的操作系统和脚本语言,最推荐的方法是使用 Python 的 mido 库,因为它跨平台且能精确控制 MIDI 消息。
以下是几种常见的脚本方案:
使用 Python 脚本(推荐,跨平台)
这是最灵活、最强大的方法,可以按照比率(如加速1.2倍)或绝对值(统一设为120 BPM)修改。
安装依赖库
需要安装 mido 库,打开终端(命令行)运行:
pip install mido
Python 脚本代码
创建一个文件,change_midi_bpm.py,复制以下代码:
import mido
from mido import MidiFile, MidiTrack, MetaMessage
import os
def change_tempo(midi_path, output_path, factor=1.0, new_bpm=None):
"""
修改 MIDI 文件速度。
:param midi_path: 输入文件路径
:param output_path: 输出文件路径
:param factor: 速度倍数 (2.0 表示加速一倍,0.5 表示减速一半)
:param new_bpm: (可选)直接设置新的BPM值,若提供则忽略 factor
"""
mid = MidiFile(midi_path)
for track in mid.tracks:
for msg in track:
# 找到 Set Tempo 消息 (元事件)
if msg.type == 'set_tempo':
if new_bpm:
# 使用 mido 的 bpm2tempo 函数转换
msg.tempo = mido.bpm2tempo(new_bpm)
else:
# 按比例调整 tempo 值 (microseconds per beat)
msg.tempo = int(msg.tempo / factor)
# 保存修改后的文件
mid.save(output_path)
print(f"已完成: {os.path.basename(midi_path)} -> BPM 已调整")
def batch_process(input_folder, output_folder, factor=1.0, new_bpm=None, file_extension='.mid'):
"""
批量处理文件夹中的 MIDI 文件
"""
if not os.path.exists(output_folder):
os.makedirs(output_folder)
for filename in os.listdir(input_folder):
if filename.lower().endswith(file_extension):
in_path = os.path.join(input_folder, filename)
out_path = os.path.join(output_folder, filename)
change_tempo(in_path, out_path, factor, new_bpm)
if __name__ == "__main__":
# ===== 配置参数 =====
input_dir = "./input_midi" # 输入文件夹(放原始MIDI)
output_dir = "./output_midi" # 输出文件夹
# 方法1:按比例调整(加速到1.2倍)
# batch_process(input_dir, output_dir, factor=1.2)
# 方法2:统一设置固定BPM(全部设为 140 BPM)
batch_process(input_dir, output_dir, new_bpm=140)
# 方法3:减速到 0.8 倍
# batch_process(input_dir, output_dir, factor=0.8)
使用方法
- 在脚本同目录下创建
input_midi文件夹,放入你的.mid文件。 - 运行脚本:
python change_midi_bpm.py - 修改后的文件会出现在
output_midi文件夹。
使用 Bash 脚本(仅限 Linux/macOS,需安装 midicsv)
如果你比较习惯命令行,可以使用 midicsv 和 csvmidi 工具链。
安装工具
# macOS brew install midicsv # Ubuntu/Debian sudo apt install midicsv
Bash 脚本
创建一个 change_bpm.sh 文件,内容如下:
#!/bin/bash
INPUT_DIR="./input"
OUTPUT_DIR="./output"
NEW_BPM=140 # 设定新BPM值
mkdir -p "$OUTPUT_DIR"
for file in "$INPUT_DIR"/*.mid; do
# 将 MIDI 转为 CSV 文本格式
csvname=$(basename "$file" .mid).csv
midicsv "$file" "/tmp/$csvname"
# 使用 sed 找到 Tempo 行并替换(Tempo 在 CSV 中格式为: 0, 0, Meta, Tempo, <value>)
# 注意:MIDI内部存的是 microseconds per quarter note,需要转换:
# tempo_value = 60000000 / BPM
NEW_TEMPO_VALUE=$((60000000 / NEW_BPM))
sed -i '' "s/^0, 0, Meta, Tempo, [0-9]*$/0, 0, Meta, Tempo, $NEW_TEMPO_VALUE/" "/tmp/$csvname"
# 转回 MIDI
csvmidi "/tmp/$csvname" "$OUTPUT_DIR/$(basename "$file")"
done
echo "批量转换完成!"
- 优点:小脚本,无需安装Python库。
- 缺点:无法处理嵌套文件夹;macOS 上
sed -i需要加空格和引号。
使用 Python + 外部工具(更简单,适合一次性修改)
如果你不想处理MIDI底层消息,也可以使用 TiMidity++ 或 FluidSynth 渲染后重新设置BPM,但这样会丢失MIDI的控制信息,上面两种方案更精确。
常见问题与注意点
-
BPM 与 tempo 的区别
MIDI文件内部存储的是“每四分音符的微秒数”(tempo)。
换算公式:tempo = 60,000,000 / BPM。
mido库的bpm2tempo()函数已经帮你做这件事。 -
某些 MIDI 文件可能没有 Set Tempo 事件
如果文件没有明确的节拍事件,系统会默认使用 120 BPM,对这种情况,可以考虑在第一个音轨开头插入一个set_tempo消息。 -
变速后音符长度变化?
放心,MIDI 文件只记录音符的“开始时间”和“时长”(以 tick 为单位),修改 tempo 后,播放器会根据新 tempo 重新计算实际时间长度,因此音符节奏会自动等比缩放。 -
文件编码
建议只处理标准的.mid或.midi文件。
推荐选择
- 如果你希望简单、跨平台、可编程:用上面的 Python 方案一。
- 如果你是 Linux/macOS 用户且熟悉命令行:用 Bash 方案二。
- 只需要修改一两个文件:也可以直接用 DAW(如FL Studio、Logic、Cubase) 直接导入后改BPM再导出。
如果你能提供更具体的需求(比如要固定为120 BPM,还是按某个百分比加速),我可以帮你直接生成完整可用的脚本文件。