MP3/Wav AudioBuffer转换成淡入淡出音频实例页面

回到相关文章 »

效果:

代码:

HTML代码:
<audio src="./htmlbook.wav" controls></audio>
    
<button id="button">点击转换</button>

<audio id="audio" controls></audio>
核心转换JS:
const sliceAudio = function (buffer, start, end, fadeIn = 0, fadeOut = 0) {
  const sampleRate = buffer.sampleRate;
  const audioContext = new AudioContext();

  const length = Math.round((end - start) * sampleRate);
  const offset = Math.round(start * sampleRate);
  const newBuffer = audioContext.createBuffer(buffer.numberOfChannels, length, sampleRate);

  for (let channel = 0; channel < buffer.numberOfChannels; channel++) {
    const inputData = buffer.getChannelData(channel);
    const outputData = newBuffer.getChannelData(channel);

    for (let i = 0; i < length; i++) {
      outputData[i] = inputData[offset + i];

      // Apply fade in
      if (i < fadeIn * sampleRate) {
        outputData[i] *= i / (fadeIn * sampleRate);
      }

      // Apply fade out
      if (i > length - fadeOut * sampleRate) {
        outputData[i] *= (length - i) / (fadeOut * sampleRate);
      }
    }
  }

  return newBuffer;
}
JS执行代码:
const url = './htmlbook.wav';

// 点击按钮,音频淡入淡出播放
button.onclick = function () {
  // 请求数据
  fetch(url).then(res => res.arrayBuffer()).then(buffer => {
    const audioContext = new AudioContext();
    audioContext.decodeAudioData(buffer, (audioBuffer) => {
      const convertBuffer = sliceAudio(audioBuffer, 0, audioBuffer.duration, 1, 1.5);
      // 转blob WAV
      const wavBuffer = audioBufferToWav(convertBuffer);
      const wavBlob = new Blob([wavBuffer], { type: 'audio/wav' });
      const urlBlob = URL.createObjectURL(wavBlob);

      // create download link and append to Dom
      const downloadLink = document.createElement('a');
      downloadLink.href = urlBlob;
      downloadLink.setAttribute('download', 'htmlbook-fade.wav');
      downloadLink.textContent = '下载';

      // 按钮禁用
      this.disabled = true;
      // 试听支持
      audio.src = urlBlob;
      // 下载支持
      audio.after(downloadLink);
    });
  });
}