JavaScript实现重采样

1. 使用现成npm包

安装包:npm install audio-resampler

API:

resampler = require('audio-resampler');
//或 import * as resampler from "audio-resampler";
resampler(input, targetSampleRate, oncomplete);

input:输入音频文件。这可以是URL,File对象或AudioBuffer。
targetSampleRate:重新采样过程后的目标采样率。该数字根据浏览器的实施方式而有所限制(通常> = 3000,<= 192000)
oncomplete:重采样过程完成后进行回调。此回调的参数是一个Object,它支持以下方法:
getAudioBuffer :返回重采样器AudioBuffer
getFile :使用callback返回从重新采样的音频创建的WAV文件的ObjectURL。

用例:

resampler = require('audio-resampler');
var URL = "https://dl.dropboxusercontent.com/u/957/audio/sine.wav"
resampler(URL, 192000, function(event){
        //使用callback返回URL
	event.getFile(function(fileEvent){
		var a = document.createElement("a");
		document.body.appendChild(a);
		a.download = "resampled.wav";
		a.style = "display: none";
		a.href = fileEvent;
		a.click();
		window.URL.revokeObjectURL(fileEvent);
		document.body.removeChild(a);
	});
});

resampler = require('audio-resampler');
var URL = "https://dl.dropboxusercontent.com/u/957/audio/sine.wav"
resampler(URL, 192000, function(event){
	const audioBuffer = event.getAudioBuffer();//返回一个AudioBuffer
});

引用:
Audio-Resampler

2. 自己实现

// 调用audioBufferToWav
import { audioBufferToWav } from "./audiobuffer-to-wav";

const getArrayBuffer = (url: string): Promise<ArrayBuffer> => {
  return new Promise(resolve => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "arraybuffer";
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.response);
      }
    };
    xhr.send();
  });
};

export const resampleAudioBuffer = (audioBuffer, targetSampleRate, oncomplete) => {
  const numCh_ = audioBuffer.numberOfChannels;
  const numFrames_ = (audioBuffer.length * targetSampleRate) / audioBuffer.sampleRate;

  let offlineContext_ = new OfflineAudioContext(numCh_, numFrames_, targetSampleRate);
  let bufferSource_ = offlineContext_.createBufferSource();
  bufferSource_.buffer = audioBuffer;

  offlineContext_.oncomplete = function(event) {
    const resampeledBuffer = event.renderedBuffer;
    if (typeof oncomplete === "function") {
      oncomplete({
        getAudioBuffer: function() {
          return resampeledBuffer;
        },
        getFileURL: function() {
          const wavBlob = new Blob([new DataView(audioBufferToWav(resampeledBuffer))], {
            type: "audio/wav",
          });
          return URL.createObjectURL(wavBlob);
        },
      });
    }
  };
  bufferSource_.connect(offlineContext_.destination);
  bufferSource_.start(0);
  offlineContext_.startRendering();
};

export const resampler = (src: string, targetSampleRate: number, oncomplete: Function) => {
  const audioContext = new AudioContext();
  getArrayBuffer(src).then(arrayBuffer => {
    audioContext.decodeAudioData(arrayBuffer, function(audioBeforeBuffer) {
      resampleAudioBuffer(audioBeforeBuffer, targetSampleRate, function(event) {
        if (typeof oncomplete === "function") {
          oncomplete({
            getAudioBuffer: function() {
              return event.getAudioBuffer();
            },
            getFileURL: function() {
              return event.getFileURL();
            },
          });
        }
      });
    });
  });
};

audioBufferToWav代码

resampler:输入音频url,输出可以选择:

  • getAudioBuffer:返回重采样器AudioBuffer;
  • getFileURL:返回从重新采样的音频创建的WAV文件的ObjectURL(不使用callback)

resampleAudioBuffer:输入audiobuffer,输出同上。

原文地址:https://www.cnblogs.com/xym4869/p/13531979.html