如何在浏览器中使用timidity顺畅播放MIDI文件并控制进度
实现浏览器中MIDI文件的播放与进度控制(支持后台播放)
解决require is not defined的核心问题
浏览器环境不支持Node.js的require语法,你需要使用UMD格式的timidity构建包,或者通过打包工具将模块暴露到全局作用域。
方案1:使用CDN直接引入(最快实现)
直接引入UMD版本的timidity,无需本地打包,浏览器会自动注册全局Timidity对象:
<!-- 引入timidity的UMD构建文件 --> <script src="https://cdn.jsdelivr.net/npm/timidity@latest/dist/timidity.min.js"></script> <button id="playBtn">播放</button> <button id="seekBtn">跳转到10秒</button> <div id="currentTime"></div> <script> let player; // 必须通过用户手势激活AudioContext(浏览器安全限制) document.getElementById('playBtn').addEventListener('click', async () => { // 初始化播放器 if (!player) { player = new Timidity(); // 加载MIDI文件 await player.load('https://bitmidi.com/uploads/16752.mid'); } // 切换播放状态 if (player.playing) { player.pause(); playBtn.textContent = '播放'; } else { await player.play(); playBtn.textContent = '暂停'; // 实时更新当前播放时间 setInterval(() => { document.getElementById('currentTime').textContent = `当前进度:${player.currentTime.toFixed(2)}秒`; }, 100); } }); // 实现进度跳转 document.getElementById('seekBtn').addEventListener('click', () => { if (player) { player.seek(10); // 跳转到第10秒 } }); </script>
方案2:本地打包并暴露实例(适合项目集成)
如果你需要本地打包,修改你的index.js,将Timidity或播放器实例挂载到window全局,这样就能在HTML中访问:
- 编写
index.js:
const Timidity = require('timidity'); // 将Timidity暴露到全局 window.Timidity = Timidity; // 或者提前创建播放器实例并暴露 window.midiPlayer = new Timidity();
- 执行打包命令:
browserify index.js -o bundle.js
- 在HTML中使用:
<script src="bundle.js"></script> <button id="playBtn">播放</button> <button id="seekBtn">跳转到15秒</button> <script> let player = window.midiPlayer; document.getElementById('playBtn').addEventListener('click', async () => { if (!player.hasLoaded) { await player.load('https://bitmidi.com/uploads/16752.mid'); } player.playing ? player.pause() : await player.play(); }); document.getElementById('seekBtn').addEventListener('click', () => { player.seek(15); }); </script>
关键注意事项
- 后台播放支持:timidity基于Web Audio API,只要播放器已经通过用户手势激活并开始播放,即使浏览器标签失去焦点,音频会继续播放(部分浏览器会对后台音频做节流,但不会完全停止)。
- AudioContext激活限制:必须在用户交互(点击、触摸等)事件中初始化或恢复AudioContext,否则会触发
The AudioContext was not allowed to start错误。 - 进度控制API:
- 获取当前播放时间:
player.currentTime(返回秒数) - 设置播放位置:
player.seek(seconds)(传入目标秒数)
- 获取当前播放时间:
内容的提问来源于stack exchange,提问作者root
相关产品推荐
相关产品推荐

