@ cantoo/ 电容- audio- capture
抓取麦克风音频的 Capacitor v7 插件 网络/ Android / iOS 和流 生PCM( 原PCM) 作为
Float32Array(莫诺)块给消费者. 没有格式转换, 没有压缩 —— 您的应用程序决定如何处理 样本.
平台
| 平台 | 执行情况 | 最低 |
|---|---|---|
| 网页 | getUserMedia + 键 AudioWorklet (DSP脱离主线) | 现代浏览器 |
| 机器人 | AudioRecord (44.1 kHz PCM16) 专用线上 | API 23 (Android 6) (英语) |
| iOS系统 | AVAudioEngine.installTap 在一个专用队列上 | iOS 14 |
原生抓取单声道,重新标出 targetSampleRate 通过线性
内插,应用可选的 RMS 静态过滤,以及每块船
在桥上作为基座64小-endian Float32 PCM. JS包装器解码
那个基数64一次,把消费者交给a Float32Array - 没有了
插件内部的编码/解码.
安装
pnpm add @cantoo/capacitor-audio-capture
# or: npm i @cantoo/capacitor-audio-capture
# or: yarn add @cantoo/capacitor-audio-capture
npx cap sync
权限
- iOS系统 - 加进
Info.plist数字 :<key>NSMicrophoneUsageDescription</key> <string>Used to record audio while you use the app.</string> - 机器人 —— 说
RECORD_AUDIO已被插件声明;权限是 在第一次呼叫中运行时请求startCapture。 。 。 . - 网页 - 需要安全上下文(HTTPS或
localhost)和用户必须 允许麦克风进入.
使用量
import { AudioCapture } from '@cantoo/capacitor-audio-capture';
await AudioCapture.startCapture({
chunkDurationMs: 250,
targetSampleRate: 16000,
silenceThreshold: 0.01,
listener: (sequence, chunk) => {
// chunk: Float32Array, mono, at targetSampleRate (samples in -1..1)
console.log(sequence, chunk.length);
},
});
// later
await AudioCapture.stopCapture();
await AudioCapture.release();
实例
发送到后端 (请求前的基数64)
listener: (_seq, chunk) => {
const bytes = new Uint8Array(chunk.buffer);
let bin = '';
for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);
const base64 = btoa(bin);
fetch('/api/audio', {
method: 'POST',
headers: { 'Content-Type': 'application/octet-stream' },
body: chunk.buffer,
});
}
客户端 WAV 缓冲数字 :
await AudioCapture.startCapture({
chunkDurationMs: 250,
targetSampleRate: 16000,
silenceThreshold: 0,
accumulate: true,
});
// ... user stops ...
const { audio } = await AudioCapture.stopCapture();
// `audio` is a Float32Array of the full session — convert to Int16,
// prepend a 44-byte WAV header, and you have a playable file.
API 密码
startCapture(options?)
| 外地 | 类型 | 默认 | 说明 |
|---|---|---|---|
chunkDurationMs | number | 1000 | 每个被排放块的持续时间. |
targetSampleRate | number | 16000 | 目标样本率。 音频被复制到此值 . |
silenceThreshold | number (条例0.1) | 0 | RMS 低于此值的块被丢弃(0 / 禁用). |
voiceProcessing | boolean | true | 切换所有平台的平台语音预处理包(echo取消,噪声抑制,自動增收). 设定 false 最原始的信号. |
listener | (sequence: number, chunk: Float32Array) => void | —— 说 | 流出消费者. 没有它,捕捉运行 但释放什么. |
accumulate | boolean | false | 缓冲每个被排放的块,然后返回压缩的PCM stopCapture静态块被跳过 . |
sequence 每个会话单调增加,每会话重播
startCapture即使是静音掉下来的块 也会增加
检测,这样消费者就可以检测出时间差距.
stopCapture()
停止抓取并释放活性抓取会话. 回返
{ audio: Float32Array }当会议开始时 accumulate: true, (中文(简体) ),
audio 是缩合的PCM( Mono Float32 at targetSampleRate页:1
这是空的 Float32Array。 。 。 .
release()
停止抓取,去除收听器,并释放出所有打开的资源.
导出类型
import type {
AudioCapturePlugin,
AudioChunkListener, // (sequence, chunk: Float32Array) => void
AudioCaptureError,
AudioCaptureErrorCode,
StartCaptureOptions,
} from '@cantoo/capacitor-audio-capture';
处理错误
插件中每个被拒绝的许诺都带有 .code 从闭口而出,
iOS、Android和Web之间完全相同。 分会 .code 而不是分析
消息 - 消息短而稳定,但只有代码是其中的一部分
公共合同.
| 代码 | 当它升起 |
|---|---|
PERMISSION_DENIED | 用户拒绝麦克风访问(或从未批准). |
MICROPHONE_UNAVAILABLE | 麦克风缺失,繁忙,或无法初始化(没有输入设备,硬件/OS级问题). |
ALREADY_CAPTURING | startCapture 当会话已经运行时调用. |
UNAVAILABLE | 只有网络 : getUserMedia 或者说 AudioWorklet 在此环境中缺失. |
INTERNAL_ERROR | 任何与上述类别不符的都退后. |
import { AudioCapture, type AudioCaptureError } from '@cantoo/capacitor-audio-capture';
try {
await AudioCapture.startCapture({ /* ... */ });
} catch (e) {
const code = (e as AudioCaptureError).code;
if (code === 'PERMISSION_DENIED') {
// prompt user to enable mic access in OS settings
} else if (code === 'MICROPHONE_UNAVAILABLE') {
// surface a "no microphone" state in UI
} else if (code === 'ALREADY_CAPTURING') {
// ignore or call stopCapture() first
}
}
为什么64垒在电线上, Float32Array 在API吗?
Capacitor的原生QQJS桥只能承载JSON-串行价值.
将PCM样本编码为基数64比JSON数组小~33%
并显著地更快地将两侧的序列化/去序列化. 这个
插件的包装器 一个 解码(基数64) − Float32Array)所以说
消费者总是收到音频的自然表示:
单采样数组 [-1, 1]。 。 。 .
网络和内容-安全政策
在网络上 AudioWorkletProcessor 内置为字符串并通过
URL.createObjectURL(new Blob([...]))如果主机应用程序有严格的CSP
这不允许 blob: 内 script-src 编号 : worker-src,工作间
无法装入 - 只是允许 blob: 在适当的指令.
许可证
麻省理工学院 罐头