更新记录
1.0.2(2025-10-13)
fix
- Android:修复当注释/省略
foregroundTitle
、foregroundText
、foregroundImportance
时触发的 NullPointerException: null cannot be cast to non-null type kotlin.Any
。
- 在
app-android/index.uts
中为 foregroundImportance
增加空值保护,未提供时不再调用 mapImportance
,并允许将 null
传入 Kotlin 的 configureForegroundService
。
- 在
app-android/utils.uts
中将 mapImportance
的参数签名放宽为 any | null
,传入 null
时返回 null
以沿用默认通知重要度。
- 行为变更:未配置任何
foreground*
文案/重要度时,录音可正常启动,通知标题/正文/重要度回落到服务默认值(保持后台录音稳定)。
1.0.1(2025-10-11)
fix
1.0.0(2025-09-05)
项目初始化
- iOS和Android基础录音功能实现
- 暂停/恢复、进度监控、格式支持等核心功能
- UTS混合开发架构搭建
查看更多
平台兼容性
uni-app(4.76)
Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
√ |
√ |
- |
- |
- |
- |
√ |
√ |
- |
微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
快应用-华为 |
快应用-联盟 |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
uni-app x(4.76)
Chrome |
Safari |
Android |
iOS |
鸿蒙 |
微信小程序 |
- |
- |
√ |
√ |
- |
- |
hens-recorder
跨端统一录音插件 - UTS实现版本
✨ 特性
- 🎯 跨平台一致性: iOS/Android行为完全统一,相同的API,相同的响应
- 📱 原生性能: UTS混合开发,Swift/Kotlin原生实现,性能卓越
- 🎚️ 完整功能: 录音/暂停/恢复/停止,实时进度,状态监控
- 🔄 智能缓存: iOS端状态缓存优化,减少桥接调用
- 🚨 统一错误处理: 标准化错误码格式,便于应用层处理
- 📊 多订阅模式: 支持多个进度/状态/错误监听器
- 🎵 统一格式: 两端都输出m4a(AAC)格式
- 📂 私有存储: 统一使用应用私有目录,无需额外存储权限
🚀 快速开始
基本用法
import { ensurePermissions, start, pause, resume, stop, getStatus,
onRecordingProgress, offRecordingProgress, onStateChange,
offStateChange, onError, offError, getCapabilities,
getRecommendedOutputDir }
from '@/uni_modules/hens-recorder'
import type { RecorderOptions } from '@/uni_modules/hens-recorder/utssdk/interface.uts'
// 1. 确保权限
ensurePermissions({
options: { mic: true, notifications: 'auto' },
success: () => {
// 2. 开始录音
const dir = getRecommendedOutputDir()
const options: RecorderOptions = {
format: 'm4a', // 固定m4a格式(AAC编码)
quality: 'medium', // 音质: high/medium/low
maxDurationMs: 0, // 0=无限制
foregroundEnabled: true,
foregroundChannelId: 'recorder',
foregroundChannelName: '录音服务',
interruption: 'pause', // 中断策略: pause/stop/ignore
progressIntervalMs: 500, // 进度间隔[100,2000]ms
ensurePermissions: true // 自动检查权限
}
if (dir && dir.length > 0) {
const normalized = dir.endsWith('/') ? dir.slice(0, -1) : dir
options.outputFilePath = `${normalized}/demo_${Date.now()}.m4a`
}
start({
options,
success: (res) => { console.log('录音开始:', res) },
fail: (e) => { console.log('录音失败:', e) }
})
},
fail: (e) => { console.log('权限申请失败:', e) }
})
进度与状态监控
// 进度监控 - 支持多订阅
const progressId = onRecordingProgress((status) => {
console.log('录音进度:', status.durationMs, 'ms')
})
// 状态变化监控
const stateId = onStateChange((state, status) => {
console.log('状态变化:', state) // idle/recording/paused
})
// 错误监控
const errorId = onError((err) => {
console.log('录音错误:', err.errCode, err.errMsg)
})
// 控制操作
pause({ success: () => {}, fail: console.error })
resume({ success: () => {}, fail: console.error })
stop({ success: (res) => {
console.log('录音完成:', res.status.filePath)
}, fail: console.error })
// 取消监听
offRecordingProgress(progressId)
offStateChange(stateId)
offError(errorId)
📋 API参考
核心配置
参数 |
类型 |
默认值 |
说明 |
format |
'm4a' |
'm4a' |
音频格式(固定m4a/AAC) |
quality |
'high'|'medium'|'low' |
'medium' |
音质级别 |
maxDurationMs |
number |
0 |
最大时长(毫秒),0=无限制 |
progressIntervalMs |
number |
500 |
进度间隔[100,2000]ms |
interruption |
'pause'|'stop'|'ignore' |
'pause' |
音频中断策略 |
outputFilePath |
string |
- |
自定义输出文件路径(应用私有目录) |
foregroundEnabled |
boolean |
true |
Android: 是否启用前台服务 |
foregroundChannelId |
string |
- |
Android: 通道ID(需与通知配置一致) |
foregroundChannelName |
string |
- |
Android: 通道名称 |
foregroundTitle |
string |
- |
Android: 前台通知标题 |
foregroundText |
string |
- |
Android: 前台通知正文 |
foregroundImportance |
'min'|'low'|'default'|'high'|'max' |
'default' |
Android: 通知重要度 |
💡 建议使用 getRecommendedOutputDir()
获取当前平台的私有录音目录,再拼接文件名构造 outputFilePath
,避免手写路径带来的兼容问题。
响应格式
// RecorderResult
{
status: {
state: 'idle' | 'recording' | 'paused',
durationMs: number, // 累计录音时长(毫秒)
filePath: string // 录音文件路径
},
message?: string, // 附加消息
actualFormat: 'm4a', // 实际输出格式
autoStopReason?: 'manual' | 'maxDuration' | 'interruption' | 'error'
}
⚠️ 错误码说明
标准格式: "9010XXX:详细说明"
错误码 |
说明 |
可重试 |
9010001 |
麦克风权限被拒绝 |
是 |
9010002 |
录音文件创建失败 |
是 |
9010003 |
录音器初始化失败 |
是 |
9010004 |
录音器状态错误 |
视状态 |
9010005 |
存储空间不足 |
是 |
9010006 |
录音格式不支持 |
否 |
9010007 |
音频会话设置失败 |
是 |
9010008 |
录音准备失败 |
是 |
9010009 |
录音开始失败 |
是 |
9010010 |
音频编码错误 |
是 |
9010011 |
文件系统错误 |
是 |
9010012 |
设备音频硬件不可用 |
是 |
🔧 平台特性
iOS
- ✅ AVFoundation + AVAudioRecorder
- ✅ 状态缓存优化性能
- ✅ 后台录音支持
- ✅ 音频会话中断处理
- ✅ 简化的实例管理
Android
- ✅ MediaRecorder + 前台服务
- ✅ API 24+ 原生暂停/恢复
- ✅ 音频焦点管理
- ✅ 自动存储清理
- ✅ 通知权限适配(Android 13+)
📝 注意事项
- 格式统一: 两端都输出m4a(AAC)格式,
RecorderResult.actualFormat === 'm4a'
- 权限处理: 建议使用
ensurePermissions
统一处理权限申请
- 错误监控: 推荐使用
onError
统一监听错误,便于集中处理
- 进度监控: iOS/Android都支持多订阅模式,行为完全一致
- 存储路径: 统一使用应用私有目录,无需WRITE_EXTERNAL_STORAGE权限
🔗 相关链接