iOS真机录音无法播放的主因是系统硬性限制:必须用AAC-LC或标准MP3编码,路径须经saveFile持久化,播放需用户手势触发,且服务器响应须带正确Content-Type(audio/mp4或audio/mpeg),否则静音无报错。

uni-app录音后iOS真机无法播放的常见原因
不是代码写错了,而是iOS系统对音频文件的编码、路径、触发时机有硬性要求。真机上静音、无声音、报错10003(格式错误)基本都指向这几个点。
- iOS只认AAC-LC或标准MP3(MPEG-1 Layer III),用Audacity导出时选“MP3 (LAME)”并勾选“Strictly adhere to MPEG-1”
- 录音文件必须存到
uni.getFileSystemManager().saveFile()返回的本地路径,不能直接用tempFilePath——后者在iOS后台会被回收 - 播放必须由用户点击触发,
play()不能放在onLoad里自动调,否则iOS直接静音 - 服务器返回的录音文件需带
Content-Type: audio/mp4(AAC)或audio/mpeg(MP3),否则iOS拒绝解码
uni.createInnerAudioContext在iOS上播放录音文件的正确写法
关键不是“能不能播”,而是“怎么播才不被iOS拦截”。重点在路径处理和生命周期绑定。
- 录音成功后,立刻用
uni.getFileSystemManager().saveFile()把tempFilePath持久化,拿到savedFilePath -
src必须设为savedFilePath,不能是tempFilePath或网络URL(除非HTTPS+正确MIME) - 播放前加
audioContext.autoplay = false,并在按钮@click里调play(),避免自动播放策略拦截 - 监听
onError,打印err.errCode:10003=格式/编码问题,10002=路径不可读,10001=系统级失败
示例:
const audioContext = uni.createInnerAudioContext();
audioContext.src = savedFilePath; // 一定是saveFile后的路径
audioContext.onError((err) => {
console.log('播放失败', err.errCode, err.errMsg);
});
// 在用户点击事件中调用
playRecord() {
audioContext.play();
}
微信小程序录音+播放必须用BackgroundAudioManager吗?
不用。BackgroundAudioManager只用于后台持续播放音乐类场景,普通录音回放用uni.createInnerAudioContext()完全够用——但仅限微信平台。支付宝、字节等不支持录音文件后台播放,切后台即停,且无法绕过。
- 微信小程序:录音文件可正常播放,只要路径和编码合规
- 支付宝小程序:
uni.getRecorderManager()录完后,uni.createInnerAudioContext()能播,但切后台立刻中断,无任何配置可修复 - H5端:依赖浏览器策略,必须用户手势触发
play(),且部分iOS Safari对blob:URL支持极差,建议转base64或存CDN
为什么安卓能播、iOS播不了,但控制台没报错?
这是iOS最坑的一点:静音失败不抛异常,onPlay也不触发,onError更不会进——它就默默卡住。真正能暴露问题的是onCanplay和duration。
- 加监听
audioContext.onCanplay(() => { console.log('canplay', audioContext.duration); }),如果duration一直是NaN或0,说明文件没加载成功或解码失败 - 用
ffprobe -v quiet -show_entries format=duration -of default=nw yourfile.mp3检查录音文件时长是否有效 - 真机调试必须开“微信开发者工具→调试器→Console”,模拟器100%不准
- 别信“已授权麦克风”,iOS录音权限和播放权限是两套机制,播放不需要额外权限
复杂点在于,同一份录音文件,在iOS模拟器里能播,真机上不能播——这几乎可以断定是编码或路径问题,而不是逻辑缺陷。


















