更新记录

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')

快速开始

  1. hj-speech-modal 目录复制到工程的 uni_modules/
  2. iOS 需在 manifest.json 配置麦克风权限描述(见下文权限说明)
  3. 导入并使用:
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.jsonapp-plusdistributeiosprivacyDescription 中配置麦克风权限描述:

"privacyDescription": {
  "NSMicrophoneUsageDescription": "需要使用麦克风进行录音"
}

uni-app x 工程则需在 nativeResources/ios/Info.plist 中配置(uni-app x 的 manifest 不读此字段)。

如需后台录音,配置 UIBackgroundModesaudio

隐私声明

  • 采集数据:仅访问设备麦克风进行录音。
  • 数据用途:音频数据仅保存在应用本地临时目录,不主动上传。
  • 不含广告:本插件不包含任何广告组件。
  • 不含第三方 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)
})

注意事项

  1. 仅支持 PCM:当前编码格式仅 pcm 生效,aac 参数保留但未实现。
  2. iOS 读取机制:iOS 通过定时器增量读取录音文件并 base64 编码回调,与 Android(直接读取 AudioRecord 缓冲区)实现不同,但回调数据格式一致。
  3. 采样率建议:语音转写场景推荐 16000Hz 或 24000Hz;音乐场景推荐 44100Hz。
  4. 回调频率callbackInterval 越小实时性越好但 CPU 占用越高,建议 100ms。
  5. 线程安全:所有回调在主线程执行,可直接更新 UI。
  6. 文件路径:录音文件保存在应用临时目录(Android cacheDir / iOS NSTemporaryDirectory),路径以 file:// 开头,可直接用于 uni.uploadFile

更新记录

changelog.md

隐私、权限声明

1. 本插件需要申请的系统权限列表:

需要麦克风录音权限

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。