根本原因是iOS系统静音开关强制静音播放,而非录制失败;需在App.vue的onLaunch中用uni.setInnerAudioOption({obeyMuteSwitch:false})全局配置,并确保播放由用户手势触发、路径经encodeURI编码、资源格式兼容。

uni-app 小程序端音频录制在特定系统(尤其是 iOS)下没有声音,根本原因不是“录不到”,而是uni.createInnerAudioContext()默认遵循系统静音开关,且录制与播放是两套逻辑——你听到的“没声音”,其实是播放环节被静音了,不是录制失败。
为什么 iOS 真机上录音后播放无声?
iOS 设备侧边静音键开启时,createInnerAudioContext() 创建的播放实例默认会静音(obeyMuteSwitch 为 true),即使录音文件已成功生成并赋值给 src,播放时也完全无声。这不是 bug,是苹果强制的媒体策略。
- Android 和模拟器不走这套静音逻辑,所以本地测试一切正常
- 微信小程序 iOS 客户端、支付宝小程序 iOS 环境均继承该行为
-
onError回调通常不触发,因为播放动作本身没报错,只是被系统静音
必须用 uni.setInnerAudioOption() 全局配置
不能只在页面里对单个 innerAudioContext 实例设 obeyMuteSwitch = false——iOS 下这个实例级设置无效。必须在应用启动时全局声明:
// App.vue
export default {
onLaunch: function() {
// #ifdef MP-WEIXIN || MP-ALIPAY
uni.setInnerAudioOption({
obeyMuteSwitch: false
});
// #endif
}
}
- 必须放在
onLaunch中,且仅限小程序平台(#ifdef MP-WEIXIN等条件编译) - 不能写在页面
onLoad或组件mounted里,否则 iOS 不生效 - 该 API 是一次性设置,后续创建的所有
innerAudioContext实例都会继承此配置
录音 + 播放链路中容易漏掉的关键点
即使 obeyMuteSwitch 解决了,仍可能无声,常见断点在资源加载和触发时机:
-
src地址含中文或空格?必须用encodeURI()处理路径部分,例如:innerAudioContext.src = 'https://domain.com/' + encodeURI('录音_20260618.mp3'); - MP3 文件后缀不能是
.mp4或.wav(iOS 对.wav支持差,.mp4音频容器需确认编码为 AAC) - 播放必须由用户手势触发:不能在
uni.startRecord()回调里直接play(),要等用户点击“播放”按钮后再调用 - 检查
onCanPlay而非onPlay判断是否真正可播,避免因解码未就绪导致静默
真机调试时最常忽略的细节
很多开发者卡在“明明配置了,还是没声”,其实问题出在设备状态和调试方式:
- iPad 同样受静音键影响,但静音指示图标不明显,需手动检查侧边开关
- 微信 iOS 客户端内调试,要关掉“调试基础库”开关再试——某些旧版基础库会忽略
setInnerAudioOption - 首次播放前,务必确保用户已完成至少一次触摸交互(哪怕只是点空白处),否则 iOS Webview 会拦截自动播放
- 不要依赖
autoplay: true,它在 iOS 小程序里基本无效,且可能干扰播放状态机
真正的难点不在代码行数,而在于 iOS 静音策略、小程序容器限制、Webview 播放权限三者叠加后的不可见约束——你得同时满足系统层、框架层、运行时层三个条件,缺一不可。


















