首页 > 解决方案 > AudioWorklet 和 GainNode 控制音量

问题描述

我正在尝试使用 AudioWorklet 和 GainNode 进行音量控制,但它不起作用,没有 AudioWorket 它运行良好。

这是实现


this.audioContext = new AudioContext({
      latencyHint: 'interactive',
      sampleRate: this.sampleRate,
      sinkId: audioinput || "default"
    });
    this.audioContext.onstatechange = () => {
      if (this.audioContext) {
        this.state = this.audioContext.state;
      } else {
        this.state = AudioState.CLOSED;
      }
    };
    this.audioBuffer = this.audioContext.createBuffer(1, this.audioSize, this.sampleRate);
    this.audioSource = this.audioContext.createBufferSource();
    this.audioSource.buffer = this.audioBuffer;
    this.audioGain = this.audioContext.createGain();
    this.audioSource.connect(this.audioGain);
    this.audioSource.loop = true;
    this.audioContext.audioWorklet
    .addModule('workers/speaker-worklet-processor.js')
    .then(() => {
      this.speakerWorklet = new AudioWorkletNode(
        this.audioContext,
        'speaker-worklet-processor',
        {
          channelCount: 1,
          processorOptions: {
            bufferSize: 160,
            channelCount: 1,
          },
        },
      );
      this.audioGain.connect(this.speakerWorklet).connect(this.audioContext.destination);
    }).catch((err)=>{
      console.log("Receiver ", err);
    });

这是我设置新音量的方式。

public changeVolume(value: number): void {
  const volume = Number(value) / 100;
  if (this.state !== AudioState.CLOSED) {
    this.audioGain.gain.value = volume;
  }
}

标签: javascriptweb-audio-apiaudio-worklet

解决方案


我找到了解决方案,我刚刚添加了


this.audioGain.connect(this.audioContext.destination);

并直接与worklet节点连接


 this.speakerWorklet.connect(this.audioGain);

这是完整的代码


  this.audioContext = new AudioContext({
      latencyHint: 'interactive',
      sampleRate: this.sampleRate,
      sinkId: audioinput || "default"
    });
    this.audioContext.onstatechange = () => {
      if (this.audioContext) {
        this.state = this.audioContext.state;
      } else {
        this.state = AudioState.CLOSED;
      }
    };
    this.audioBuffer = this.audioContext.createBuffer(1, this.audioSize, this.sampleRate);
    this.audioSource = this.audioContext.createBufferSource();
    this.audioSource.buffer = this.audioBuffer;
    this.audioGain = this.audioContext.createGain();
    this.audioGain.gain.minVal = 0.0;
    this.audioGain.gain.maxVal = 1.0;
    this.audioSource.connect(this.audioGain);
    this.audioSource.loop = true;
    this.audioGain.connect(this.audioContext.destination);
    this.audioContext.audioWorklet
    .addModule('workers/speaker-worklet-processor.js')
    .then(() => {
      this.speakerWorklet = new AudioWorkletNode(
        this.audioContext,
        'speaker-worklet-processor',
        {
          channelCount: 1,
          processorOptions: {
            bufferSize: 160,
            channelCount: 1,
          },
        },
      );
      this.speakerWorklet.connect(this.audioGain);
    }).catch((err)=>{
      console.log("Receiver ", err);
    });


推荐阅读