不能只用cameraContext.takePhoto()录像,因其仅生成单帧图片;真正录像必须用uni.startRecord()和uni.stopRecord()全局API,混用会导致H5白屏、App无声、小程序报错。

uni.startRecord() 是最直接、跨端兼容性最好的方案,但必须配合 maxDuration 参数和权限预检,否则在小程序或 App 端会静音、中断或根本无响应。
为什么不能只用 cameraContext.takePhoto() 录像
这是最常见的误用:把拍照 API 当录像用。实际上 cameraContext.takePhoto() 只生成单帧图片;真正录像必须用全局 API uni.startRecord() 和 uni.stopRecord()。混用会导致 H5 页面白屏、App 端无声、小程序报错 undefined is not an object (evaluating 'e.startRecord')。
关键区别在于:cameraContext 是组件级上下文,只管预览与拍照;而录像能力由 uni-app 运行时统一管理,不依赖 <camera> 组件是否存在。
maxDuration 参数必须显式传,且单位是秒
小程序平台(微信/支付宝)默认限制 60 秒,但 Android/iOS App 不设限 —— 意味着你不传 maxDuration,用户可能录到几分钟才停,甚至因内存溢出崩溃。
- 设为
60表示最长 1 分钟,超时自动触发stopRecord回调 - 设为
10可用于短视频场景(如朋友圈“10秒快拍”) - 不能传字符串(如
"60"),否则 iOS 会静默失败,Android 报java.lang.NumberFormatException - H5 端不支持该参数,调用
uni.startRecord()会直接 fail,需提前if (uni.getSystemInfoSync().platform !== 'h5')判断
权限必须同时申请 scope.camera 和 scope.record
相机和录音是两个独立权限。只申请了 scope.camera,uni.startRecord() 在小程序里会静音或返回空路径;只申请 scope.record,<camera> 根本打不开。
更麻烦的是:用户点一次“拒绝”,uni.authorize() 后续调用不会再弹窗。所以必须:
- 进入页面前,先
uni.getSetting()检查两者状态 - 任一未授权,优先调
uni.authorize({scope: 'scope.camera'}),成功后再检查scope.record - 若任一失败,立刻
uni.openSetting()跳转设置页 —— 尤其小程序,不跳就卡死 - App 端虽默认允许录音,但 manifest.json 仍需声明
<uses-permission android:name="android.permission.RECORD_AUDIO"/>,否则 Android 12+ 会静音
停止录制后拿到的路径要立刻处理
uni.stopRecord() 成功回调里的 tempVideoPath 是临时文件,iOS 7 天后自动清理,Android 部分机型重启即删。不能存着等上传,必须马上读取或转存。
常见错误操作:
- 直接把
tempVideoPath传给uni.uploadFile()—— H5 不支持 file:// 协议,App 端部分 Android 机型也会 404 - 用
uni.saveVideoToPhotosAlbum()后再上传 —— 用户可能拒绝对相册写入,导致流程中断
推荐做法:用 uni.getFileSystemManager().readFile() 读成 ArrayBuffer,再转 base64 或 Blob 上传;或调 uni.saveFile() 存到本地持久路径(如 uni.env.USER_DATA_PATH)后再处理。
真正容易被忽略的是:iOS 录制视频默认带音频轨,但如果你在 startRecord 里传了 muted: true,某些旧版 iOS 会录出无声视频且不报错 —— 测试时务必真机验音。


















