【发布时间】:2023-01-21 11:30:25
【问题描述】:
我想用AudioWorklet播放我从AudioContext.decodeAudioData()得到的AudioBuffer。我目前可以使用 AudioBufferSourceNode 播放解码后的音频缓冲区,但如您所知,此方法将在主线程上执行任务,这不是我想要的,我想要的是在后台播放音频,这似乎只是可能与工人有关。但工作人员无法访问Web Audio Api。所以唯一的方法是AudioWorklet
设置工作集:
var audioContext = new AudioContext()
await audioContext.audioWorklet.addModule("./playing-audio-processor.js");
PlayingAudioProcessor= new AudioWorkletNode(
audioContext,
"playing-audio-processor"
);
PlayingAudioProcessor.connect(audioContext.destination);
audioContext.resume();
解码并发送到worklet(我确定通过的audioBuffer没有任何问题,可以轻松玩AudioBufferSourceNode)
let ctx = new AudioContext();
ctx.decodeAudioData(new Uint8Array(audioData).buffer, (audioBuffer) => {
//set `audioData` of worklet to a float32array
myAudioWorklet.port.postMessage(audioBuffer.getChannelData(0))
})
传递的音频数据数组 (audioBuffer.getChannelData(0)) 的长度是 960,它大于 outputs[0][0] 的长度,所以我拆分了它(实际上这似乎不是一个好主意,我想这就是我有的原因不是预期的音频输出)
class PlayingAudioProcessor extends AudioWorkletProcessor {
audioData = []
constructor() {
super();
//set listener to receive audio data
this.port.onmessage = (data) => {
this.audioData = data.data
}
}
process(inputs, outputs, parameters) {
//playing each 128 floats of 960 floats
for (let i = 0; i < this.audioData.length / 128; i++) {
for (let b = 0; b < 128; b++) {
if ((i * 128) + b <= this.audioData.length) {
outputs[0][0][b] = this.audioData[(i * 128) + b];
}
}
}
return true;
}
}
registerProcessor("playing-audio-processor", PlayingAudioProcessor);
现在的问题是音频结果只不过是一种无意义的嘈杂声音,它取决于输入数据的响度。
我真的需要解决这个问题,请提出任何可能对我有帮助的内容。 谢谢你。
【问题讨论】:
标签: javascript service-worker audio-streaming web-audio-api audio-worklet