如何在CreateJS中加载MIDI文件?解决SoundJS拦截问题
问题根因
这并非CreateJS的Bug,是PreloadJS的内置插件路由逻辑导致的:
- LoadQueue初始化时会自动挂载SoundJS的扩展匹配规则,只要文件扩展名落在SoundJS的识别列表内,就会优先路由到SoundJS的音频加载流程,即便你手动在manifest里指定了
type: createjs.Types.BINARY,也会被插件逻辑覆盖 - 由于所有主流浏览器都不原生支持MIDI文件的直接播放,这个自动路由逻辑会直接打断加载流程,根本不会触发BinaryLoader的二进制读取逻辑,最终导致你拿不到预期的ArrayBuffer。
可直接落地的解决方案
根据项目是否需要同时加载其他常规音频文件,二选一即可:
方案1:不需要LoadQueue加载其他原生音频文件
初始化LoadQueue时,关闭自动挂载的默认插件列表,从根源上移除SoundJS的扩展拦截逻辑:
// 构造参数顺序:优先XHR请求、基础路径、主脚本地址、默认插件列表 // 第四个参数传空数组,禁用自动注册的SoundJS插件 let queue = new createjs.LoadQueue(false, null, null, []); queue.on("complete", assets_loaded); queue.on("fileload", handle_file_load); queue.loadManifest([ {id: "bach_score", src: "Bach_score.png"}, {id: "football_stage", src:"Football.png"}, { id: '1badbar1s', src: "exampleplayer/e1/1badbar1.mid", type: createjs.Types.BINARY } ]);
这种配置下所有资源加载都会完全按照manifest中指定的type走流程,MIDI文件会被BinaryLoader正常处理,最终通过queue.getResult('1badbar1s')拿到的就是可直接传给midiplayer.js的ArrayBuffer。
方案2:需要同时加载其他常规音频文件
不能全局禁用SoundJS插件的情况下,可以单独给MIDI加载项手动指定文件扩展名,绕开SoundJS的扩展匹配规则,全程不需要修改实际的文件存储路径和后缀:
// 其他配置保持不变,仅给MIDI的manifest条目增加ext字段 { id: '1badbar1s', src: "exampleplayer/e1/1badbar1.mid", type: createjs.Types.BINARY, ext: 'bin' // 手动指定扩展名,跳过SoundJS的.mid规则匹配 }
这个改动只会改变PreloadJS内部的路由判断逻辑,不会影响实际的文件请求,最终还是会走BinaryLoader的流程返回符合要求的二进制数据。
效果验证
加载完成后,可以在fileload事件中打印返回结果类型,确认输出为[object ArrayBuffer]即代表流程正常,可以直接把结果传入midiplayer.js完成后续初始化。
内容的提问来源于stack exchange,提问作者Timothy Paustian
相关产品推荐
相关产品推荐

