更新记录
0.0.1(2026-07-01)
首次发布。
功能
- PCM 流式音频块回调(base64),可配置回调频率
- 实时分贝监听(RMS 算法,返回原始 dB 与归一化 0-100)
- 静音检测(阈值/时长/动作 stop|commit)
- 音频中断处理(来电、麦克风被抢占时保存已完成部分)
- 麦克风权限自动请求与拒绝回调
- 最大录音时长限制
- Android(AudioRecord)+ iOS(AVAudioRecorder)双端原生实现
- 非原生平台占位实现
平台支持
- uni-app · app-android 5.0+(app-vue / app-nvue)
- uni-app · app-ios 12.0+(app-vue / app-nvue)
- uni-app x · app-android 5.0+
- uni-app x · app-ios 12.0+
平台兼容性
uni-app(5.14)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| - | - | × | × | - | - | √ | √ | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(5.0)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | - | - | - | - |
hj-speech-modal 实时语音录音插件
一个纯录音功能的 UTS 插件,无 UI 部分,提供 PCM 流式音频块回调、实时分贝监听、静音检测、音频中断处理与权限管理,专为实时语音转写(如 OpenAI Realtime Transcription)场景设计。支持 uni-app(app-vue / app-nvue)与 uni-app x 双模式。
特性
- PCM 流式音频块回调:每 N 毫秒回调 base64 编码的 PCM 数据块,可直接发送到 WebSocket
- 文件流式写入:录音同时写入临时文件,实时提供文件路径
- 实时分贝监听:同时返回原始 dB 值(RMS 算法)与归一化音量(0-100)
- 静音自动检测:连续低于阈值达指定时长后自动停止或仅通知
- 音频中断处理:来电、麦克风被抢占时保存已完成部分并回调
- 权限管理:自动请求麦克风权限,拒绝时回调通知
- 最大时长限制:超时自动停止
- Android/iOS 双端适配:统一 API,透明处理平台差异
支持平台
| 平台 | 支持情况 | 说明 |
|---|---|---|
| uni-app · app-android(app-vue / app-nvue) | ✅ 5.0+(minSdkVersion 21) | 原生 AudioRecord 实现 |
| uni-app · app-ios(app-vue / app-nvue) | ✅ 12.0+ | 原生 AVAudioRecorder 实现 |
| uni-app x · app-android | ✅ 5.0+ | 原生 AudioRecord 实现 |
| uni-app x · app-ios | ✅ 12.0+ | 原生 AVAudioRecorder 实现 |
| H5 / 小程序 | ⚠️ 占位 | 提示当前平台不支持 |
原生能力仅在 App(Android / iOS)生效;H5 / 小程序为占位实现,会触发
onError('platform_unsupported')。
快速开始
- 将
hj-speech-modal目录复制到工程的uni_modules/下 - iOS 需在
manifest.json配置麦克风权限描述(见下文权限说明) - 导入并使用:
import { startRecording, stopRecording } from '@/uni_modules/hj-speech-modal'
startRecording({
sampleRate: 16000,
channels: 1,
encoding: 'pcm',
callbackInterval: 100,
onAudioChunk: (chunk, timestamp, chunkIndex) => {
// 将 base64 PCM 数据块发送到转写服务
},
: (decibel, normalized) => {
// 更新音量条 UI
},
onRecordComplete: (path, durationMs) => {
console.log('录音完成:', path, durationMs)
},
onError: (code, message) => {
console.error('录音错误:', code, message)
}
})
// 停止
stopRecording()
API 文档
startRecording(options)
开始录音。若已在录音中,会忽略本次调用。
参数 HjSpeechRecorderOptions:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| sampleRate | number | 否 | 16000 | 采样率(Hz),常用 8000/16000/24000/44100 |
| channels | number | 否 | 1 | 声道数:1=单声道,2=立体声 |
| encoding | 'pcm' | 'aac' | 否 | 'pcm' | 编码格式,当前仅 pcm 生效 |
| maxDuration | number | 否 | 0 | 最大录音时长(秒),0 表示不限制 |
| callbackInterval | number | 否 | 100 | 回调频率(毫秒) |
| silenceDetection | SilenceDetectionOptions | 否 | - | 静音检测配置 |
| onStart | () => void | 否 | - | 录音开始回调 |
| onAudioChunk | (chunk: string, timestamp: number, chunkIndex: number) => void | 否 | - | 音频块回调,chunk 为 base64 PCM |
| onFilePathUpdate | (path: string) => void | 否 | - | 录音文件路径确定回调 |
| onVolumeChange | (decibel: number, normalized: number) => void | 否 | - | 音量回调,decibel 约 -60~0,normalized 0~100 |
| onSilenceDetected | (durationMs: number) => void | 否 | - | 静音触发回调 |
| onRecordComplete | (path: string, durationMs: number) => void | 否 | - | 录音正常停止回调,path 为 file:// 格式 |
| onError | (code: string, message: string) => void | 否 | - | 错误回调 |
| onPermissionDenied | () => void | 否 | - | 麦克风权限被拒绝回调 |
| onInterrupt | (path: string, durationMs: number) => void | 否 | - | 录音被中断回调(来电等) |
SilenceDetectionOptions:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| enabled | boolean | 否 | false | 是否启用静音检测 |
| threshold | number | 否 | 10 | 静音阈值(归一化音量 0-100) |
| duration | number | 否 | 1500 | 静音持续时间(毫秒) |
| action | 'stop' | 'commit' | 否 | 'stop' | 静音后动作:stop 自动停止,commit 仅回调通知 |
stopRecording()
停止录音,触发 onRecordComplete 回调。
isRecording(): boolean
返回是否正在录音。
getRecordingFilePath(): string | null
返回当前录音文件路径(file:// 格式),未录音返回 null。
回调时机
| 回调 | 触发时机 | 频率 |
|---|---|---|
| onStart | 录音启动后 | 一次 |
| onFilePathUpdate | 文件路径确定后 | 一次 |
| onAudioChunk | 录音进行中 | 每 callbackInterval 毫秒 |
| onVolumeChange | 录音进行中 | 每 callbackInterval 毫秒 |
| onSilenceDetected | 静音检测触发时 | 一次 |
| onRecordComplete | 正常停止时 | 一次 |
| onInterrupt | 音频中断时 | 一次 |
| onPermissionDenied | 权限拒绝时 | 一次 |
| onError | 发生错误时 | 一次 |
所有回调均在主线程执行,可直接更新 UI。
错误码
| code | 含义 | 触发平台 |
|---|---|---|
| platform_unsupported | 当前平台不支持录音 | H5/小程序占位 |
| ACTIVITY_NULL | 无法获取当前 Activity | Android |
| FILE_ERROR | 创建录音文件失败 | Android |
| BUFFER_ERROR | 无法获取有效的音频缓冲区大小 | Android |
| INIT_ERROR | AudioRecord / AVAudioRecorder 初始化失败 | Android / iOS |
| PERMISSION_DENIED | 录音权限未授予 | Android |
| AUDIO_SESSION_ERROR | iOS AudioSession 配置失败 | iOS |
| PREPARE_ERROR | iOS prepareToRecord 失败 | iOS |
| ENCODE_ERROR | iOS 音频编码错误 | iOS |
iOS 权限拒绝通过
onPermissionDenied回调,不归入 error code。
权限说明
Android
android.permission.RECORD_AUDIO(必须,录音)android.permission.MODIFY_AUDIO_SETTINGS(可选)
插件 app-android/config.json 已声明 RECORD_AUDIO,首次使用自动请求。
iOS
在 manifest.json → app-plus → distribute → ios → privacyDescription 中配置麦克风权限描述:
"privacyDescription": {
"NSMicrophoneUsageDescription": "需要使用麦克风进行录音"
}
uni-app x 工程则需在
nativeResources/ios/Info.plist中配置(uni-app x 的 manifest 不读此字段)。
如需后台录音,配置 UIBackgroundModes 含 audio。
隐私声明
- 采集数据:仅访问设备麦克风进行录音。
- 数据用途:音频数据仅保存在应用本地临时目录,不主动上传。
- 不含广告:本插件不包含任何广告组件。
- 不含第三方 SDK:仅使用系统原生录音 API(Android AudioRecord / iOS AVFoundation)。
示例代码
1. 基础录音
import { startRecording, stopRecording } from '@/uni_modules/hj-speech-modal'
startRecording({
onAudioChunk: (chunk, timestamp, chunkIndex) => {
console.log('收到音频块', chunkIndex, chunk.length)
},
onRecordComplete: (path, durationMs) => {
console.log('录音文件:', path, '时长:', durationMs, 'ms')
},
onError: (code, message) => console.error(code, message)
})
setTimeout(() => stopRecording(), 5000)
2. 实时分贝音量条
import { startRecording, stopRecording } from '@/uni_modules/hj-speech-modal'
const volumePercent = ref(0)
startRecording({
: (decibel, normalized) => {
volumePercent.value = normalized // 0-100
},
onError: (code, message) => console.error(code, message)
})
3. 静音自动停止
startRecording({
silenceDetection: {
enabled: true,
threshold: 10,
duration: 1500,
action: 'stop' // 静音 1.5 秒自动停止
},
onSilenceDetected: (durationMs) => {
console.log('检测到静音', durationMs, 'ms')
},
onRecordComplete: (path, durationMs) => {
console.log('录音完成', path)
}
})
4. 配合实时语音转写 WebSocket
import { startRecording, stopRecording } from '@/uni_modules/hj-speech-modal'
const ws = new WebSocket('wss://asr.example.com/realtime')
startRecording({
sampleRate: 24000,
channels: 1,
encoding: 'pcm',
callbackInterval: 100,
silenceDetection: {
enabled: true,
threshold: 10,
duration: 1500,
action: 'commit' // 静音时仅通知,由 JS 层 commit
},
onAudioChunk: (chunk) => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'input_audio_buffer.append', audio: chunk }))
}
},
onSilenceDetected: () => {
ws.send(JSON.stringify({ type: 'input_audio_buffer.commit' }))
},
onRecordComplete: (path) => console.log('完成', path),
onError: (code, message) => console.error(code, message)
})
注意事项
- 仅支持 PCM:当前编码格式仅
pcm生效,aac参数保留但未实现。 - iOS 读取机制:iOS 通过定时器增量读取录音文件并 base64 编码回调,与 Android(直接读取 AudioRecord 缓冲区)实现不同,但回调数据格式一致。
- 采样率建议:语音转写场景推荐 16000Hz 或 24000Hz;音乐场景推荐 44100Hz。
- 回调频率:
callbackInterval越小实时性越好但 CPU 占用越高,建议 100ms。 - 线程安全:所有回调在主线程执行,可直接更新 UI。
- 文件路径:录音文件保存在应用临时目录(Android cacheDir / iOS NSTemporaryDirectory),路径以
file://开头,可直接用于uni.uploadFile。

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 21
赞赏 1
下载 12373570
赞赏 1927
赞赏
京公网安备:11010802035340号