必须用 uni.getRecorderManager 配合 touchstart/touchend/touchcancel 三事件严格对齐控制录音,防误触、防状态丢失、防 iOS 播放失败,并手动定时控时长、优化音频参数。

直接用 uni.startRecord 实现不了微信式的按住说话——它已废弃,且不支持手势耦合控制;必须用 uni.getRecorderManager 手动接管录音生命周期,并与 touchstart/touchend/touchcancel 事件严格对齐。
为什么 touchstart + touchend 绑定会失效
真机上松手瞬间常收不到 touchend:手指滑出按钮区域、弹窗遮挡、微信基础库拦截滚动容器内的事件,都会导致它丢失。更危险的是 touchcancel——切后台、收键盘、弹系统提示时触发,但多数人根本没监听它,结果录音进程卡在后台,recorder.stop() 永远不执行。
- 必须三事件全监听:
touchstart启动录音,touchend和touchcancel都调recorder.stop() - 加一个 100ms 延迟校验:
touchstart后立即setTimeout(() => { if (isPressed) start() }, 100),避免误触启动 - 在
touchmove中判断位移是否超出按钮范围,超了就提前stop()
recorder.start() 报 “fail recorder is running” 怎么办
这是状态没保护住的典型表现。iOS 尤其敏感:recorder.start() 调用前若上一次录音还没真正结束(比如 onStop 还没触发),就会报这个错。
- 定义
isRecording布尔变量,只在recorder.start()**调用成功后**设为true,别在onStart里设——它不一定触发 -
recorder.onStop和recorder.onError回调里都必须重置isRecording = false - 每次
start()前先判断:if (isRecording) return - 别复用同一个
recorder实例做多次录音——虽然可以,但状态容易串,建议每次新建或显式stop()后再start()
iOS 微信里录音文件播不了的根源
拿到的 tempFilePath 是 file:// 或 wxfile:// 协议路径,iOS 微信 WebView 禁止直接加载本地文件,uni.createInnerAudioContext().src 赋值后调 play() 会静默失败,控制台也不报错。
- 必须上传到服务端,拿到 HTTP 地址后再播放:
uni.uploadFile({ url: 'https://your-api.com/upload', filePath: tempFilePath, ... }) - 别尝试用
uni.getFileSystemManager().readFile读取 PCM 数据——iOS 权限拒绝,且读出来也没法直接喂给InnerAudioContext - H5 环境完全不支持
tempFilePath,连上传都不行,得走 WebRTC +MediaRecorder另起一套 - Android 和小程序真机多数 OK,但也要检查文件大小,避免用户录了 3 分钟才发现超限
如何控时长又不让 Android 机型失效
recorder.start({ duration: 60000 }) 的 duration 是软限制,部分 Android 厂商(如华为 EMUI)根本不认,录音能跑过 60 秒。
- 自己起定时器:
this.timer = setTimeout(() => recorder.stop(), 60000) -
recorder.onStop回调里立刻clearTimeout(this.timer) - 采样率设
16000、声道数1,体积减半,语音识别够用 - 格式优先选
mp3,比默认wav小得多;encodeBitRate控在96000~128000之间,再低会影响识别准确率
最易被忽略的点是:手势事件和录音状态的“时间对齐”。按下去那一刻就要完成权限检查、recorder 初始化、防抖计时、UI 变色;松手那一帧就要确保 stop 被执行、临时路径拿到、上传开始、UI 复位。中间任何一环延迟或丢失,用户感知就是“点了没反应”或“松手还在录”。



















