@seastart/srtc-plugin-deepfilternet 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -0
- package/assets/v2/models/DeepFilterNet3_onnx.tar.gz +0 -0
- package/assets/v2/pkg/df_bg.wasm +0 -0
- package/dist/deepfilternet-processor.d.ts +25 -0
- package/dist/deepfilternet-processor.js +67 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# @seastart/srtc-plugin-deepfilternet
|
|
2
|
+
|
|
3
|
+
基于 [DeepFilterNet](https://github.com/Rikorose/DeepFilterNet)(AudioWorklet + WASM)的 SRTC Web SDK 降噪处理器插件,实现 SDK 的 `TrackProcessor` 接口。
|
|
4
|
+
|
|
5
|
+
相比 RNNoise,DeepFilterNet 降噪质量更高,且支持**运行时可调的降噪强度**与**旁路开关**。底层封装了 [`deepfilternet3-noise-filter`](https://github.com/mezonai/mezon-noise-suppression) 的内核。
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i @seastart/srtc-web-sdk @seastart/srtc-plugin-deepfilternet
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 托管静态资源
|
|
14
|
+
|
|
15
|
+
插件依赖两个静态资源(wasm + 模型,合计约 18MB),需自托管:
|
|
16
|
+
|
|
17
|
+
- `v2/pkg/df_bg.wasm`
|
|
18
|
+
- `v2/models/DeepFilterNet3_onnx.tar.gz`
|
|
19
|
+
|
|
20
|
+
> ⚠️ `v2/pkg`、`v2/models` 这两层子目录由底层包写死,拷贝时**必须保留该目录结构**,且通过 `assetBasePath` 指向其根目录。
|
|
21
|
+
|
|
22
|
+
资源不随源码入库,安装后用包内脚本拉取,再拷到你的静态目录:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# 在本包目录下拉取资源到 assets/
|
|
26
|
+
npm run fetch-assets --prefix node_modules/@seastart/srtc-plugin-deepfilternet
|
|
27
|
+
|
|
28
|
+
# 拷贝到你的静态目录(保留 v2/ 结构)
|
|
29
|
+
cp -r node_modules/@seastart/srtc-plugin-deepfilternet/assets/v2 public/deepfilternet/v2
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
(发布流程见下;npm 上的版本已内置 `assets/v2`,安装后即存在,上面的 `fetch-assets` 仅作兜底。)
|
|
33
|
+
|
|
34
|
+
## 发布
|
|
35
|
+
|
|
36
|
+
在仓库根目录执行(会先构建 web SDK 产出类型、再拉取资源、编译并发布):
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm run publishdeepfilternet
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 使用
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import SRTC from "@seastart/srtc-web-sdk";
|
|
46
|
+
import { DeepFilterNetProcessor } from "@seastart/srtc-plugin-deepfilternet";
|
|
47
|
+
|
|
48
|
+
const srtc = new SRTC();
|
|
49
|
+
|
|
50
|
+
const mic = srtc.createLocalMicTrack();
|
|
51
|
+
await mic.startCapture({ deviceId });
|
|
52
|
+
|
|
53
|
+
// 开启降噪(assetBasePath 指向上一步托管资源的目录)
|
|
54
|
+
const processor = new DeepFilterNetProcessor({
|
|
55
|
+
assetBasePath: "/deepfilternet/",
|
|
56
|
+
suppressionLevel: 50,
|
|
57
|
+
});
|
|
58
|
+
await mic.setProcessor(processor);
|
|
59
|
+
|
|
60
|
+
await srtc.publishLocalTrack(mic);
|
|
61
|
+
|
|
62
|
+
// 运行时调整降噪强度(0–100),无需重建流
|
|
63
|
+
processor.setSuppressionLevel(80);
|
|
64
|
+
|
|
65
|
+
// 运行时旁路 / 恢复
|
|
66
|
+
processor.setEnabled(false);
|
|
67
|
+
processor.setEnabled(true);
|
|
68
|
+
|
|
69
|
+
// 关闭降噪,还原原始麦克风轨道
|
|
70
|
+
await mic.removeProcessor();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 选项
|
|
74
|
+
|
|
75
|
+
| 选项 | 类型 | 默认 | 说明 |
|
|
76
|
+
| --- | --- | --- | --- |
|
|
77
|
+
| `suppressionLevel` | `number` | `50` | 降噪强度 0–100,映射 DeepFilterNet 衰减上限 `atten_lim_db`;可运行时调整 |
|
|
78
|
+
| `assetBasePath` | `string` | `"/"` | 自托管资源根目录(其下需有 `v2/pkg`、`v2/models`) |
|
|
79
|
+
| `cdnUrl` | `string` | — | 高级:直接覆盖资源根 URL,优先级高于 `assetBasePath` |
|
|
80
|
+
|
|
81
|
+
## 运行时方法
|
|
82
|
+
|
|
83
|
+
| 方法 | 说明 |
|
|
84
|
+
| --- | --- |
|
|
85
|
+
| `setSuppressionLevel(level: number)` | 调整降噪强度 0–100,无需重建音频流 |
|
|
86
|
+
| `setEnabled(enabled: boolean)` | 旁路(`false` 输出原始音频)/ 恢复降噪(`true`) |
|
|
87
|
+
|
|
88
|
+
## 注意事项
|
|
89
|
+
|
|
90
|
+
- 仅支持音频轨道;用于视频轨道会抛错。
|
|
91
|
+
- 需在 HTTPS(或 localhost)环境下运行;`AudioContext` 可能需用户手势后才能 `resume`。
|
|
92
|
+
- 采样率固定 48kHz。
|
|
93
|
+
- DeepFilterNet 计算量高于 RNNoise,STFT 最小延迟约 20ms;请在目标设备实测 CPU 与延迟。
|
|
94
|
+
- 切换设备(`changeDeviceId`)或重新 `startCapture` 后,SDK 会自动重建处理器,无需再次 `setProcessor`。
|
|
95
|
+
- 许可:DeepFilterNet 本体为 Apache-2.0/MIT;模型权重的授权请在分发前自行核实。
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ProcessorOptions, TrackProcessor } from "@seastart/srtc-web-sdk";
|
|
2
|
+
export interface DeepFilterNetProcessorOptions {
|
|
3
|
+
suppressionLevel?: number;
|
|
4
|
+
assetBasePath?: string;
|
|
5
|
+
cdnUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class DeepFilterNetProcessor implements TrackProcessor {
|
|
8
|
+
readonly name = "deepfilternet";
|
|
9
|
+
processedTrack?: MediaStreamTrack;
|
|
10
|
+
private suppressionLevel;
|
|
11
|
+
private assetBasePath;
|
|
12
|
+
private cdnUrl?;
|
|
13
|
+
private audioContext?;
|
|
14
|
+
private ownContext;
|
|
15
|
+
private core?;
|
|
16
|
+
private sourceNode?;
|
|
17
|
+
private workletNode?;
|
|
18
|
+
private destinationNode?;
|
|
19
|
+
constructor(options?: DeepFilterNetProcessorOptions);
|
|
20
|
+
private resolveAssetBase;
|
|
21
|
+
init(options: ProcessorOptions): Promise<void>;
|
|
22
|
+
setSuppressionLevel(level: number): void;
|
|
23
|
+
setEnabled(enabled: boolean): void;
|
|
24
|
+
destroy(): Promise<void>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { TrackKind } from "@seastart/srtc-web-sdk";
|
|
2
|
+
import { DeepFilterNet3Core } from "deepfilternet3-noise-filter";
|
|
3
|
+
export class DeepFilterNetProcessor {
|
|
4
|
+
constructor(options = {}) {
|
|
5
|
+
this.name = "deepfilternet";
|
|
6
|
+
this.ownContext = false;
|
|
7
|
+
this.suppressionLevel = options.suppressionLevel ?? 50;
|
|
8
|
+
this.assetBasePath = options.assetBasePath ?? "/";
|
|
9
|
+
this.cdnUrl = options.cdnUrl;
|
|
10
|
+
}
|
|
11
|
+
resolveAssetBase() {
|
|
12
|
+
return (this.cdnUrl ?? this.assetBasePath).replace(/\/+$/, "");
|
|
13
|
+
}
|
|
14
|
+
async init(options) {
|
|
15
|
+
if (options.kind !== TrackKind.Audio) {
|
|
16
|
+
throw new Error("DeepFilterNetProcessor 仅支持音频轨道");
|
|
17
|
+
}
|
|
18
|
+
if (options.audioContext) {
|
|
19
|
+
this.audioContext = options.audioContext;
|
|
20
|
+
this.ownContext = false;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
this.audioContext = new (window.AudioContext || window.webkitAudioContext)({
|
|
24
|
+
sampleRate: 48000,
|
|
25
|
+
latencyHint: "interactive",
|
|
26
|
+
});
|
|
27
|
+
this.ownContext = true;
|
|
28
|
+
}
|
|
29
|
+
this.core = new DeepFilterNet3Core({
|
|
30
|
+
sampleRate: 48000,
|
|
31
|
+
noiseReductionLevel: this.suppressionLevel,
|
|
32
|
+
assetConfig: { cdnUrl: this.resolveAssetBase() },
|
|
33
|
+
});
|
|
34
|
+
await this.core.initialize();
|
|
35
|
+
this.workletNode = await this.core.createAudioWorkletNode(this.audioContext);
|
|
36
|
+
this.sourceNode = this.audioContext.createMediaStreamSource(new MediaStream([options.track]));
|
|
37
|
+
this.destinationNode = this.audioContext.createMediaStreamDestination();
|
|
38
|
+
this.sourceNode.connect(this.workletNode);
|
|
39
|
+
this.workletNode.connect(this.destinationNode);
|
|
40
|
+
const tracks = this.destinationNode.stream.getAudioTracks();
|
|
41
|
+
if (!tracks.length) {
|
|
42
|
+
throw new Error("DeepFilterNetProcessor 未产出音频轨道");
|
|
43
|
+
}
|
|
44
|
+
this.processedTrack = tracks[0];
|
|
45
|
+
}
|
|
46
|
+
setSuppressionLevel(level) {
|
|
47
|
+
this.suppressionLevel = Math.max(0, Math.min(100, Math.floor(level)));
|
|
48
|
+
this.core?.setSuppressionLevel(this.suppressionLevel);
|
|
49
|
+
}
|
|
50
|
+
setEnabled(enabled) {
|
|
51
|
+
this.core?.setNoiseSuppressionEnabled(enabled);
|
|
52
|
+
}
|
|
53
|
+
async destroy() {
|
|
54
|
+
this.core?.destroy();
|
|
55
|
+
this.sourceNode?.disconnect();
|
|
56
|
+
this.destinationNode?.disconnect();
|
|
57
|
+
if (this.ownContext && this.audioContext && this.audioContext.state !== "closed") {
|
|
58
|
+
await this.audioContext.close();
|
|
59
|
+
}
|
|
60
|
+
this.core = undefined;
|
|
61
|
+
this.sourceNode = undefined;
|
|
62
|
+
this.workletNode = undefined;
|
|
63
|
+
this.destinationNode = undefined;
|
|
64
|
+
this.audioContext = undefined;
|
|
65
|
+
this.processedTrack = undefined;
|
|
66
|
+
}
|
|
67
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DeepFilterNetProcessor } from "./deepfilternet-processor.js";
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@seastart/srtc-plugin-deepfilternet",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SRTC Web SDK DeepFilterNet 降噪处理器插件",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"assets"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"fetch-assets": "node scripts/fetch-assets.mjs",
|
|
15
|
+
"build": "tsc -p tsconfig.json"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"deepfilternet3-noise-filter": "^1.2.1"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@seastart/srtc-web-sdk": ">=0.5.0"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"srtc",
|
|
28
|
+
"deepfilternet",
|
|
29
|
+
"denoise",
|
|
30
|
+
"noise-suppression",
|
|
31
|
+
"webrtc"
|
|
32
|
+
],
|
|
33
|
+
"author": "dev@seastart.cn",
|
|
34
|
+
"license": "ISC"
|
|
35
|
+
}
|