You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MIDI.js中setTimeout触发过晚及音符、程序变更事件滞后的修复咨询

修复MIDI.js abcjs分支首次播放延迟问题

针对你遇到的首次播放延迟(尤其是MIDI程序变更事件延迟更严重)、重新播放正常的问题,可通过以下方案修复:

1. 用Web Audio时间轴替代setTimeout处理程序变更事件

setTimeout依赖浏览器事件循环,精度低且无法和音频调度同步,这是程序变更事件延迟严重的核心原因。需改用Web Audio API的高精度时间轴来调度此类事件:

  • 找到adaptors.js中用setTimeout处理程序变更的代码段,替换为基于AudioContext.currentTime的调度逻辑:
    // 替换原setTimeout代码
    const targetTime = MIDI.audioContext.currentTime + delay / 1000; // delay为原毫秒值,转成秒级时间偏移
    const triggerProgramChange = () => {
      if (MIDI.audioContext.currentTime >= targetTime) {
        MIDI.programChange(channel, program); // 原程序变更逻辑
      } else {
        requestAnimationFrame(triggerProgramChange);
      }
    };
    requestAnimationFrame(triggerProgramChange);
    
    该逻辑通过Web Audio的时间基准校准,确保程序变更和音符播放严格同步。

2. 预加载所有用到的乐器音色

首次播放延迟大概率和音色资源未完全加载有关,重新播放时资源已缓存所以正常。需在播放前预加载MIDI文件中涉及的所有乐器:

  • 初始化MIDI.js时指定所有需要的乐器,等待加载完成后再触发播放:
    MIDI.loadPlugin({
      soundfontUrl: "./soundfont/", // 你的音色文件路径
      instruments: ["acoustic_grand_piano", "electric_guitar_clean"], // 列出MIDI中用到的所有乐器
      onsuccess: () => {
        // 加载完成后启用播放功能
        document.getElementById("play-btn").disabled = false;
      }
    });
    

3. 校准AudioContext的激活时机

浏览器对AudioContext有自动暂停限制(需用户交互激活),若页面加载时提前创建Context,会导致初始时间基准异常:

  • 仅在用户交互(如点击播放按钮)时创建或恢复AudioContext:
    let audioContext;
    document.getElementById("play-btn").addEventListener("click", async () => {
      if (!audioContext) {
        audioContext = new (window.AudioContext || window.webkitAudioContext)();
        MIDI.setContext(audioContext);
      } else if (audioContext.state === "suspended") {
        await audioContext.resume();
      }
      // 执行MIDI播放逻辑
      playMidiFile();
    });
    

4. 统一事件时间基准计算

检查adaptors-AudioAPI.js中start()方法的时间计算逻辑,确保所有事件(音符、程序变更)的延迟值转换一致(毫秒转秒时除以1000),避免时间基准错位。

内容的提问来源于stack exchange,提问作者root

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 21:45:46