# audio-recorder-worklet-processor

> 基于 AudioWorklet 的浏览器端实时录音库，提供音频采集、降噪、格式转换等原子能力。

Latest version **0.0.9** (published 2026-05-26) · ISC license · 0 weekly downloads

## Install

```sh
npm install audio-recorder-worklet-processor
pnpm add audio-recorder-worklet-processor
yarn add audio-recorder-worklet-processor
bun add audio-recorder-worklet-processor
```

## Health

**Score 55/100 (C)** — status: active.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.0.9 |
| Published | 2026-05-26 |
| First published | 2023-11-30 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 20 |
| Unpacked size | 2.3 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | kukuxuan-cola |

## Links

- npm: https://www.npmjs.com/package/audio-recorder-worklet-processor
- npm.io page: https://npm.io/package/audio-recorder-worklet-processor

## Dependencies (20)

- [rollup](https://npm.io/package/rollup.md) ^4.52.5
- [webpack](https://npm.io/package/webpack.md) ^5.89.0
- [ts-loader](https://npm.io/package/ts-loader.md) ^9.5.1
- [raw-loader](https://npm.io/package/raw-loader.md) ^4.0.2
- [typescript](https://npm.io/package/typescript.md) ^5.3.2
- [webpack-cli](https://npm.io/package/webpack-cli.md) ^5.1.4
- [worker-loader](https://npm.io/package/worker-loader.md) ^3.0.8
- [worklet-loader](https://npm.io/package/worklet-loader.md) ^2.0.0
- [@types/minimatch](https://npm.io/package/@types/minimatch.md) ^6.0.0
- [arraybuffer-loader](https://npm.io/package/arraybuffer-loader.md) ^1.0.8
- [rollup-plugin-copy](https://npm.io/package/rollup-plugin-copy.md) ^3.5.0
- [copy-webpack-plugin](https://npm.io/package/copy-webpack-plugin.md) ^13.0.1
- [rollup-plugin-string](https://npm.io/package/rollup-plugin-string.md) ^3.0.0
- [deepfilter-standalone](https://npm.io/package/deepfilter-standalone.md) ^1.0.2
- [@rollup/plugin-commonjs](https://npm.io/package/@rollup/plugin-commonjs.md) ^28.0.8
- [@vonage/noise-suppression](https://npm.io/package/@vonage/noise-suppression.md) ^1.0.3
- [rollup-plugin-typescript2](https://npm.io/package/rollup-plugin-typescript2.md) ^0.36.0
- [@rollup/plugin-node-resolve](https://npm.io/package/@rollup/plugin-node-resolve.md) ^16.0.3
- [node-polyfill-webpack-plugin](https://npm.io/package/node-polyfill-webpack-plugin.md) ^4.1.0
- [@sapphi-red/web-noise-suppressor](https://npm.io/package/@sapphi-red/web-noise-suppressor.md) ^0.3.5

## Recent versions

- 0.0.9 (latest) — 2026-05-26
- 0.0.8 — 2026-05-26
- 0.0.7 — 2025-10-31
- 0.0.6 — 2025-10-23
- 0.0.5 — 2025-09-12
- 0.0.4 — 2025-09-12
- 0.0.3 — 2024-06-03
- 0.0.2 — 2023-12-05
- 0.0.1 — 2023-11-30

## README

# audio-recorder-worklet-processor

基于 AudioWorklet 的浏览器端实时录音库，提供音频采集、降噪、格式转换等原子能力。

> 不做音频数据存储，仅提供原子能力。业务层可自行缓存数据，再调用 `encodePCM` / `encodeWAV` 转换格式。
> 内置多种降噪算法，可根据业务需求选择。

## 浏览器支持

| Chrome | Firefox | Edge | Opera | Safari |
|--------|---------|------|-------|--------|
| 66+    | 76+     | 79+  | 53+   | 14.1+  |

## 音频处理流程

```
┌──────────┐    ┌──────────────┐    ┌────────────┐    ┌───────────────┐    ┌────────────┐
│ 麦克风   │───▶│ RNNoise?     │───▶│ Biquad?    │───▶│ MainWorklet   │───▶│ Destination│
│          │    │ (AI降噪-A)   │    │ (带通滤波) │    │ (采集+音量)   │    │ (扬声器)   │
└──────────┘    └──────────────┘    └────────────┘    └───────┬───────┘    └────────────┘
                                                           │ postMessage
                                                           ▼
                                                     ┌──────────────┐
                                                     │ 主线程回调    │
                                                     │ DeepFilter?  │── 48kHz降噪 → 重采样回目标采样率
                                                     │              │
                                                     │ onDataProcess│── { vol, buffer }
                                                     └──────────────┘
```

### 降噪方案（互斥，三选一）

| 方案 | 原理 | 延迟 | 效果 | 备注 |
|------|------|------|------|------|
| **RNNoise** | AudioWorklet 线程内 RNN 推理 | 极低 | 中 | 需引入 WASM + Worklet 文件 |
| **DeepFilter** | 主线程 DeepFilterNet3 WASM 推理 | ~10-20ms | 高 | 需联网加载模型，内部 48kHz 自动重采样 |
| **Vonage** | 替换麦克风流轨道 | 低 | 中 | 第三方 SDK |

另有 **Biquad 带通滤波器**（传统 DSP），可与上述方案叠加使用。

---

## 安装

```bash
npm install audio-recorder-worklet-processor
```

## 引入

ES Module：

```js
import Recorder from "audio-recorder-worklet-processor";

const recorder = new Recorder();
```

CDN / Script 标签：

```html
<script src="../dist/index.js"></script>
<script>
  const recorder = new Recorder();
</script>
```

---

## API

### `init(config?)`

初始化录音环境，创建 AudioContext 和各音频节点（不获取麦克风、不连接链路）。

```typescript
await recorder.init(config);
```

<details>
<summary><strong>IConfig 完整定义</strong></summary>

```typescript
interface IConfig {
  /** 实时音频回调，返回音量(0-1)和 Float32 原始数据 */
  onDataProcess?: (data: { vol: number; buffer: Float32Array }) => void;

  /** 音频采集参数 */
  processOptions?: IProcessOptions;

  /** 频谱分析参数（可用于可视化） */
  analyserOptions?: IAnalyserOptions;

  /** Biquad 带通滤波器参数 */
  noiseReductionOptions?: INoiseReductionOptions;

  /** 是否使用 Vonage AI 降噪，默认 false */
  useVonage?: boolean;

  /** RNNoise 降噪参数 */
  rnnoiseOptions?: IRnnoiseOptions;

  /** DeepFilter 降噪参数（内部 48kHz 处理后自动重采样回 sampleRate） */
  deepFilterOptions?: IDeepFilterOptions;
}
```

</details>

<details>
<summary><strong>IProcessOptions 采集参数</strong></summary>

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `processSize` | `number` | 4096 | 每次回调的采样数 |
| `numChannels` | `1 \| 2` | 1 | 声道数 |
| `sampleBits` | `16 \| 8` | 16 | 采样位深 |
| `sampleRate` | `number` | 16000 | 采样率，常用 16000 / 48000 |

</details>

<details>
<summary><strong>IAnalyserOptions 频谱分析参数</strong></summary>

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `open` | `boolean` | false | 是否开启 AnalyserNode |
| `fftSize` | `number` | 512 | FFT 精度，范围 32-32768，越大越精确 |

</details>

<details>
<summary><strong>INoiseReductionOptions 带通滤波器参数</strong></summary>

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `open` | `boolean` | false | 是否启用 |
| `frequency` | `number` | 1300 | 中心频率 Hz（人声 300-3400Hz） |
| `Q` | `number` | 1 | 品质因数，决定带宽 = frequency/Q |

</details>

<details>
<summary><strong>IRnnoiseOptions RNNoise 参数</strong></summary>

| 参数 | 类型 | 说明 |
|------|------|------|
| `useRnnoise` | `boolean` | 是否启用 |
| `rnnoiseWasmPath` | `string` | rnnoise.wasm 文件路径 |
| `rnnoiseSimdWasmPath` | `string` | rnnoise_simd.wasm 文件路径（SIMD 加速） |
| `rnnoiseWorkletPath` | `string` | rnnoise.worklet.js 文件路径 |

</details>

<details>
<summary><strong>IDeepFilterOptions DeepFilter 参数</strong></summary>

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `useDeepFilter` | `boolean` | false | 是否启用 |
| `cdnUrl` | `string` | `https://cdn.laptrinhai.id.vn/deepfilternet3` | WASM/模型资源 CDN 地址 |
| `attenuationLimit` | `number` | 50 | 降噪强度 dB，0-100，越大越强 |
| `postFilterBeta` | `number` | 0.02 | 后滤波强度，0-0.05，0=禁用 |

> **注意：** 首次 `init()` 需联网加载 WASM + 模型（约 2-4MB），耗时数秒，建议应用启动时预初始化。启用后自动关闭浏览器原生降噪/回声消除/自动增益。内部 48kHz 处理后自动重采样回你配置的 `sampleRate`。

</details>

---

### `start()`

开始录音，获取麦克风并建立音频链路。

```typescript
await recorder.start();
```

### `stop()`

停止录音。会将缓冲区中不足 `processSize` 的剩余数据再回调一次 `onDataProcess`，不丢数据。

```typescript
await recorder.stop();
```

### `destroy()`

销毁录音器，彻底释放所有资源。调用后需重新 `init()` 才能使用。

```typescript
await recorder.destroy();
```

### `getAnalyserData()`

获取实时频谱数据（需在 `init` 时开启 `analyserOptions.open`）。

```typescript
const data: Uint8Array = recorder.getAnalyserData();
```

### `encodePCM(bytes, sampleBits?, littleEdian?)`

Float32 原始数据 → PCM DataView。

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `bytes` | `Float32Array` | — | `onDataProcess` 返回的原始数据 |
| `sampleBits` | `16 \| 8` | init 配置 | 采样位深 |
| `littleEdian` | `boolean` | 自动检测 | 字节序 |

```typescript
const pcmData = recorder.encodePCM(bufferArr);
```

### `encodeWAV(buffer, sampleRate?, numChannels?, sampleBits?, littleEdian?)`

PCM DataView → WAV DataView。

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `buffer` | `DataView` | — | `encodePCM` 返回的数据 |
| `sampleRate` | `number` | init 配置 | 采样率 |
| `numChannels` | `1 \| 2` | init 配置 | 声道数 |
| `sampleBits` | `16 \| 8` | init 配置 | 采样位深 |
| `littleEdian` | `boolean` | 自动检测 | 字节序 |

```typescript
const wavData = recorder.encodeWAV(pcmData);
```

### `dataViewToBase64(dataView)`

DataView → base64 字符串。

```typescript
const base64 = recorder.dataViewToBase64(wavData);
```

---

## 示例

### 基础录音 + 频谱

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Recorder Demo</title>
    <script src="../dist/index.js"></script>
  </head>
  <body>
    <button onclick="init()">init</button>
    <button onclick="start()">start</button>
    <button onclick="stop()">stop</button>
  </body>
  <script>
    const recorder = new Recorder();
    const bufferArr = [];

    const init = () => {
      recorder.init({
        analyserOptions: { open: true },
        onDataProcess: (data) => {
          bufferArr.push(...data.buffer);
        },
      });
    };

    const start = async () => {
      await recorder.start();
    };

    const stop = async () => {
      await recorder.stop();
      const pcmData = recorder.encodePCM(bufferArr);
      const wavData = recorder.encodeWAV(pcmData);
      const wavBlob = new Blob([wavData], { type: "audio/wav" });
      const oA = document.createElement("a");
      oA.href = URL.createObjectURL(wavBlob);
      oA.download = "recorder.wav";
      oA.click();
    };
  </script>
</html>
</html>
```

### DeepFilter AI 降噪

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>DeepFilter Demo</title>
    <script src="../dist/index.js"></script>
  </head>
  <body>
    <button onclick="init()">init</button>
    <button onclick="start()">start</button>
    <button onclick="stop()">stop</button>
  </body>
  <script>
    const recorder = new Recorder();
    const bufferArr = [];

    const init = async () => {
      await recorder.init({
        deepFilterOptions: {
          useDeepFilter: true,
          attenuationLimit: 50,  // 降噪强度 0-100
          postFilterBeta: 0.02,  // 后滤波 0-0.05
        },
        processOptions: {
          numChannels: 1,
          sampleBits: 16,
          sampleRate: 16000,  // 可自由配置，DeepFilter 内部 48kHz 处理后自动重采样回来
        },
        onDataProcess: (data) => {
          bufferArr.push(...data.buffer);
        },
      });
      console.log("DeepFilter ready");
    };

    const start = async () => {
      await recorder.start();
    };

    const stop = async () => {
      await recorder.stop();
      const pcmData = recorder.encodePCM(bufferArr);
      const wavData = recorder.encodeWAV(pcmData);
      const wavBlob = new Blob([wavData], { type: "audio/wav" });
      const oA = document.createElement("a");
      oA.href = URL.createObjectURL(wavBlob);
      oA.download = "denoised.wav";
      oA.click();
    };
  </script>
</html>
</html>
```

---

## 生命周期

```
init()  ──▶  start()  ──▶  stop()  ──▶  start()  ──▶  ...
  │              │            │
  │              └─ onDataProcess 循环回调
  │
  └──────────────────────────▶  destroy()  ──彻底释放
```

- `init()` 可重复调用（会关闭旧 context），但录音中不允许
- `stop()` 后状态回到 `ready`，可再次 `start()`
- `destroy()` 后需重新 `init()` 才能使用

---
_Source: https://npm.io/package/audio-recorder-worklet-processor · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
