如何在Tone.Offline中播放本地音频并获取输出的处理后Buffer
问题原因
transport.schedule要求传入第二个参数指定回调的触发时间点,缺失该参数时调度事件不会被注册到时间线,回调自然无法触发- Tone.Offline 为预渲染模式,渲染逻辑会同步遍历整个时间线完成计算,你在 Player 的 onload 异步回调中才启动 transport,容易出现时序错位,渲染完成时 transport 还没启动,导致调度事件不会执行
- 你的代码中设置了音频在 5s 启动、9s 停止,要确保 Offline 的总渲染时长(当前设置的10s)足够覆盖该播放区间,避免内容被截断
修复后可运行代码
async function renderCustomAudio() { // 预加载音频资源,避免离线渲染的时序冲突 await Tone.Buffer.load(src); // 启动离线渲染 const renderBuffer = await Tone.Offline(({ transport }) => { const player = new Tone.Player(src).toDestination(); // 补充第二个参数0,指定回调在渲染时间线的0秒位置触发 transport.schedule((time) => { player.start(time + 5).stop(time + 9); }, 0); // 直接启动transport,无需放在Player的异步加载回调中 transport.start(); }, 10); // 导出wav文件 const wav = toWav(renderBuffer); saveAs(new Blob([wav], { type: "audio/wav" }), "blibli.wav"); } // 执行渲染逻辑 renderCustomAudio();
核心修改说明
- 新增资源预加载逻辑,调用
Tone.Buffer.load(src)确保音频资源加载完成后再启动离线渲染 - 给
transport.schedule补充第二个参数0,明确调度回调的触发时间 - 将
transport.start()从Player的onload回调移到Offline上下文顶层,符合离线渲染的同步时序要求
内容的提问来源于stack exchange,提问作者ueeieiie
相关产品推荐
相关产品推荐

