更新记录
1.1.0(2026-10-18)
兼容蒸汽模式
平台兼容性
uni-app(5.26)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | √ | × | × | √ | × | √ | √ | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(5.26)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | √ | √ | × | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| × | × | × | √ |
UTS 分片录音 X
前台开始 → 退后台或锁屏继续录音 → 分片保存 → 停止后拿到完整音频。
适合语音采集、访谈记录、录音上传与转写前的音频采集环节。原生录制 AAC / M4A,无第三方录音 SDK;界面、上传和业务处理由你的项目决定。
| 能力 | 用法 |
|---|---|
| 录音控制 | 开始、暂停、继续、停止 |
| 后台录音 | Android 麦克风前台服务;iOS 后台音频模式 |
| 通知控制 | Android 通知栏暂停、继续、停止,标题和说明可自定义 |
| 自动分片 | 按毫秒设置分片时长,每段完成后回调本地路径 |
| 完整音频 | 停止后返回合并结果,原始分片继续保留 |
| 状态与音量 | 查询录音时长、状态、片段数量,监听分贝变化 |
| 历史记录 | 会话索引落盘,重开 App 后查看已保存的录音与片段 |
| 中断保护 | 异常结束后找回已完成片段,标记为“已中断” |
| 文件管理 | 查询会话与片段,删除会话文件 |
| 演示页 | 附带权限申请、录音控制、片段试听与复制路径 |
兼容性
| 项目类型 | Android | iOS | 演示文件 |
|---|---|---|---|
| uni-app x · Vapor 蒸汽模式 | 支持,Android 7.0+ | 支持 | index.uvue |
| uni-app x · VDOM 模式 | 支持,Android 7.0+ | 支持 | index.uvue |
| uni-app · Vue3 | 支持,Android 7.0+ | 支持 | index.vue |
| Web、小程序、鸿蒙、nvue | 不支持 | 不支持 | — |
使用 HBuilderX 5.26 或以上版本。两种 uni-app x 渲染模式共用 UTS API 和演示页,无需改插件调用。
录音必须由用户在前台页面主动开始。开始后可以离开页面、切到桌面或锁屏。Android 使用带通知的麦克风前台服务和录音期间的 CPU 唤醒锁;iOS 使用系统后台音频能力。
强制停止、系统终止进程、关机后不能继续录音。重新打开 App 会恢复历史索引与可用片段,不会自动开启麦克风。Android 厂商省电策略仍可能终止服务;iOS 来电、麦克风被占用等情况由系统决定中断和恢复。
第 1 步:导入插件
把整个 austin-recorder-x 文件夹放到项目的 uni_modules 中,保留 utssdk 目录。
你的项目/
uni_modules/
austin-recorder-x/
package.json
index.uvue ← uni-app x 演示页
index.vue ← uni-app Vue3 演示页
utssdk/ ← 必须保留
插件 ID 为 austin-recorder-x。从旧的 austin-recorder 迁移时,将业务代码的导入路径改为新 ID;不要在同一应用里同时启动两个录音引擎。
第 2 步:配置麦克风与后台音频
Android
插件自带 utssdk/app-android/AndroidManifest.xml,自动合并以下配置,无需在业务页面重复声明:
| 配置 | 用途 |
|---|---|
RECORD_AUDIO |
用户授权后访问麦克风 |
FOREGROUND_SERVICE、FOREGROUND_SERVICE_MICROPHONE |
运行麦克风前台服务 |
WAKE_LOCK |
录音时维持 CPU 工作,暂停或停止后释放 |
POST_NOTIFICATIONS |
Android 13+ 展示通知栏录音控制 |
RecorderForegroundService |
注册 microphone 类型的非导出服务 |
首次导入或从旧版升级后,必须重新制作并安装自定义基座。仅热更新页面无法添加原生服务。开始前调用 requestRecorderPermission:先申请麦克风,Android 13+ 再询问通知权限。拒绝通知不影响麦克风授权,但通知栏控制可能不可见,此时回到页面操作。
默认使用应用私有目录,不需要相册或外部存储权限。前台服务的“前台”指系统服务等级,不要求用户一直停留在录音页面。
iOS · uni-app x
打开项目根目录的 manifest.json,合并下面的配置。麦克风文案改成你的真实业务用途:
{
"app-ios": {
"distribute": {
"UIBackgroundModes": "audio",
"privacyDescription": {
"NSMicrophoneUsageDescription": "用于录制用户主动发起的语音记录"
}
}
}
}
也可以在 HBuilderX 的 manifest.json 可视化页面进入「iOS App配置」:后台运行能力填写 audio,隐私许可描述填写麦克风用途。已有其他后台模式时保留它们,以逗号分隔。
iOS · 普通 uni-app
普通 uni-app 的配置位置不同,放在 app-plus.distribute.ios:
{
"app-plus": {
"distribute": {
"ios": {
"UIBackgroundModes": "audio",
"privacyDescription": {
"NSMicrophoneUsageDescription": "用于录制用户主动发起的语音记录"
}
}
}
}
}
这两项必须配置在宿主项目中:NSMicrophoneUsageDescription 用于申请麦克风,UIBackgroundModes: audio 用于后台录音。插件中虽附带默认 Info.plist,接入时仍请按上面的对应路径填写宿主 manifest.json。
配置后重新云打包并安装新基座;仅同步页面或原生插件、重新签名已有基座,不能补齐旧安装包的用途说明和后台声明。配置位置参考 uni-app x iOS 配置 与 uni-app 后台运行配置。
第 3 步:制作并选择自定义基座
- 在 HBuilderX 选择当前项目,进入「运行 → 运行到手机或模拟器 → 制作自定义调试基座」。
- 选择 Android 或 iOS;iOS 真机使用与你的应用标识匹配的证书和描述文件。录音本身不需要 APNs 推送证书或
.p8。 - 打包完成后,在运行配置中选择「自定义基座」,安装到设备再运行项目。
- 后续修改原生插件或权限配置时重新制作基座;仅修改演示页样式或业务调用时正常运行即可。
第 4 步:先打开演示页
在 pages.json 的 pages 数组中加入:
{
"path": "uni_modules/austin-recorder-x/index",
"style": {
"navigationBarTitleText": "分片录音 X",
"disableScroll": true
}
}
从你的页面进入:
uni.navigateTo({ url: '/uni_modules/austin-recorder-x/index' })
测试顺序:选择 10秒 → 开始录音并授权 → 返回桌面、锁屏至少 30 秒 → 回页面确认片段增加 → 暂停、继续 → 停止并保存 → 试听片段和完整音频。Android 也可以从通知栏控制;停止后重新打开 App 检查历史录音。
要使用自己的页面,把插件内的 index.uvue(uni-app x)或 index.vue(uni-app Vue3)复制到 pages/recorder/index.uvue / .vue,并注册 pages/recorder/index。页面中的 API 与类型均使用 @/uni_modules/austin-recorder-x 下的绝对路径导入,无需改动导入路径。
演示页切后台、返回上一页均保留录音,重新进入会读取当前状态。结束录音请点击“停止并保存”或 Android 通知中的“停止”。业务中的持续状态管理、上传等回调建议放在应用级模块,页面通过查询 API 刷新;后台页面回调执行时机不能代替原生录音状态。
第 5 步:接入自己的按钮
uni-app x 页面在 <script setup lang="uts"> 中使用以下代码:
import {
requestRecorderPermission, startRecorder, stopRecorder,
pauseRecorderSync, resumeRecorderSync
} from '@/uni_modules/austin-recorder-x'
import {
StartRecorderOptions, StopRecorderOptions,
RequestRecorderPermissionOptions
} from '@/uni_modules/austin-recorder-x'
function start() {
const permission: RequestRecorderPermissionOptions = {
success: (res) => {
if (!res.granted) return
const options: StartRecorderOptions = {
segmentDurationMs: 10000,
maxDurationMs: 3600000,
enableMetering: true,
notificationTitle: '语音记录',
notificationText: '录音进行中,点击返回应用',
onStateChange: (event) => { console.log('状态', event.status) },
onSegmentReady: (segment) => { console.log('片段路径', segment.filePath) },
fail: (error) => { console.log(error.errCode, error.errMsg, error.note) }
}
startRecorder(options)
},
fail: (error) => { console.log('权限失败', error.errMsg) }
}
requestRecorderPermission(permission)
}
function pause() { console.log(pauseRecorderSync()) }
function resume() { console.log(resumeRecorderSync()) }
function stop() {
const options: StopRecorderOptions = {
reason: 'manual-stop',
success: (session) => {
// 以这个回调中的路径为准,iOS 多片段合并为异步操作。
console.log('完整音频', session.mergedFilePath)
console.log('合并说明', session.mergeNote)
},
fail: (error) => { console.log(error.errCode, error.errMsg, error.note) }
}
stopRecorder(options)
}
普通 Vue3 的 <script setup> 用法相同,删除类型导入及变量上的 : XxxOptions 标注即可。完整示例见 index.vue。
播放已保存的录音
等待停止并保存成功后,传入 session.mergedFilePath 或 segment.filePath。iOS 给 uni.createInnerAudioContext() 传递本插件返回的绝对路径时,加上 file:// 前缀;不要额外调用 encodeURI。演示页已处理。
import { getRecorderStatusSync } from '@/uni_modules/austin-recorder-x'
const previewAudio = uni.createInnerAudioContext()
previewAudio.onError((error) => { console.log(error.errCode, error.errMsg) })
function playRecording(path: string) {
if (path.length == 0) return
previewAudio.stop()
const isIOS = getRecorderStatusSync().platform == 'ios'
previewAudio.src = isIOS && path.startsWith('/') ? 'file://' + path : path
previewAudio.play()
}
onUnload(() => { previewAudio.destroy() })
普通 Vue3 页面删除参数上的 : string。file:// 仅在播放时添加,插件返回的路径仍用于文件管理和业务处理。
API 一览
| API | 参数 | 返回 / 结果 |
|---|---|---|
requestRecorderPermission(options) |
权限回调 | success(RecorderPermissionResult) 或 fail(RecorderFail) |
startRecorder(options) |
StartRecorderOptions |
success(RecorderSessionInfo) 表示已开始,不是录音结束 |
pauseRecorderSync() |
无 | RecorderOperationResult |
resumeRecorderSync() |
无 | RecorderOperationResult |
stopRecorder(options) |
reason?、结果回调 |
success(RecorderSessionInfo) 返回录音及合并结果 |
getRecorderStatusSync() |
无 | RecorderStatus |
getCurrentSessionSync() |
无 | RecorderSessionInfo \| null |
getRecorderHistorySync() |
无 | 历史快照:sessions 会话数组、segments 已完成片段数组 |
listRecorderSessionsSync() |
无 | 保留的原生会话数组接口;iOS 页面请用历史快照 |
listRecorderSegmentsSync(sessionId) |
会话 ID | 保留的原生片段数组接口;iOS 页面请用历史快照 |
deleteRecorderSessionSync(sessionId) |
会话 ID | 删除该会话及文件;录音/暂停中及 iOS 合并中的会话不可删除 |
openRecorderPermissionSettingsSync() |
无 | 打开应用权限设置,返回操作结果 |
普通 uni-app Vue3 中,使用 if (session && session.sessionId) 判断是否取到了当前会话;部分运行基座在无会话时会返回空字符串,不能只判断 session != null。
开始录音 StartRecorderOptions
| 字段 | 类型 / 默认值 | 说明 |
|---|---|---|
scene |
string / trip-record |
可选业务标识,不需要选择预设场景 |
sessionId |
string / 自动生成 |
建议不传;自行传入时使用唯一的字母、数字、下划线或连字符组合,最长 96 字符,不能复用已有会话 |
outputDir |
string / 应用私有录音目录 |
建议不传。Android 视为根目录并追加 sessionId;iOS 绝对路径作为本会话目录,相对路径拼到私有录音目录下,必须是不存在或空的目录。不要复用其他会话或业务目录 |
segmentDurationMs |
number / 300000 |
每段时长,毫秒;填写 0 关闭自动分片,否则至少 1000,调试建议 10000 |
maxDurationMs |
number / 3600000 |
最大有效录音时长,毫秒;0 表示不限,否则至少 1000;暂停时间不计入 |
enableMetering |
boolean / true |
是否开启音量回调 |
notificationTitle |
string / 正在录音 |
Android 前台服务通知标题;iOS 忽略 |
notificationText |
string / 录音服务运行中,点击返回应用 |
Android 通知说明;iOS 忽略 |
onStateChange |
(RecorderStateEvent) => void |
状态与周期进度通知,同一 status 可能多次回调 |
onMetering |
(RecorderMeteringEvent) => void |
音量及录音时长通知 |
onSegmentReady |
(RecorderSegmentInfo) => void |
一段录音完成并落盘时触发 |
success、fail、complete |
回调,可选 | 分别对应开始成功、开始失败、本次开始操作结束;complete 不是整段录音结束 |
权限与操作结果
| 类型 | 字段 | 说明 |
|---|---|---|
RecorderOperationResult |
ok、platform、action、errCode、errMsg、note |
成功状态、平台、动作、错误码、错误内容及补充说明 |
RecorderPermissionResult |
上述字段 + granted、canAskAgain、permissions、deniedPermissions |
是否已授权、能否再次询问及权限列表。拒绝后可引导打开设置,实际是否弹窗由系统决定 |
RecorderFail |
errSubject、errCode、errMsg、platform、action、note |
失败详情,错误主题为 austin-recorder-x |
状态与事件
| 类型 | 字段 | 说明 |
|---|---|---|
RecorderStatus |
supported、platform |
当前运行环境与支持状态 |
status、sessionId、scene |
状态、会话 ID、业务标识 | |
durationMs、segmentCount、meterDb、note |
有效录音时长、已生成片段数、音量与说明 | |
RecorderStateEvent |
sessionId、scene、status、durationMs、segmentCount、reason、time |
状态变化;time 为毫秒时间戳 |
RecorderMeteringEvent |
sessionId、durationMs、db、peak、time |
音量与时间;数值用于音量反馈,不作为校准分贝仪读数 |
status 常见值:idle 待命、recording 录音中、paused 已暂停、stopped 已停止、error 异常、interrupted 上次会话意外结束。Android 创建期间还可能出现 starting。
文件与会话
| 类型 | 字段 | 说明 |
|---|---|---|
RecorderSegmentInfo |
sessionId、index、filePath |
会话 ID、片段序号、已完成片段的绝对路径 |
durationMs、sizeBytes、createdAt |
片段时长(毫秒)、大小(字节)、生成时间(毫秒时间戳) | |
RecorderSessionInfo |
sessionId、scene、status、platform |
会话身份、业务标识、状态、平台 |
outputDir、startedAt、endedAt |
输出目录、起止时间戳 | |
totalDurationMs、segmentCount |
有效录音时长与片段数 | |
mergedFilePath、mergedSizeBytes、mergeNote |
完整音频路径、字节数与合并说明;无可用结果时路径为空 |
多个片段停止后生成 merged.m4a;iOS 只有一个片段时直接返回该片段作为完整音频。不要把“收到停止状态”当作“合并已经完成”,应等待 stopRecorder.success,并检查路径与 mergeNote。合并失败时原始片段仍可取出处理。
会话索引与已完成片段会保存到本机,重开 App 后统一通过 getRecorderHistorySync() 查询:
import { getRecorderHistorySync } from '@/uni_modules/austin-recorder-x'
const history = getRecorderHistorySync()
console.log('全部会话', history['sessions'])
console.log('全部已完成片段', history['segments'])
快照内两组数组的字段分别对应上表的 RecorderSessionInfo 和 RecorderSegmentInfo;用 sessionId 关联会话和片段。附带演示页已处理列表显示与筛选,可直接复制。iOS 的 Vapor / 普通 uni-app 页面使用这个接口,避免部分基座直接返回自定义对象数组时丢失字段。
上次仍在录音或暂停的会话会标记为 interrupted;可用片段可以试听或交给业务处理,不会自动续录。强制结束时正在写入的尾段可能损坏,不能保证恢复:Android 会将识别出的无效尾段保留为 .incomplete,iOS 保留未完成文件但不将其列为有效片段。
自动分片使用停止当前录制、开始下一段的方式,切换有短暂间隙,不适合要求采样连续、无缝录音的场景。卸载 App 或清除应用数据会删除私有音频与索引;重要记录应由业务上传或导出。
常见问题
导入了但 API 不可用?
确认模块目录完整、导入 ID 正确,并重新制作和选中包含本插件的自定义基座。不要只把 JS 页面同步到旧基座。
Android 提示 Please register permissions ... RECORD_AUDIO?
这表示当前安装的基座未声明麦克风权限。确认插件的 utssdk/app-android/AndroidManifest.xml 随插件一起导入,再制作、安装并选择最新自定义基座。手机设置里的“允许麦克风”只负责用户授权,不能补充安装包缺失的权限声明。若错误内容已经改变,请按新的 errMsg 排查。
iOS 点击“申请权限”或“开始录音”闪退?
查看崩溃日志:若出现 TCC 和 NSMicrophoneUsageDescription,说明当前安装包缺少麦克风用途说明。按第 2 步填写宿主 manifest.json,再按第 3 步重新制作、安装并选中新基座。录音插件会在两个入口检查该说明,缺失或为空时通过 fail / complete 返回 9101002,具体处理方法见 note;更新了页面但基座仍是旧版本时,检查不会自动生效。
录音停止了却没有完整音频?
先等待 stopRecorder.success,读取 mergeNote。过短录音、麦克风中断或合并失败可能无法得到完整文件;可以读取 getRecorderHistorySync() 的 segments,按 sessionId 检查已经落盘的片段。
如何测试后台?
按第 4 步在真机录制,锁屏期间跨过多个分片周期,回到应用后核对文件数量、实际时长并试听。Android 确认通知里的暂停、继续、停止生效;若厂商省电策略中断服务,在系统电池设置中允许该 App 后台运行。iOS 确认安装包包含 audio 后台模式,再检查锁屏和来电中断后的表现。模拟器用于调用和文件流程调试,后台表现以真机为准。
需要服务器、Key、推送证书吗?
录音、分片和合并都在本机执行,不需要服务器或 Key。上传、云端转写等能力由业务另行接入。
失败怎么定位?
打印 errCode、errMsg 与 note:9101002 权限未授予或 iOS 麦克风用途说明缺失;9101003 初始化失败;9101004 已有录音;9101005/9101006/9101007 当前状态不能暂停/继续/停止;9101008 原生运行环境不可用;9101009/9101010 文件创建或写入失败;9101011 删除失败;9101001/9101012 平台或操作不支持。
版本
1.1.0:新增 Android 前台录音服务、通知控制、录音期间唤醒锁;新增 iOS 原生分片计时和音频中断处理;支持历史索引持久化、统一历史快照查询、异常结束后的片段恢复,以及跨页面录音。
1.0.0:独立插件 ID austin-recorder-x,提供 uni-app x 的 Vapor / VDOM 演示及普通 uni-app Vue3 演示,保留分片录音、暂停继续、合并与会话管理 API。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 642
赞赏 4
下载 12694408
赞赏 1956
赞赏
京公网安备:11010802035340号